Compare commits

...

154 Commits

Author SHA1 Message Date
Daniel Stenberg
4d2cb8b32a 7.9 commit 2001-09-25 06:39:18 +00:00
Daniel Stenberg
d5001a3f0b Added httpput.c 2001-09-25 05:55:56 +00:00
Daniel Stenberg
91f5ac4d5c two ipv6 fixes 2001-09-24 07:48:31 +00:00
Daniel Stenberg
f9977df50d moved to parent directory 2001-09-24 07:48:00 +00:00
Daniel Stenberg
711650b178 test 119 proved a memory leak in the FTP parts when IPv6 is enabled and the
RETR fails, this corrects it.
2001-09-23 12:47:07 +00:00
Daniel Stenberg
c9adbc9f1c Adjusted to run on ipv6-enabled hosts 2001-09-23 12:46:04 +00:00
Cris Bailiff
611fbfa917 Commit Curl_easy v1.1.8 - constants updated for libcurl 7.9 - tests modularised 2001-09-20 09:48:52 +00:00
Daniel Stenberg
ecfacfb334 redirect and ssl connect fixes 2001-09-19 21:57:26 +00:00
Daniel Stenberg
645413f5ef Lots of praise and glory to Vojtech Minarik for setting up a test server
and providing me with test-certificates that helped me nail the problem with
curl not discovering with a bad certificate was used.
2001-09-19 21:49:11 +00:00
Daniel Stenberg
5becdc38b3 http put with --crlf requires chunked content encoding 2001-09-19 14:49:23 +00:00
Daniel Stenberg
f36cea67fe This verifies that bug report #462600 is fixed, a Location: following when
the given URL has no protocol:// part and the Location: redirect contains a
:// section
2001-09-18 18:41:46 +00:00
Daniel Stenberg
b556d6caee fixed bug report #462600, following a Location: when the initial URL didn't
have a protocol:// part did wrong
2001-09-18 18:33:25 +00:00
Daniel Stenberg
a17a78c477 removed Curl_http_close() 2001-09-18 15:30:59 +00:00
Daniel Stenberg
146413a53c the stuff formerly done in Curl_http_close is now done in Curl_close 2001-09-18 15:30:38 +00:00
Daniel Stenberg
437fd064c9 modified GetLine(), removed Curl_http_close() 2001-09-18 15:29:57 +00:00
Daniel Stenberg
28dd4e4f1f made it respond as a http proxy on CONNECT 2001-09-18 15:26:54 +00:00
Daniel Stenberg
f92dc70beb added two https test cases 2001-09-18 15:26:32 +00:00
Daniel Stenberg
6d8f1328bf HTTPS test case 2001-09-18 15:13:40 +00:00
Daniel Stenberg
8d1d93d56d Linus Nielsen Feltzing fixed telnet for win32. 2001-09-17 22:51:48 +00:00
Daniel Stenberg
f8e102c485 curl_easy_duphandle is new 2001-09-17 22:24:35 +00:00
Daniel Stenberg
d816fcc965 Linus Nielsen Feltzing changed winsock lib for linking 2001-09-17 14:38:41 +00:00
Daniel Stenberg
e30dcd0501 Linus Nielsen Feltzing's telnet-for-win32 fixes 2001-09-17 14:10:38 +00:00
Daniel Stenberg
24dc7cffbd libtool 1.4.2 generated 2001-09-17 14:08:47 +00:00
Daniel Stenberg
3bc83926ce just a simple example that seems to work! 2001-09-17 12:20:44 +00:00
Daniel Stenberg
c5cca4d059 fixed the stunnel PEM path 2001-09-17 08:55:32 +00:00
Daniel Stenberg
0db04c4f56 added stunnel PEM 2001-09-17 08:41:45 +00:00
Daniel Stenberg
5c566c9aa3 added the stunnel PEM file 2001-09-17 08:41:28 +00:00
Daniel Stenberg
822f02313d changed the PEM path 2001-09-17 08:41:01 +00:00
Daniel Stenberg
d934890c1e libtool 1.4.2 2001-09-17 06:12:53 +00:00
Daniel Stenberg
0e25cf41c4 modified error message when PWD fails 2001-09-14 12:18:46 +00:00
Daniel Stenberg
5214dbbd02 duphandle(), cipher list, *18* new ftp tests 2001-09-14 12:12:50 +00:00
Daniel Stenberg
0c716d51ad added README and FILEFORMAT to distrbution archive 2001-09-14 12:07:11 +00:00
Daniel Stenberg
86367d675a new FTP tests 2001-09-14 12:03:33 +00:00
Daniel Stenberg
bd8cef5a70 the strip stuff 2001-09-14 12:02:02 +00:00
Daniel Stenberg
708431e2ea fixed the REST again 2001-09-14 12:01:21 +00:00
Daniel Stenberg
db5c1c61e5 added curl_easy_duphandle 2001-09-13 14:50:04 +00:00
Daniel Stenberg
aa4ff6d8b9 Added curl_easy_duphandle 2001-09-13 14:49:35 +00:00
Daniel Stenberg
6d5b8b50e1 minor informatinal output changes 2001-09-13 12:52:58 +00:00
Daniel Stenberg
600d7b11e6 moved lots of the verbose stuff to do logmsg instead 2001-09-13 12:52:24 +00:00
Daniel Stenberg
afa7648be6 initial test suite file format description 2001-09-13 12:51:32 +00:00
Daniel Stenberg
5c344fc23a ftp tests added 2001-09-13 12:51:07 +00:00
Cris Bailiff
5a905e0bb8 Release 1.1.7 - documentation update with licence info only. 2001-09-13 11:27:59 +00:00
Cris Bailiff
c31216949d Update documentation to explicitly state Curl::easy licence is dual MIT/X - MPL. 2001-09-13 05:00:13 +00:00
Daniel Stenberg
2cb893575d moved a 100K buffer from the transfer loop to the urlstate struct, as it
seriously decreases the amount of used stack space
2001-09-12 12:02:12 +00:00
Daniel Stenberg
63f1f58077 removed perl and php makefiles 2001-09-12 11:31:58 +00:00
Daniel Stenberg
36e9507e29 reverted. twas no memory leak and the "fix" didn't even compile on windows... 2001-09-12 08:59:00 +00:00
Daniel Stenberg
1fde1431c9 narrowed some source lines to fit in 80 cols 2001-09-12 08:14:35 +00:00
Daniel Stenberg
bec97a0999 ConnectionKillOne() _can_ return -1 as an indication of error
This is T. Bharath's fix
2001-09-12 08:00:30 +00:00
Daniel Stenberg
07de3c9df0 T. Bharath's patch that sets up a few necessary buffers in the duphandle()
function
2001-09-12 07:57:33 +00:00
Daniel Stenberg
8950a2dfa1 *TERRIBLE* terrible memory leak occuring on all systems that have no
gethostbyname_r() function, most notably windows machines...
2001-09-12 07:19:11 +00:00
Daniel Stenberg
be47d83555 added CURLOPT_SSL_CIPHER_LIST 2001-09-11 22:36:43 +00:00
Daniel Stenberg
d5054ad52d --ciphers now sets CURLOPT_SSL_CIPHER_LIST 2001-09-11 22:36:03 +00:00
Daniel Stenberg
051fad8d88 now can set list of ciphers 2001-09-11 22:35:23 +00:00
Daniel Stenberg
c4532b9a07 added --ciphers 2001-09-11 22:34:54 +00:00
Daniel Stenberg
0e7824d1a9 documented CURLOPT_SSL_CIPHER_LIST 2001-09-11 22:29:30 +00:00
Daniel Stenberg
a2c78607a6 CURLOPT_SSL_CIPHER_LIST support 2001-09-11 22:23:16 +00:00
Daniel Stenberg
cc1a4edf3d added cipher_list 2001-09-11 22:21:26 +00:00
Daniel Stenberg
db7bde1d7a added ability to set prefered list of ciphers 2001-09-11 22:21:02 +00:00
Daniel Stenberg
719008596a changes since pre3 2001-09-11 12:00:36 +00:00
Daniel Stenberg
377e78d917 removed the 'perl' and 'php' dirs from the release archive 2001-09-11 10:15:40 +00:00
Daniel Stenberg
894b47da9b ouputs the start and expire dates of the server certificate on verbose
output
2001-09-11 10:00:49 +00:00
Daniel Stenberg
54e7246342 cleaned up, now closes the listener port in PASV and it doesn't re-use the
same passive port number
2001-09-11 07:45:12 +00:00
Daniel Stenberg
9b3b050640 some unixes have the netrc description in the ftp(1) man page 2001-09-11 06:39:54 +00:00
Daniel Stenberg
a0e389caa2 generated .h file cut off 2001-09-10 12:17:23 +00:00
Daniel Stenberg
b747408f9e updated to allow separate packaging 2001-09-10 12:15:17 +00:00
Daniel Stenberg
d3e55d8155 Added project curl source header 2001-09-10 12:14:40 +00:00
Cris Bailiff
96c7253cea Fix perl segfault due to changes in header callback behaviour since curl-7.8.1-pre3 2001-09-10 09:17:02 +00:00
Daniel Stenberg
3f5227dfc7 Curl_cookie_output() must check that there's a cookie struct present before
trying to address it!
2001-09-10 07:43:08 +00:00
Daniel Stenberg
b91103099a updated tool versions 2001-09-10 06:05:38 +00:00
Daniel Stenberg
82d3ded922 checks for sys/utime.h 2001-09-07 09:53:40 +00:00
Daniel Stenberg
5a8d1c4cd1 HAVE_SYS_UTIME_H adjustments 2001-09-07 09:53:21 +00:00
Daniel Stenberg
46372c04ee made it compile properly when not building with SSL support 2001-09-07 09:40:46 +00:00
Sterling Hughes
6147879837 Added formatting sections for emacs and vim 2001-09-07 04:01:32 +00:00
Sterling Hughes
e2e3c95d3b fix for emacs 2001-09-07 03:30:30 +00:00
Daniel Stenberg
c3b448dcea moved the session ID cache state variables into the UrlState struct within
the SessionHandle. It was previously wrongly put in UserDefined
2001-09-06 08:32:01 +00:00
Daniel Stenberg
86da31e031 Curl_SSL_Close_All() now checks that we have a session cache before we run
around killing entries in it!
2001-09-06 06:26:24 +00:00
Daniel Stenberg
1d7075e339 added -R description 2001-09-05 13:26:54 +00:00
Daniel Stenberg
610ec27d93 first shaky and stumbling attempts at a *_duphandle() function 2001-09-05 07:24:01 +00:00
Daniel Stenberg
70f2717c11 added curl-mode.el 2001-09-05 06:56:24 +00:00
Daniel Stenberg
b31a54c46a emacs lisp setup for hacking curl code 2001-09-05 06:55:08 +00:00
Sterling Hughes
08238f4320 Fix formatting when tabs and spaces got mixed up (if tabstop was not set to
8 this looked quite funny :)

Added a small formatting section for vim at the bottom, it also contains an
emacs portion (copied it from another project I'm working on), I don't know
if this is correct, but its a step (the vim part is correct :)
2001-09-05 02:49:04 +00:00
Daniel Stenberg
06993556f3 defined HAVE_UTIME and HAVE_UTIME_H 2001-09-03 14:31:48 +00:00
Daniel Stenberg
144459d364 corrected the comment to be valid chunk format 2001-09-03 12:51:23 +00:00
Daniel Stenberg
0fa61eff77 -R removes a TODO 2001-09-03 12:32:44 +00:00
Daniel Stenberg
a0be515d2d -R added 2001-09-03 12:10:48 +00:00
Daniel Stenberg
5900c0f767 utime() and utime.h adjustments for curl -R 2001-09-03 12:00:38 +00:00
Daniel Stenberg
d10cf2ba94 introducing -R/--remote-time which uses the remote file's time to set the
local file's time
2001-09-03 12:00:08 +00:00
Daniel Stenberg
bae1a75731 use the LIBCURL_NAME instead of the "hardcoded" string 2001-09-03 07:01:49 +00:00
Daniel Stenberg
f5adc8e53f libtool 1.4.1 2001-09-03 07:00:59 +00:00
Daniel Stenberg
67df4c9e6c removed unused #defines 2001-09-01 10:20:12 +00:00
Daniel Stenberg
50adfe3be9 Heikki Korpela noticed openbsd problems and libtool 2001-09-01 09:43:52 +00:00
Daniel Stenberg
71794da389 as generated with libtool 1.4.0a 2001-09-01 09:42:22 +00:00
Daniel Stenberg
6ef11f0b13 Heikki Korpela fixed the 'make -C' invokes. make -C is banned. 2001-09-01 09:39:40 +00:00
Daniel Stenberg
a5705acc9c the big struct rename of the year 2001-08-30 23:03:22 +00:00
Daniel Stenberg
47e7a3e678 a few more struct fixes 2001-08-30 22:59:58 +00:00
Daniel Stenberg
0ece1b5c34 Major rename and redesign of the internal "backbone" structs. Details will
be posted in a minute to the libcurl list.
2001-08-30 22:48:34 +00:00
Daniel Stenberg
315954c175 updated a bit 2001-08-29 15:02:46 +00:00
Daniel Stenberg
27ce46a85d removed cookies and SSL sessions 2001-08-29 12:14:18 +00:00
Daniel Stenberg
ea3cc81487 new ftp upload example, brand new cookie functionality and more 2001-08-29 09:51:44 +00:00
Daniel Stenberg
a9b139b25c added CURLOPT_COOKIEJAR details 2001-08-29 09:47:33 +00:00
Daniel Stenberg
bbdd5adf6e '-c -' 2001-08-29 09:45:44 +00:00
Daniel Stenberg
d425f5389d -c/--cookie-jar documented 2001-08-29 09:44:35 +00:00
Daniel Stenberg
26983053c4 take port numbers into account when finding a previous session from the
cache
2001-08-29 09:36:41 +00:00
Daniel Stenberg
8e0043165a added COOKIEJAR 2001-08-29 09:32:50 +00:00
Daniel Stenberg
c13dbf7bae uses the new cookie jar feature 2001-08-29 09:32:35 +00:00
Daniel Stenberg
a2b6ef3478 cookie jar adjustments 2001-08-29 09:32:18 +00:00
Daniel Stenberg
b6526af442 added ftpupload.c 2001-08-29 07:12:04 +00:00
Daniel Stenberg
4edba42c7c lots of crap 2001-08-28 09:02:33 +00:00
Daniel Stenberg
1180ef4b31 added the most recent one from automake 1.5, it complained on the former
one being "too old"
2001-08-28 09:01:50 +00:00
Daniel Stenberg
94bf462473 up'ed the version-info 2001-08-28 08:58:27 +00:00
Daniel Stenberg
233b3f718f curl_formadd() adjustments by Georg Huettenegger 2001-08-28 08:55:59 +00:00
Daniel Stenberg
0452fd8657 Georg Huettenegger's updates 2001-08-28 08:55:26 +00:00
Daniel Stenberg
613eafaf02 automake 1.5 complained on my SUFFIXES line! 2001-08-28 08:55:12 +00:00
Daniel Stenberg
725bd1dddf Georg Huettenegger's fixes and improvements to curl_formadd() 2001-08-28 08:54:33 +00:00
Daniel Stenberg
9835629801 Georg Huettenegger added code to deal with error 417 when doing form posts.
NOTE: we might do this for *ALL* errors when doing form posts.
2001-08-28 08:54:09 +00:00
Daniel Stenberg
3c52c53ddd Added SSL session ID caching, moved some SSL code from url.c to ssluse.c 2001-08-28 08:37:54 +00:00
Sterling Hughes
321ba15a82 we should be using start here. 2001-08-26 20:51:16 +00:00
Daniel Stenberg
9e5dfc15ac improved the test 2001-08-26 14:28:05 +00:00
Daniel Stenberg
8d52681e1d Added #include <string.h> and removed a silly mistakenly added , 2001-08-26 14:27:07 +00:00
Daniel Stenberg
56f6815d3d rewrite to work around BSD announcement license issues, this is also
somewhat easier to understand if I may say so. It is slightly slower.
2001-08-24 10:25:02 +00:00
Daniel Stenberg
ce07e79f3c cookies are stored in the reversed order now (which in turn means that
the order is _not_ actually reversed like it used to be)
2001-08-24 10:18:14 +00:00
Daniel Stenberg
723ced9336 T. Bharath's patch => linking with multithreaded versions of the c runtime
library for use in multithreaded apps
2001-08-24 07:45:16 +00:00
Daniel Stenberg
73417b59c7 T. Bharath's patch. It is kind of dirty, as it #pragma aways a whole bunch
of compiler warnings, but I guess they make the life somewhat easier to live
for a ms dude compiling this. For a rainy day: remove the pragmas and correct
the source code that cause the warnings!
2001-08-24 07:43:24 +00:00
Daniel Stenberg
f4e2774ab8 newly re-generated from the modified getdate.y 2001-08-24 07:41:51 +00:00
Daniel Stenberg
d5112c0dec include setup.h properly, not config.h 2001-08-24 07:39:50 +00:00
Daniel Stenberg
aace68c91b extern declarations no longer done on windows (T. Bharath's patch) 2001-08-24 07:39:15 +00:00
Daniel Stenberg
4034f31823 cleanups 2001-08-24 07:24:34 +00:00
Daniel Stenberg
5323340cae Kevin Roth's comments about -G have been addressed:
o -G -I works on the same command line and makes HEAD instead of GET
o -G with an already present question mark in the URL makes an ampersand get
  added as a separator instead
2001-08-24 07:01:09 +00:00
Daniel Stenberg
3aae2ec511 Tim Costello's bug report #454856 2001-08-24 06:31:34 +00:00
Daniel Stenberg
df09214c62 strcasecmp() is banned from our code, should be strequal() everywhere!
Tim Costello reported bug report #454858.
2001-08-24 06:20:47 +00:00
Daniel Stenberg
12acab9b86 When setting *_URL or *_PROXY in *_setopt(), it is important that we check
and possibly free the existing pointer first, and then clear the "allocated"
bit. We previously mistakenly could free the new pointer passed to us by
the friendly user...!
2001-08-23 14:06:38 +00:00
Daniel Stenberg
c9c2115088 started working on a function for writing (all) cookies, made it possible
to read multiple cookie files, no longer writes to the URL string passed
to the _add() function. The new stuff is now conditionally compiled on the
COOKIE define. Changed the _init() proto.
2001-08-23 14:05:25 +00:00
Daniel Stenberg
d73d28a75b added FTPS to the list of supported protocols 2001-08-23 11:12:07 +00:00
Daniel Stenberg
13bf964b78 item 4.6 is now an indication of a crash, not a timeout 2001-08-23 11:11:13 +00:00
Daniel Stenberg
3fb9c5727c As Steve Lhomme pointed out, this generates 'libcurl.dll' now instead of
the previous 'curl.dll'
2001-08-23 11:06:10 +00:00
Daniel Stenberg
b69f33ed44 Nico's update: "modified the build procedure to restore to the right current
directory where the build was started and it will autosense where is was run
from and set up the correct default directory at start of the script."
2001-08-23 10:56:48 +00:00
Daniel Stenberg
56e8d073bf curl_formadd() using example, the 7.9 style of building rfc1867 form posts 2001-08-23 08:45:20 +00:00
Daniel Stenberg
83a8786fe1 I want Sterling to be my friend, so I wasted some time on splitting up the
huge monster function _ftp() into more little functions. There are still
more that can be done, but this is at least improving readability and
maintainability... :-)
2001-08-23 06:10:01 +00:00
Daniel Stenberg
e3d7cc895b Georg Huettenegger's fixes, man pages converted to HTML pages and included
in release archive
2001-08-22 11:25:39 +00:00
Daniel Stenberg
0f425b01aa CURLOPT_FTPASCII is the old name, CURLOPT_TRANSFERTEXT is the new 2001-08-22 11:24:57 +00:00
Daniel Stenberg
c5a4b52d83 libcurl.3 has the info now 2001-08-22 11:23:53 +00:00
Daniel Stenberg
fc2d24105c CURLOPT_POST isn't needed these days 2001-08-22 11:23:07 +00:00
Daniel Stenberg
6704d44dd4 updated 2001-08-22 11:22:43 +00:00
Daniel Stenberg
3d9aeccc90 libcurl.3 is the man page 2001-08-22 11:22:28 +00:00
Daniel Stenberg
08655d8d5d Georg Huettenegger's patch curl-7.8.1-pre5-patch-20010819 2001-08-21 13:18:07 +00:00
Daniel Stenberg
3e5dbac7a2 added test44 formpost without Expect:, modified test9 2001-08-21 12:46:23 +00:00
Daniel Stenberg
05d9c9b849 run 'make clean' before 'make dist' to make sure the HTML files are up-to-date 2001-08-21 09:16:43 +00:00
Daniel Stenberg
4c2fb64e21 added a 'html' target that builds HTML versions from the man page sources.
It requires 'gnroff' and 'man2html' for now. 'make html' will be invoked by
the 'maketgz' script and the HTML files are included in release archives.
2001-08-21 09:16:09 +00:00
Daniel Stenberg
46a897f604 make html runs make html in the docs dir 2001-08-21 09:14:31 +00:00
Daniel Stenberg
d4b23198fa this is replaced with libcurl.3 2001-08-21 06:56:13 +00:00
Daniel Stenberg
6581663687 fflush the progress output, fixed configure.in for SSL without --with-ssl 2001-08-21 06:50:45 +00:00
Daniel Stenberg
4398151fd5 Troy Engel's fix for running configure without --with-ssl 2001-08-21 06:36:30 +00:00
Daniel Stenberg
d5fbfa3d0b As Andrs Garca reported we need to fflush() the data->err so that the
progress meter looks better on windows (and if the data->err is redirected
from stderr it also makes a point)
2001-08-21 06:29:56 +00:00
Daniel Stenberg
3a588fc9e7 added "4.5 FIGURE OUT WHAT A POST LOOKS LIKE"
added an online URL to this document
corrected a bad use of -t
2001-08-20 13:22:37 +00:00
148 changed files with 6459 additions and 2390 deletions

203
CHANGES
View File

@@ -6,6 +6,207 @@
History of Changes
Daniel (23 September 2001)
- Found and removed a 'socket leak' that would occur on IPv6 enabled hosts
when FTP RETR failed.
- Made the FTP upload tests run fine on machines with IPv6 enabled.
Version 7.9-pre8
Daniel (19 September 2001)
- Vojtech Minarik set up a special-purpose test server and provided me with
test certificates in order for me to repeat the bug reports #440068 and
#440373. It turned out we didn't check all the error codes properly. We do
now, and connecting with a unacceptable certificate will make libcurl fail
to connect with an error code returned.
- Ramana Mokkapati found a case when the Location: following code did wrong.
I wrote a test case for this (45).
Version 7.9-pre7
Daniel (17 September 2001)
- Linus Nielsen Feltzing fixed telnet for win32. It makes libcurl require
winsock 2.0.
Version 7.9-pre6
- libtool 1.4.2 is now in use!
Version 7.9-pre5
Daniel (14 September 2001)
- Added another 14 ftp tests.
Daniel (13 September 2001)
- Added curl_easy_duphandle() to the easy.h header file. It has now been
tested and proved to work in a real-world tests by T Bharath. We still need
to write up some docs for this function.
- Added four more ftp tests to the test suite.
Daniel (12 September 2001)
- CURLOPT_SSL_CIPHER_LIST was added, and the curl tool option is named
--ciphers. Use them to specify a list of ciphers to use in the SSL
connection.
- T. Bharath found a memory leak in libcurl's windows version. It turned out
to be the new duphandle() that didn't quite work yet.
Version 7.9-pre4
Daniel (11 September 2001)
- Added verbose output for SSL connections that output the server
certificate's start and expire dates. As suggested by Paul Harrington.
- Heikki Korpela found problems in the perl ftp server used for the test
suite, when he runs on on OpenBSD with perl 5.6. Some changes have been
made, but nothing really certain.
- T. Bharath has experienced problems with libcurl's stack usage on windows
and works on reducing it.
Daniel (10 September 2001)
- Cris Bailiff fixed the perl interface. It stopped working since the changed
behavior with WRITEHEADER and NULL pointers.
- The "output cookies" function could dump core if no cookies were enabled.
Daniel (7 September 2001)
- SM pointed out that the SSL code didn't compile any longer if SSL was
disabled... Also, we needed to correct the #include for the utime stuff on
windows.
Daniel (6 September 2001)
- T. Bharath pointed out a flaw in the SSL session cache code that made it
sometimes read from a NULL pointer.
Version 7.9-pre3
Daniel (3 September 2001)
- Added the -R/--remote-time option, that uses the remote file's datestamp to
set the local file's datestamp. Thus, when you get a remote file your local
file will get the same time and date. Note that this only works when you use
-o or -O.
- Installed libtool 1.4.1, libtoolized and everything.
Daniel (1 September 2001)
- Heikki Korpela pointed out that I did not ship the proper libtool stuff in
the pre-releases, even though that was my intention. libtoolize has now
been re-run.
- Heikki also patched away the bad use of 'make -C' in the test suite
makefile. make -C is not very portable and is now banned from here.
Version 7.9-pre2
Daniel (31 August 2001)
- I just made a huge internal struct rehaul, and all the big internally used
structs have been renamed, redesigned and stuff have been moved around a bit
to make the source easier to follow, more logically grouped and to hopefully
decrease future bugs. I also hope that this will make new functions to get
easier to add, and make it less likely that we have bugs left like the URL-
free bug from August 23.
Version 7.9-pre1
Daniel (29 August 2001)
- The new cookie code have enabled the brand new '-c/--cookie-jar' option. Use
that to specify the file name in which you want to have all cookies curl
knows of, dumped to. It'll be written using the netscape cookie format.
This is internally done with the new CURLOPT_COOKIEJAR option to libcurl,
which in turn dumps this information when curl_easy_cleanup() is invoked.
There might be reasons to re-consider my choice of putting it there. Perhaps
it is better placed to get done just before *_perform() is done. It is all
of course depending on how you guys want to use this feature...
- Added ftpupload.c in the source examples section, based on source code posted
by Erick Nuwendam.
Daniel (28 August 2001)
- Now running libtool CVS branch-1-4 to generate stuff. Should fix problems
on OpenBSD and hopefully on FreeBSD as well!
- Georg Huettenegger modified the curl_formadd() functionality slightly, and
added support for error code 417 when doing form post and using the Expect:
header. Great work!
- Made some tests with cached SSL session IDs, and they seem to work. There
should be a significant speed improvement in the SSL connection phase, but
in my tiny tests it just isn't possible to notice any difference. Like other
caching in libcurl, you must reuse the same handle for the caching to take
effect. SSL session ID caching is done on a per host-name and destination
port number basis.
Set verbose, and you'll get informational tests when libcurl detects and
uses a previous SSL session ID.
- Upgraded to automake 1.5 on my development/release machine.
Daniel (27 August 2001)
- Slowly started writing SSL session ID caching code
Daniel (24 August 2001)
- T. Bharath removed compiler warnings on windows and updated the MS project
files.
- Kevin Roth reported two kinds of command line constructs with the new -G that
curl didn't really deal with the way one would like.
- Tim Costello patched away a use of strcasecmp() in the SSL code. We have our
own portable version named strequal() that should be used!
- Tim also pointed out a problem in the lib/Makefile.vc6 file that made it mix
debug object modules causing confusions.
Daniel (23 August 2001)
- T. Bharath accurately found a libcurl bug that would happen when doing a
second invoke of curl_easy_perform() with a new URL when the previous invoke
followed a Location: header.
- Started the improvement work on the cookie engine:
- Now keeps cookies in the same order as the cookie file
- A write to the possibly static string was removed
- Added a function that can output all cookies
- Now supports reading multiple cookie files
- Steve Lhomme corrected a DLL naming issue in the MSVC++ project file.
- Split up the monster function in lib/ftp.c to use more smallish functions to
increase readability and maintainability.
Daniel (21 August 2001)
- Georg Huettenegger's big patch was applied. Now we have:
o "Expect: 100-continue" support. We will from now on send that header in
all rfc1867-posts, as that makes us abort much faster when the server
rejects our POST. Posting without the Expect: header is still possible in
the standard replace-internal-header style.
o curl_formadd() is a new formpost building function that is introduced to
replace the now deprecated curl_formparse() function. The latter function
will still hang around for a while, but the curl_formadd() is the new way
and correct way to build form posts.
o Documentation has been updated to reflect these changes
These changes are reason enough to name the next curl release 7.9...
- We now convert man pages to HTML pages and include them in the release
archive. For the pleasure of everyone without nroff within reach.
- Andr<64>s Garc<72>a's suggested flushing of the progress meter output stream was
added. It should make the progress meter look better on Windows.
- Troy Engel pointed out a mistake in the configure script that made it fail
on many Red Hat boxes!
Daniel (20 August 2001)
- We need an updated libtool to make a better build environment for OpenBSD
as well as FreeBSD
Version 7.8.1
Daniel (20 August 2001)
- Brad pointed out that we ship two extra libtool files in the tarballs that
we really don't need to! Removing them makes the gz-archive about 60K
@@ -993,7 +1194,7 @@ Version 7.6.1-pre2
Daniel (31 January 2001)
- Curl_read() and curl_read() now return a ssize_t for the size, as it had to
be able to return -1. The telnet support crashed due to this and there was a
possibility to weird behaviour all over. Linus Nielsen Feltzing helped me
possibility to weird behavior all over. Linus Nielsen Feltzing helped me
find this.
- Added a configure.in check for a working getaddrinfo() if IPv6 is requested.

View File

@@ -10,8 +10,8 @@ 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.
Use autoconf 2.50 and no earlier. Also, try having automake 1.4 and libtool
1.4 at least.
Use autoconf 2.50 and no earlier. Also, try having automake 1.5 and libtool
1.4.1 at least.
You will need perl to generate the src/hugehelp.c file. The file
src/hugehelp.c.cvs is a one-shot file that you can rename to src/hugehelp.c if

View File

@@ -8,16 +8,19 @@ EXTRA_DIST = \
CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt \
config-win32.h reconf Makefile.dist \
curl-config.in build_vms.com config-riscos.h \
config-vms.h
config-vms.h curl-mode.el
bin_SCRIPTS = curl-config
SUBDIRS = docs lib src include tests packages perl php
SUBDIRS = docs lib src include tests packages
# create a root makefile in the distribution:
dist-hook:
cp $(srcdir)/Makefile.dist $(distdir)/Makefile
html:
cd docs; make html
check: test
test:

2
README
View File

@@ -12,7 +12,7 @@ README
document.
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.5 man page to
available to be used by your software. Read the libcurl.3 man page to
find out how!
You find answers to the most frequent questions we get in the FAQ document.

Binary file not shown.

View File

@@ -101,6 +101,9 @@
/* Define if you have the <alloca.h> header file. */
/*#define HAVE_ALLOCA_H 1*/
/* Define if you have the malloc.h file. */
#define HAVE_MALLOC_H 1
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
@@ -185,3 +188,28 @@
#define HAVE_UNISTD_H 1
#endif
/**************************************************
*This is to eliminate the warnings when compiled *
* using MS VC++ compiler *
**************************************************/
#ifdef _MSC_VER
#pragma warning (disable: 4244) /* truncation from 'const int' to 'char' */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4706) /* assignment within conditional expression */
#pragma warning (disable: 4761) /* integral size mismatch in argument */
#pragma warning (disable: 4101) /* unreferenced local variable */
#pragma warning (disable: 4131) /* uses old-style declarator */
#pragma warning (disable: 4057) /* const char *' differs in indirection to
slightly different base types from
'unsigned char [x] */
#pragma warning (disable: 4100) /* unreferenced formal parameter */
#pragma warning (disable: 4055) /* type cast' : from data pointer 'void *' to
function pointer
'void *(__cdecl *)(char *,int ) */
#pragma warning (disable: 4701) /* local variable may be used without having
been initialized */
#pragma warning (disable: 4715) /* ToHour' : not all control paths return a
value */
#endif

240
config.guess vendored
View File

@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
timestamp='2001-04-20'
timestamp='2001-09-04'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@@ -95,25 +95,25 @@ trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int dummy(){}" > $dummy.c
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int dummy(){}" > $dummy.c ;
for c in cc gcc c89 ; do
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
if test $? = 0 ; then
CC_FOR_BUILD="$c"; break
fi
done
rm -f $dummy.c $dummy.o $dummy.rel
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac
esac'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
@@ -150,6 +150,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# to ELF recently, or will in the future.
case "${UNAME_MACHINE}" in
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
then
@@ -204,6 +205,7 @@ main:
jsr \$26,exit
.end main
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
case `./$dummy` in
@@ -225,6 +227,9 @@ EOF
2-307)
UNAME_MACHINE="alphaev67"
;;
2-1307)
UNAME_MACHINE="alphaev68"
;;
esac
fi
rm -f $dummy.s $dummy
@@ -328,6 +333,9 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
sparc*:NetBSD:*)
echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
@@ -385,6 +393,7 @@ EOF
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
@@ -475,6 +484,7 @@ EOF
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
@@ -553,6 +563,7 @@ EOF
fi ;;
esac
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
@@ -586,9 +597,9 @@ EOF
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
rm -f $dummy.c $dummy
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
rm -f $dummy.c $dummy
fi ;;
esac
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -598,6 +609,7 @@ EOF
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
@@ -633,7 +645,7 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:*)
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
@@ -677,12 +689,13 @@ EOF
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
@@ -763,97 +776,29 @@ EOF
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
cat >$dummy.c <<EOF
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
#ifdef __MIPSEL__
printf ("%sel-unknown-linux-gnu\n", argv[1]);
#endif
return 0;
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
big) echo mips-unknown-linux-gnu && exit 0 ;;
little) echo mipsel-unknown-linux-gnu && exit 0 ;;
esac
;;
ppc:Linux:*:*)
# Determine Lib Version
cat >$dummy.c <<EOF
#include <features.h>
#if defined(__GLIBC__)
extern char __libc_version[];
extern char __libc_release[];
#endif
main(argc, argv)
int argc;
char *argv[];
{
#if defined(__GLIBC__)
printf("%s %s\n", __libc_version, __libc_release);
#else
printf("unknown\n");
#endif
return 0;
}
EOF
LIBC=""
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy | grep 1\.99 > /dev/null
if test "$?" = 0 ; then LIBC="libc1" ; fi
fi
rm -f $dummy.c $dummy
echo powerpc-unknown-linux-gnu${LIBC}
echo powerpc-unknown-linux-gnu
exit 0 ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit 0 ;;
alpha:Linux:*:*)
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
LIBC=""
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
case `./$dummy` in
0-0) UNAME_MACHINE="alpha" ;;
1-0) UNAME_MACHINE="alphaev5" ;;
1-1) UNAME_MACHINE="alphaev56" ;;
1-101) UNAME_MACHINE="alphapca56" ;;
2-303) UNAME_MACHINE="alphaev6" ;;
2-307) UNAME_MACHINE="alphaev67" ;;
esac
objdump --private-headers $dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f $dummy.s $dummy
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit 0 ;;
parisc:Linux:*:* | hppa:Linux:*:*)
@@ -883,40 +828,30 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
ld_supported_emulations=`cd /; ld --help 2>&1 \
| sed -ne '/supported emulations:/!d
ld_supported_targets=`cd /; ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported emulations: *//
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_emulations" in
i*86linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0
;;
elf_i*86)
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
i*86coff)
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0
;;
esac
# Either a pre-BFD a.out linker (linux-gnuoldld)
# or one that does not give us useful --help.
# GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
# If ld does not provide *any* "supported emulations:"
# that means it is gnuoldld.
test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
case "${UNAME_MACHINE}" in
i*86)
VENDOR=pc;
;;
*)
VENDOR=unknown;
;;
exit 0 ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
cat >$dummy.c <<EOF
#include <features.h>
#ifdef __cplusplus
@@ -928,15 +863,15 @@ EOF
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
printf ("%s-pc-linux-gnu\n", argv[1]);
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
#else
printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
printf ("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
@@ -945,9 +880,10 @@ EOF
rm -f $dummy.c $dummy
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit 0 ;;
i*86:UNIX_SV:4.2MP:2.*)
@@ -966,14 +902,13 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i*86:*:5:7*)
# Fixed at (any) Pentium or better
UNAME_MACHINE=i586
if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
i*86:*:5:[78]*)
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit 0 ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
@@ -1067,8 +1002,8 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
@@ -1080,6 +1015,10 @@ EOF
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
@@ -1172,11 +1111,18 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>

149
config.sub vendored
View File

@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
timestamp='2001-04-20'
timestamp='2001-09-07'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -117,7 +117,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -157,6 +157,14 @@ case $os in
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
@@ -215,26 +223,36 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
| pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| hppa64 \
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
| alphaev6[78] \
| we32k | ns16k | clipper | i370 | sh | sh[34] \
| powerpc | powerpcle \
| 1750a | dsp16xx | pdp10 | pdp11 \
| mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
| v850 | c4x \
| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
| pj | pjl | h8500)
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dsp16xx \
| fr30 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| m32r | m68000 | m68k | m88k | mcore \
| mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
| mipsisa32 \
| mn10200 | mn10300 \
| ns16k | ns32k \
| openrisc \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| s390 | s390x \
| sh | sh[34] | sh[34]eb | shbe | shle \
| sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
| stormy16 | strongarm \
| tahoe | thumb | tic80 | tron \
| v850 \
| we32k \
| x86 | xscale \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -242,7 +260,7 @@ case $basic_machine in
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65)
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
@@ -257,31 +275,43 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| hppa2.0n-* | hppa64-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
| alphaev6[78]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
| mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
| [cjt]90-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
| bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alphapca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armv*-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cray2-* | cydra-* \
| d10v-* | d30v-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| m32r-* \
| m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| s390-* | s390x-* \
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
| sparc-* | sparc64-* | sparc86x-* | sparclite-* \
| sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
| t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -727,6 +757,16 @@ case $basic_machine in
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
@@ -881,6 +921,10 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xmp)
basic_machine=xmp-cray
os=-unicos
@@ -934,7 +978,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh3 | sh4)
sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
sparc | sparcv9 | sparcv9b)
@@ -1018,11 +1062,13 @@ case $os in
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1346,6 +1392,9 @@ case $basic_machine in
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;

View File

@@ -305,6 +305,8 @@ else
case "$OPT_SSL" in
yes)
EXTRA_SSL=/usr/local/ssl ;;
off)
EXTRA_SSL= ;;
*)
dnl check the given spot right away!
EXTRA_SSL=$OPT_SSL
@@ -475,7 +477,9 @@ AC_CHECK_HEADERS( \
winsock.h \
time.h \
io.h \
pwd.h
pwd.h \
utime.h \
sys/utime.h
)
dnl Check for libz header
@@ -529,7 +533,8 @@ AC_CHECK_FUNCS( socket \
strlcat \
getpwuid \
geteuid \
dlopen
dlopen \
utime
)
dnl removed 'getpass' check on October 26, 2000
@@ -571,10 +576,6 @@ AC_CONFIG_FILES([Makefile \
packages/Linux/RPM/curl.spec \
packages/Linux/RPM/curl-ssl.spec \
packages/Solaris/Makefile \
perl/Makefile \
perl/Curl_easy/Makefile \
php/Makefile \
php/examples/Makefile \
curl-config
])
AC_OUTPUT

21
curl-mode.el Normal file
View File

@@ -0,0 +1,21 @@
;;;; Emacs Lisp help for writing curl code. ;;;;
;;; In C files, put something like this to load this file automatically:
;;
;; /* -----------------------------------------------------------------
;; * local variables:
;; * eval: (load-file "../curl-mode.el")
;; * end:
;; */
;;
;; (note: make sure to get the path right in the argument to load-file).
;;; The curl hacker's C conventions
;;; we use intent-level 2
(setq c-basic-offset 2)
;;; never ever use tabs to indent!
(setq indent-tabs-mode nil)
;;; I like this, stolen from Subversion! ;-)
(setq angry-mob-with-torches-and-pitchforks t)

View File

@@ -10,6 +10,12 @@ To Think About When Contributing Source Code
in mind when you decide to write a contribution to the project. This concerns
new features as well as corrections to existing flaws or bugs.
Join the Community
Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
list(s). Read up on details before you post questions. Read this file before
you start sending patches!
The License Issue
When contributing with code, you agree to put your changes and new code under
@@ -21,6 +27,12 @@ The License Issue
GPL (as we don't want the GPL virus to attack users of libcurl) but they must
use "GPL compatible" licenses.
What To Read
Source code, the man pages, the INTERALS document, the TODO, the most recent
CHANGES. Just lurking on the libcurl mailing list is gonna give you a lot of
insights on what's going on right now.
Naming
Try using a non-confusing naming scheme for your new functions and variable
@@ -87,7 +99,9 @@ Write Access to CVS Repository
If you are a frequent contributor, or have another good reason, you can of
course get write access to the CVS repository and then you'll be able to
check-in all your changes straight into the CVS tree instead of sending all
changes by mail as patches. Just ask if this is what you'd want.
changes by mail as patches. Just ask if this is what you'd want. You will be
required to have posted a few quality patches first, before you can be
granted write access.
Test Cases

View File

@@ -1,4 +1,4 @@
Updated: August 7, 2001 (http://curl.haxx.se/docs/faq.shtml)
Updated: August 23, 2001 (http://curl.haxx.se/docs/faq.shtml)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -81,7 +81,7 @@ FAQ
fact it can also be pronounced 'see URL' also helped.
Curl supports a range of common Internet protocols, currently including
HTTP, HTTPS, FTP, GOPHER, LDAP, DICT, TELNET and FILE.
HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE.
We spell it cURL or just curl. We pronounce it with an initial k sound:
[kurl].
@@ -467,9 +467,9 @@ FAQ
4.6. Can you tell me what error code 142 means?
All error codes that are larger than the highest documented error code means
that curl has existed due to a timeout. There was no nice way for curl to
abort from such a condition and that's why it got this undocumented
error. This should not occur in releases after 7.4.1.
that curl has exited due to a crash. This is a serious error, and we
appriciate a detailed bug report from you that describes how we could go
ahead and repeat this!
4.7. How do I keep user names and passwords secret in Curl command lines?

View File

@@ -1,117 +0,0 @@
_ _ _ _
| (_) |__ ___ _ _ _ __| |
| | | '_ \ / __| | | | '__| |
| | | |_) | (__| |_| | | | |
|_|_|_.__/ \___|\__,_|_| |_|
How To Use Libcurl In Your C/C++ Program
[ libcurl can be used directly from within your Java, PHP, Perl, Ruby or Tcl
programs as well, look elsewhere for documentation on this ]
The interface is meant to be very simple for applictions/programmers, hence
the name "easy". We have therefore minimized the number of entries.
The Easy Interface
When using the easy interface, you init your session and get a handle, which
you use as input to the following interface functions you use. Use
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. curl_easy_setopt() is there for this.
When all is setup, you tell libcurl to perform the transfer using
curl_easy_perform(). It will then do the entire operation and won't return
until it is done or failed.
After the transfer has been made, you cleanup the session with
curl_easy_cleanup() and libcurl is entirely off the hook! If you want
persistant connections, you don't cleanup immediately, but instead run ahead
and perform other transfers. See the chapter below for Persistant
Connections.
While the above mentioned four functions are the main functions to use in the
easy interface, there is a series of other helpful functions to use. They
are:
curl_version() - displays the libcurl version
curl_getdate() - converts a date string to time_t
curl_getenv() - portable environment variable reader
curl_easy_getinfo() - get information about a performed transfer
curl_formparse() - helps building a HTTP form POST
curl_formfree() - free a list built with curl_formparse()
curl_slist_append() - builds a linked list
curl_slist_free_all() - frees a whole curl_slist
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
libcurl works *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.
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
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
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 defined behaviour.

View File

@@ -12,7 +12,9 @@ man_MANS = \
curl_easy_init.3 \
curl_easy_perform.3 \
curl_easy_setopt.3 \
curl_easy_duphandle.3 \
curl_formparse.3 \
curl_formadd.3 \
curl_formfree.3 \
curl_getdate.3 \
curl_getenv.3 \
@@ -28,8 +30,47 @@ man_MANS = \
curl_global_cleanup.3 \
libcurl.3
SUBDIRS = examples
HTMLPAGES = \
curl.html \
curl-config.html \
curl_easy_cleanup.html \
curl_easy_getinfo.html \
curl_easy_init.html \
curl_easy_perform.html \
curl_easy_setopt.html \
curl_easy_duphandle.html \
curl_formadd.html \
curl_formparse.html \
curl_formfree.html \
curl_getdate.html \
curl_getenv.html \
curl_slist_append.html \
curl_slist_free_all.html \
curl_version.html \
curl_escape.html \
curl_unescape.html \
curl_strequal.html \
curl_strnequal.html \
curl_mprintf.html \
curl_global_init.html \
curl_global_cleanup.html \
libcurl.html
EXTRA_DIST = $(man_MANS) \
MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \
LIBCURL README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
$(HTMLPAGES)
SUBDIRS = examples
MAN2HTML= gnroff -man $< | man2html >$@
SUFFIXES = .1 .3 .html
html: $(HTMLPAGES)
.3.html:
$(MAN2HTML)
.1.html:
$(MAN2HTML)

View File

@@ -12,46 +12,31 @@ TODO
To do in a future release (random order):
* FTP ASCII upload does not follow RFC959 section 3.1.1.1:
"The sender converts the data from an internal character representation to
the standard 8-bit NVT-ASCII representation (see the Telnet
specification). The receiver will convert the data from the standard form
to his own internal form."
* Make the connect non-blocking so that timeouts work for connect in
multi-threaded programs
* Using FILE * in the libcurl API introduces a serious limitation since (at
least in the *nix falvours I know) you can fopen only the first 256
files. This means, that an application that first opens or fopens 256 files
has no chance to use libcurl. Using open and file descriptors instead of
FILE * would solve the problem. This implies a minor API
change/enhancement. ck1 <ck1@swissonline.ch>
* It would be nice to be able to use "-d" (or something similar) to attach
parameters of EITHER the GET or POST type... It would either require
another curl argument to specify "GET" (obviously the default should remain
POST), or it would require a new curl argument (perhaps -G/--get-data).
I know we're running out of letters, but it somehow feels a little
"cleaner" to just tag on each of your HTTP "parameters" (data-items) one by
one and let curl put them together, rather than having to put them together
myself and include them in the URL.
* Add an interface that enables a user to select prefered SSL ciphers to use.
* Make curl deal with cookies better. libcurl should be able to maintain a
"cookie jar". Updating it with cookies that is received, and using it to
pass cookies to the servers that have matching cookies in the jar.
http://curl.haxx.se/dev/cookie-jar.txt
* Consider an interface to libcurl that allows applications to easier get to
know what cookies that are sent back in the response headers.
* Make SSL session ids get used if multiple HTTPS documents from the same
host is requested. http://curl.haxx.se/dev/SSL_session_id.txt
* HTTP PUT for files passed on stdin. Requires libcurl to send the file
with chunked content encoding. http://curl.haxx.se/dev/HTTP-PUT-stdin.txt
* HTTP PUT for files passed on stdin *OR* when the --crlf option is
used. Requires libcurl to send the file with chunked content
encoding. http://curl.haxx.se/dev/HTTP-PUT-stdin.txt
* Introduce another callback interface for upload/download that makes one
less copy of data and thus a faster operation.
http://curl.haxx.se/dev/no_copy_callbacks.txt
* An option to only download remote FTP files if they're newer than the local
one is a good idea, and it would fit right into the same syntax as the
already working http dito works. It of course requires that 'MDTM' works,
and it isn't a standard FTP command.
* Suggested on the mailing list: CURLOPT_FTP_MKDIR...!
* Add configure options that disables certain protocols in libcurl to
@@ -63,10 +48,6 @@ To do in a future release (random order):
* Make TELNET work on windows!
* Add a command line option that allows the output file to get the same time
stamp as the remote file. libcurl already is capable of fetching the remote
file's date.
* Make curl's SSL layer option capable of using other free SSL libraries.
Such as the Mozilla Security Services
(http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS

View File

@@ -1,6 +1,7 @@
Online: http://curl.haxx.se/docs/httpscripting.shtml
Author: Daniel Stenberg <daniel@haxx.se>
Date: September 15, 2000
Version: 0.3
Date: August 20, 2001
Version: 0.4
The Art Of Scripting HTTP Requests Using Curl
=============================================
@@ -174,6 +175,19 @@ Version: 0.3
curl -d "birthyear=1905&press=OK&person=daniel" [URL]
4.5 FIGURE OUT WHAT A POST LOOKS LIKE
When you're about fill in a form and send to a server by using curl instead
of a browser, you're of course very interested in sending a POST exactly the
way your browser does.
An easy way to get to see this, is to save the HTML page with the form on
your local disk, mofidy the 'method' to a GET, and press the submit button
(you could also change the action URL if you want to).
You will then clearly see the data get appended to the URL, separated with a
'?'-letter as GET forms are supposed to.
5. PUT
The perhaps best way to upload data to a HTTP server is to use PUT. Then
@@ -182,7 +196,7 @@ Version: 0.3
Put a file to a HTTP server with curl:
curl -t uploadfile www.uploadhttp.com/receive.cgi
curl -T uploadfile www.uploadhttp.com/receive.cgi
6. AUTHENTICATION
@@ -289,7 +303,6 @@ Version: 0.3
curl -b "name=Daniel" www.cookiesite.com
Cookies are sent as common HTTP headers. This is practical as it allows curl
to record cookies simply by recording headers. Record cookies with curl by
using the -D option like:
@@ -304,6 +317,14 @@ Version: 0.3
curl -b stored_cookies_in_file www.cookiesite.com
Curl's "cookie engine" gets enabled when you use the -b option. If you only
want curl to understand received cookies, use -b with a file that doesn't
exist. Example, if you want to let curl understand cookies from a page and
follow a location (and thus possibly send back cookies it received), you can
invoke it like:
curl -b nada -L www.cookiesite.com
11. HTTPS
There are a few ways to do secure HTTP transfers. The by far most common

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
.TH curl 1 "16 Aug 2001" "Curl 7.8.1" "Curl Manual"
.TH curl 1 "12 Sep 2001" "Curl 7.9" "Curl Manual"
.SH NAME
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
HTTPS syntax.
@@ -91,6 +91,12 @@ 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.
If this option is used twice, the second one will disable ASCII usage.
.IP "--ciphers <list of ciphers>"
(SSL) Specifies which ciphers to use in the connection. The list of ciphers
must be using valid ciphers. Read up on SSL cipher list details on this URL:
.I http://www.openssl.org/docs/apps/ciphers.html (Option added in curl 7.9)
If this option is used severl times, the last one will override the others.
.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
@@ -100,15 +106,16 @@ also the
option.
If this option is used several times, the last one will be used.
.IP "-c/--continue"
.B Deprecated. Use '-C -' instead.
Continue/Resume a previous file transfer. This instructs curl to
continue appending data on the file where it was previously left,
possibly because of a broken connection to the server. There must be
a named physical file to append to for this to work.
Note: Upload resume is depening on a command named SIZE not always
present in all ftp servers! Upload resume is for FTP only.
HTTP resume is only possible with HTTP/1.1 or later servers.
.IP "-c/--cookie-jar <file name>"
Specify to which file you want curl to write all cookies after a completed
operation. Curl writes all cookies previously read from a specified file as
well as all cookies received from remote server(s). If no cookies are known,
no file will be written. The file will be written using the Netscape cookie
file format. If you set the file name to a single dash, "-", the cookies will
be written to stdout. (Option added in curl 7.9)
If this option is used several times, the last specfied file name will be
used.
.IP "-C/--continue-at <offset>"
Continue/Resume a previous file transfer at the given offset. The
given offset is the exact number of bytes that will be skipped
@@ -237,7 +244,7 @@ added in curl 7.6)
When used, this option will make all data specified with -d/--data or
--data-binary to be used in a HTTP GET request instead of the POST request
that otherwise would be used. The data will be appended to the URL with a '?'
separator.
separator. (Option added in curl 7.9)
.IP "-h/--help"
Usage help.
.IP "-H/--header <header>"
@@ -324,6 +331,8 @@ file in the user's home directory for login name and password. This is
typically used for ftp on unix. If used with http, curl will enable user
authentication. See
.BR netrc(4)
or
.BR ftp(1)
for details on the file format. Curl will not complain if that file
hasn't the right permissions (it should not be world nor group
readable). The environment variable "HOME" is used to find the home
@@ -452,6 +461,12 @@ 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.
If this option is used several times, the last one will be used.
.IP "-R/--remote-time"
When used, this will make libcurl attempt to figure out the timestamp of the
remote file, and if that is available make the local file get that same
timestamp.
If this option is used twice, the second time disables this again.
.IP "-s/--silent"
Silent mode. Don't show progress meter or error messages. Makes
Curl mute.

View File

@@ -0,0 +1,37 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" $Id$
.\"
.TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual"
.SH NAME
curl_easy_duphandle - Clone a libcurl session handle
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "CURL *curl_easy_duphandle(CURL *"handle ");"
.ad
.SH DESCRIPTION
This function will return a new curl handle, a duplicate, using all the
options previously set in the input curl \fIhandle\fP. Both handles can
subsequently be used independently and they must both be freed with
\fIcurl_easy_cleanup()\fP.
All strings that the input handle has been told to point to (as opposed to
copy) with previous calls to \fIcurl_easy_setopt\fP using char * inputs, will
be pointed to by the new handle as well. You must therefore make sure to keep
the data around until both handles have been cleaned up.
The new handle will \fBnot\fP inherit any state information, no connections,
no SSL sessions and no cookies.
\fBNote\fP that even in multi-threaded programs, this function must be called
in a synchronous way, the input handle may not be in use when cloned.
This function was added in libcurl 7.9.
.SH RETURN VALUE
If this function returns NULL, something went wrong and no valid handle was
returned.
.SH "SEE ALSO"
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
.SH BUGS
Surely there are some, you tell me!

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" $Id$
.\"
.TH curl_easy_setopt 3 "20 August 2001" "libcurl 7.8.1" "libcurl Manual"
.TH curl_easy_setopt 3 "12 Sep 2001" "libcurl 7.9" "libcurl Manual"
.SH NAME
curl_easy_setopt - Set curl easy-session options
.SH SYNOPSIS
@@ -140,7 +140,9 @@ CURLOPT_INFILE and CURLOPT_INFILESIZE are also interesting for uploads.
A non-zero parameter tells the library to do a regular HTTP post. This is a
normal application/x-www-form-urlencoded kind, which is the most commonly used
one by HTML forms. See the CURLOPT_POSTFIELDS option for how to specify the
data to post and CURLOPT_POSTFIELDSIZE in how to set the data size.
data to post and CURLOPT_POSTFIELDSIZE in how to set the data size. Starting
with libcurl 7.8, this option is obsolete. Using the CURLOPT_POSTFIELDS option
will imply this option.
.TP
.B CURLOPT_FTPLISTONLY
A non-zero parameter tells the library to just list the names of an ftp
@@ -211,7 +213,8 @@ that this does not work in multi-threaded programs!
.TP
.B CURLOPT_POSTFIELDS
Pass a char * as parameter, which should be the full data to post in a HTTP
post operation. See also the CURLOPT_POST.
post operation. See also the CURLOPT_POST. Since 7.8, using CURLOPT_POSTFIELDS
implies CURLOPT_POST.
.TP
.B CURLOPT_POSTFIELDSIZE
If you want to post data to the server without letting libcurl do a strlen()
@@ -275,7 +278,7 @@ instruct what data to pass on to the server. Pass a pointer to a linked list
of HTTP post structs as parameter. The linked list should be a fully valid
list of 'struct HttpPost' structs properly filled in. The best and most
elegant way to do this, is to use
.I curl_formparse(3)
.I curl_formadd(3)
as documented. The data in this list must remained intact until you close this
curl handle again with curl_easy_cleanup().
.TP
@@ -512,6 +515,24 @@ previously using the same curl handle. (Added in 7.8.1)
Pass a long. Set if we should verify the Common name from the peer certificate
in the SSL handshake, set 1 to check existence, 2 to ensure that it matches
the provided hostname. (Added in 7.8.1)
.TP
.B CURLOPT_COOKIEJAR
Pass a file name as char *, zero terminated. This will make libcurl dump all
internally known cookies to the specified file when curl_easy_cleanup() is
called. If no cookies are known, no file will be created. Specify "-" to
instead have the cookies written to stdout.
.TP
.B CURLOPT_SSL_CIPHER_LIST
Pass a char *, pointing to a zero terminated string holding the list of
ciphers to use for the SSL connection. The list must be syntactly correct, it
consists of one or more cipher strings separated by colons. Commas or spaces
are also acceptable separators but colons are normally used, \!, \- and \+ can
be used as operators. Valid examples of cipher lists include 'RC4-SHA',
\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
compile OpenSSL.
You'll find all details about cipher lists on this URL:
.I http://www.openssl.org/docs/apps/ciphers.html
.PP
.SH RETURN VALUE
0 means the option was set properly, non-zero means an error as

121
docs/curl_formadd.3 Normal file
View File

@@ -0,0 +1,121 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" $Id$
.\"
.TH curl_formadd 3 "27 August 2001" "libcurl 7.9" "libcurl Manual"
.SH NAME
curl_formadd - add a section to a multipart/formdata HTTP POST
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "CURLcode curl_formadd(struct HttpPost ** " firstitem,
.BI "struct HttpPost ** " lastitem, " ...);"
.ad
.SH DESCRIPTION
curl_formadd() is used to append sections when building a multipart/formdata
HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at
a time until you've added all the sections you want included and then you pass
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
\fIlastitem\fP is set after each call and on repeated invokes it should be
left as set to allow repeated invokes to find the end of the list in a faster
way.
After \fIlastitem\fP follow the real arguments that constitute the
new section (if the following description confuses you jump directly
to the examples):
CURLFORM_COPYNAME or CURLFORM_PTRNAME followed by a string is used for
the name of the section. Optionally one may use CURLFORM_NAMELENGTH to
specify the length of the name (allowing null characters within the name).
The three options for providing values are: CURLFORM_COPYCONTENTS,
CURLFORM_PTRCONTENTS, or CURLFORM_FILE, followed by a char or void
pointer (allowed for PTRCONTENTS).
Other arguments may be CURLFORM_CONTENTTYPE if the
user wishes to specify one (for FILE if no type is given the library
tries to provide the correct one; for CONTENTS no Content-Type is sent
in this case)
For CURLFORM_PTRCONTENTS or CURLFORM_COPYNAME the user may also add
CURLFORM_CONTENTSLENGTH followed by the length as a long (if not given
the library will use strlen to determine the length).
For CURLFORM_FILE the user may send multiple files in one section by
providing multiple CURLFORM_FILE arguments each followed by the filename
(and each FILE is allowed to have a CONTENTTYPE).
The last argument always is CURLFORM_END.
The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing 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.
This function will copy all input data except the data pointed to by
the arguments after CURLFORM_PTRNAME and CURLFORM_PTRCONTENTS and keep
its own version of it allocated until you call \fIcurl_formfree\fP. When
you've passed the pointer to \fIcurl_easy_setopt\fP, you must not free
the list until after you've called \fIcurl_easy_cleanup\fP for the
curl handle. If you provide a pointer as an arguments after
CURLFORM_PTRNAME or CURLFORM_PTRCONTENTS you must ensure that the pointer
stays valid until you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP.
See example below.
.SH RETURN VALUE
Returns non-zero if an error occurs.
.SH EXAMPLE
.nf
HttpPost* post = NULL;
HttpPost* last = NULL;
char namebuffer[] = "name buffer";
long namelength = strlen(namebuffer);
char buffer[] = "test buffer";
char htmlbuffer[] = "<HTML>test buffer</HTML>";
long htmlbufferlength = strlen(htmlbuffer);
/* add null character into htmlbuffer, to demonstrate that
transfers of buffers containing null characters actually work
*/
htmlbuffer[8] = '\\0';
/* Add simple name/content section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
CURLFORM_COPYCONTENTS, "content", CURLFORM_END);
/* Add simple name/content/contenttype section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode",
CURLFORM_COPYCONTENTS, "<HTML></HTML>",
CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);
/* Add name/ptrcontent section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent",
CURLFORM_PTRCONTENTS, buffer, CURLFORM_END);
/* Add ptrname/ptrcontent section */
curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer,
CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH,
namelength, CURLFORM_END);
/* Add name/ptrcontent/contenttype section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole",
CURLFORM_PTRCONTENTS, htmlbuffer,
CURLFORM_CONTENTSLENGTH, htmlbufferlength,
CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);
/* Add simple file section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
CURLFORM_FILE, "my-face.jpg", CURLFORM_END);
/* Add file/contenttype section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
CURLFORM_FILE, "my-face.jpg",
CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END);
/* Add two file section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures",
CURLFORM_FILE, "my-face.jpg",
CURLFORM_FILE, "your-face.jpg", CURLFORM_END);
/* Set the form info */
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
.SH "SEE ALSO"
.BR curl_easy_setopt "(3), "
.BR curl_formparse "(3) [deprecated], "
.BR curl_formfree "(3)
.SH BUGS
Surely there are some, you tell me!

View File

@@ -12,12 +12,14 @@ curl_formfree - free a previously build multipart/formdata HTTP POST chain
.ad
.SH DESCRIPTION
curl_formfree() is used to clean up data previously built/appended with
curl_formparse(). This must be called when the data has been used, which
typically means after the curl_easy_perform() has been called.
curl_formadd()/curl_formparse(). This must be called when the data has
been used, which typically means after the curl_easy_perform() has
been called.
.SH RETURN VALUE
None
.SH "SEE ALSO"
.BR curl_formparse "(3) "
.BR curl_formparse "(3) [deprecated], "
.BR curl_formadd "(3) "
.SH BUGS
libcurl 7.7.1 and earlier versions does not allow a NULL pointer to be used as
argument.

View File

@@ -4,7 +4,8 @@
.\"
.TH curl_formparse 3 "21 May 2001" "libcurl 7.7.4" "libcurl Manual"
.SH NAME
curl_formparse - add a section to a multipart/formdata HTTP POST
curl_formparse - add a section to a multipart/formdata HTTP POST:
deprecated (use curl_formadd instead)
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
@@ -79,6 +80,7 @@ Returns non-zero if an error occurs.
.SH "SEE ALSO"
.BR curl_easy_setopt "(3), "
.BR curl_formadd "(3), "
.BR curl_formfree "(3)
.SH BUGS
Surely there are some, you tell me!

View File

@@ -8,7 +8,7 @@ curl_slist_append - add a string to an slist
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "struct curl_slist *curl_slist_append(struct curl_slit *" list,
.BI "struct curl_slist *curl_slist_append(struct curl_slist *" list,
.BI "const char * "string ");"
.ad
.SH DESCRIPTION

View File

@@ -4,9 +4,9 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c \
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c postit2.c \
win32sockets.c persistant.c ftpget.c Makefile.example \
multithread.c getinmemory.c
multithread.c getinmemory.c ftpupload.c httpput.c
all:
@echo "done"

88
docs/examples/ftpupload.c Normal file
View File

@@ -0,0 +1,88 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include <stdio.h>
#include <curl/curl.h>
/*
* This example shows an FTP upload, with a rename of the file just after
* a successful upload.
*
* Example based on source code provided by Erick Nuwendam. Thanks!
*/
#define LOCAL_FILE "/tmp/uploadthis.txt"
#define UPLOAD_FILE_AS "while-uploading.txt"
#define REMOTE_URL "ftp://localhost/" UPLOAD_FILE_AS
#define RENAME_FILE_TO "renamed-and-fine.txt"
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *ftpfile;
FILE * hd_src ;
int hd ;
struct stat file_info;
struct curl_slist *headerlist=NULL;
char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
char buf_2 [] = "RNTO " RENAME_FILE_TO;
/* get the file size of the local file */
hd = open(LOCAL_FILE, O_RDONLY) ;
fstat(hd, &file_info);
close(hd) ;
/* get a FILE * of the same file, could also be made with
fdopen() from the previous descriptor, but hey this is just
an example! */
hd_src = fopen(LOCAL_FILE, "rb");
/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* build a list of commands to pass to libcurl */
headerlist = curl_slist_append(headerlist, buf_1);
headerlist = curl_slist_append(headerlist, buf_2);
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
/* specify target */
curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
/* pass in that last of FTP commands to run after the transfer */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_INFILE, hd_src);
/* and give the size of the upload (optional) */
curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size);
/* Now run off and do what you've been told! */
res = curl_easy_perform(curl);
/* clean up the FTP commands list */
curl_slist_free_all (headerlist);
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(hd_src); /* close the local file */
curl_global_cleanup();
return 0;
}

100
docs/examples/httpput.c Normal file
View File

@@ -0,0 +1,100 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <curl/curl.h>
/*
* This example shows a HTTP PUT operation. PUTs a file given as a command
* line argument to the URL also given on the command line.
*
* This example also uses its own read callback.
*/
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t retcode;
/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */
retcode = fread(ptr, size, nmemb, stream);
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
return retcode;
}
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *ftpfile;
FILE * hd_src ;
int hd ;
struct stat file_info;
char *file;
char *url;
if(argc < 3)
return 1;
file= argv[1];
url = argv[2];
/* get the file size of the local file */
hd = open(file, O_RDONLY) ;
fstat(hd, &file_info);
close(hd) ;
/* get a FILE * of the same file, could also be made with
fdopen() from the previous descriptor, but hey this is just
an example! */
hd_src = fopen(file, "rb");
/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
/* HTTP PUT please */
curl_easy_setopt(curl, CURLOPT_PUT, TRUE);
/* specify target */
curl_easy_setopt(curl,CURLOPT_URL, url);
/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_INFILE, hd_src);
/* and give the size of the upload (optional) */
curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size);
/* Now run off and do what you've been told! */
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(hd_src); /* close the local file */
curl_global_cleanup();
return 0;
}

92
docs/examples/postit2.c Normal file
View File

@@ -0,0 +1,92 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Example code that uploads a file name 'foo' to a remote script that accepts
* "HTML form based" (as described in RFC1738) uploads using HTTP POST.
*
* The imaginary form we'll fill in looks like:
*
* <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
* Enter file: <input type="file" name="sendfile" size="40">
* Enter file name: <input type="text" name="filename" size="30">
* <input type="submit" value="send" name="submit">
* </form>
*
* This exact source code has not been verified to work.
*/
/* to make this work under windows, use the win32-functions from the
win32socket.c file as well */
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#if LIBCURL_VERSION_NUM < 0x070900
#error "curl_formadd() is not introduced until libcurl 7.9 and later"
#endif
int main(int argc, char *argv[])
{
CURL *curl;
CURLcode res;
struct HttpPost *formpost=NULL;
struct HttpPost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
char buf[] = "Expect:";
/* Fill in the file upload field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, "postit2.c",
CURLFORM_END);
/* Fill in the filename field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, "postit2.c",
CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
curl = curl_easy_init();
/* initalize custom header list (stating that Expect: 100-continue is not
wanted */
headerlist = curl_slist_append(headerlist, buf);
if(curl) {
/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, "http://curl.haxx.se/examplepost.cgi");
if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) )
/* only disable 100-continue header if explicitly requested */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
/* then cleanup the formpost chain */
curl_formfree(formpost);
/* free slist */
curl_slist_free_all (headerlist);
}
return 0;
}

View File

@@ -53,11 +53,14 @@ portable environment variable reader
.B curl_easy_getinfo()
get information about a performed transfer
.TP
.B curl_formparse()
.B curl_formadd()
helps building a HTTP form POST
.TP
.B curl_formparse()
helps building a HTTP form POST (deprecated since 7.9 use curl_formadd()!)
.TP
.B curl_formfree()
free a list built with curl_formparse()
free a list built with curl_formparse()/curl_formadd()
.TP
.B curl_slist_append()
builds a linked list

View File

@@ -58,13 +58,19 @@ extern "C" {
struct HttpPost {
struct HttpPost *next; /* next entry in the list */
char *name; /* pointer to allocated name */
long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */
char *contenttype; /* Content-Type */
struct HttpPost *more; /* if one field name has more than one file, this
link should link to following files */
long flags; /* as defined below */
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer
do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */
};
typedef int (*curl_progress_callback)(void *clientp,
@@ -447,6 +453,13 @@ typedef enum {
* handshake, set 1 to check existence, 2 to ensure that it matches the
* provided hostname. */
CINIT(SSL_VERIFYHOST, LONG, 81),
/* Specify which file name to write all known cookies in after completed
operation. Set file name to "-" (dash) to make it go to stdout. */
CINIT(COOKIEJAR, OBJECTPOINT, 82),
/* Specify which SSL ciphers to use */
CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
CURLOPT_LASTENTRY /* the last unusued */
} CURLoption;
@@ -483,6 +496,34 @@ int curl_formparse(char *string,
struct HttpPost **httppost,
struct HttpPost **last_post);
/* name is uppercase CURLFORM_<name> */
#ifdef CFINIT
#undef CFINIT
#endif
#define CFINIT(name) CURLFORM_ ## name
typedef enum {
CFINIT(NOTHING), /********* the first one is unused ************/
/* */
CFINIT(COPYNAME),
CFINIT(PTRNAME),
CFINIT(NAMELENGTH),
CFINIT(COPYCONTENTS),
CFINIT(PTRCONTENTS),
CFINIT(CONTENTSLENGTH),
CFINIT(FILE),
CFINIT(CONTENTTYPE),
CFINIT(END),
CURLFORM_LASTENTRY /* the last unusued */
} CURLformoption;
/* new external form function */
int curl_formadd(struct HttpPost **httppost,
struct HttpPost **last_post,
...);
/* cleanup a form: */
void curl_formfree(struct HttpPost *form);
@@ -495,8 +536,8 @@ 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);
char *curl_escape(const char *string, int length);
char *curl_unescape(const char *string, int length);
/* curl_global_init() should be invoked exactly once for each application that
uses libcurl */
@@ -507,8 +548,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void);
/* This is the version number */
#define LIBCURL_VERSION "7.8.1"
#define LIBCURL_VERSION_NUM 0x070801
#define LIBCURL_VERSION "7.9"
#define LIBCURL_VERSION_NUM 0x070900
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {

View File

@@ -46,6 +46,21 @@ void curl_easy_cleanup(CURL *curl);
*/
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
/*
* NAME curl_easy_duphandle()
*
* DESCRIPTION
*
* Creates a new curl session handle with the same options set for the handle
* passed in. Duplicating a handle could only be a matter of cloning data and
* options, internal state info and things like persistant connections cannot
* be transfered. It is useful in multithreaded applications when you can run
* curl_easy_duphandle() for each new thread to avoid a series of identical
* curl_easy_setopt() invokes in every thread.
*/
CURL* curl_easy_duphandle(CURL *curl);
#ifdef __cplusplus
}
#endif

8
java/MANIFEST Normal file
View File

@@ -0,0 +1,8 @@
CurlGlue.java
CurlWrite.java
define2java.pl
javacurl.c
Makefile
README
test.java
MANIFEST

View File

@@ -13,3 +13,5 @@ stuff supported.
The interface is not set yet, bring your suggestions!
Feel free to grab the source files in here and help out!
The 'test.java' is the actual program that uses the curl stuff.

View File

@@ -1,3 +1,25 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
* licenses. You may pick one of these licenses.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
*****************************************************************************/
#include <curl/curl.h> /* libcurl header */
#include "CurlGlue.h" /* the JNI-generated glue header file */

View File

@@ -16,7 +16,7 @@ lib_LTLIBRARIES = libcurl.la
INCLUDES = -I$(top_srcdir)/include
libcurl_la_LDFLAGS = -version-info 2:1:0
libcurl_la_LDFLAGS = -version-info 2:2:0
# 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
# 1.

View File

@@ -1,11 +1,10 @@
#############################################################
# $Id: Makefile.am,v 1.20 2001/08/08 07:46:44 bagder Exp $
#
## Makefile for building libcurl.lib with MSVC6
## Use: nmake -f makefile.vc6 [release | release-ssl | debug]
## (default is release)
##
## Comments to: Troy Engel <tengel@sonic.net>
## Originally written by: Troy Engel <tengel@sonic.net>
## Updated by: Craig Davison <cd@securityfocus.com>
## Updated by: SM <sm@technologist.com>
@@ -30,7 +29,7 @@ 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"
LFLAGS = /nologo
LINKLIBS = wsock32.lib
LINKLIBS = ws2_32.lib
LINKSLIBS = libeay32.lib ssleay32.lib RSAglue.lib
RELEASE_OBJS= \
@@ -127,7 +126,7 @@ RELEASE_SSL_OBJS= \
versionrs.obj \
easyrs.obj \
strequalrs.obj \
strtokd.obj
strtokrs.obj
LINK_OBJS= \
base64.obj \
@@ -310,7 +309,7 @@ formdatars.obj: formdata.c
ftprs.obj: ftp.c
$(CCRS) $(CFLAGS) ftp.c
httprs.obj: http.c
$(CCR) $(CFLAGS) http.c
$(CCRS) $(CFLAGS) http.c
http_chunksrs.obj: http_chunks.c
$(CCRS) $(CFLAGS) http_chunks.c
ldaprs.obj: ldap.c

View File

@@ -32,9 +32,8 @@
* This code will break if int is smaller than 32 bits
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "setup.h"
#include <stdlib.h>
#include <string.h>
@@ -261,3 +260,11 @@ void *suck(int *lenptr) {
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
@@ -95,7 +95,7 @@ Example set of cookies:
/****************************************************************************
*
* cookie_add()
* Curl_cookie_add()
*
* Add a single cookie line to the cookie keeping object.
*
@@ -112,6 +112,7 @@ Curl_cookie_add(struct CookieInfo *c,
char *ptr;
char *semiptr;
struct Cookie *co;
struct Cookie *lastc=NULL;
time_t now = time(NULL);
bool replace_old = FALSE;
@@ -129,13 +130,11 @@ Curl_cookie_add(struct CookieInfo *c,
semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
ptr = lineptr;
do {
if(semiptr)
*semiptr='\0'; /* zero terminate for a while */
/* we have a <what>=<this> pair or a 'secure' word here */
if(strchr(ptr, '=')) {
name[0]=what[0]=0; /* init the buffers */
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^=]=%"
MAX_COOKIE_LINE_TXT "[^\r\n]",
MAX_COOKIE_LINE_TXT "[^;\r\n]",
name, what)) {
/* this is a legal <what>=<this> pair */
if(strequal("path", name)) {
@@ -178,7 +177,7 @@ Curl_cookie_add(struct CookieInfo *c,
}
}
else {
if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^\r\n]",
if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]",
what)) {
if(strequal("secure", what))
co->secure = TRUE;
@@ -190,7 +189,6 @@ Curl_cookie_add(struct CookieInfo *c,
if(!semiptr)
continue; /* we already know there are no more cookies */
*semiptr=';'; /* put the semicolon back */
ptr=semiptr+1;
while(ptr && *ptr && isspace((int)*ptr))
ptr++;
@@ -245,6 +243,7 @@ Curl_cookie_add(struct CookieInfo *c,
We don't currently take advantage of this knowledge.
*/
co->field1=strequal(ptr, "TRUE")+1; /* store information */
break;
case 2:
/* It turns out, that sometimes the file format allows the path
@@ -293,6 +292,8 @@ Curl_cookie_add(struct CookieInfo *c,
}
co->livecookie = c->running;
/* now, we have parsed the incoming line, we must now check if this
superceeds an already existing cookie, which it may if the previous have
the same domain and path as this */
@@ -327,6 +328,26 @@ Curl_cookie_add(struct CookieInfo *c,
}
if(replace_old && !co->livecookie && clist->livecookie) {
/* Both cookies matched fine, except that the already present
cookie is "live", which means it was set from a header, while
the new one isn't "live" and thus only read from a file. We let
live cookies stay alive */
/* Free the newcomer and get out of here! */
if(co->domain)
free(co->domain);
if(co->path)
free(co->path);
if(co->name)
free(co->name);
if(co->value)
free(co->value);
free(co);
return NULL;
}
if(replace_old) {
co->next = clist->next; /* get the next-pointer first */
@@ -351,39 +372,51 @@ Curl_cookie_add(struct CookieInfo *c,
}
}
lastc = clist;
clist = clist->next;
}
if(!replace_old) {
/* first, point to our "next" */
co->next = c->cookies;
/* then make ourselves first in the list */
c->cookies = co;
/* then make the last item point on this new one */
if(lastc)
lastc->next = co;
else
c->cookies = co;
}
c->numcookies++; /* one more cookie in the jar */
return co;
}
/*****************************************************************************
*
* cookie_init()
* Curl_cookie_init()
*
* Inits a cookie struct to read data from a local file. This is always
* called before any cookies are set. File may be NULL.
*
****************************************************************************/
struct CookieInfo *Curl_cookie_init(char *file)
struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
{
char line[MAX_COOKIE_LINE];
struct CookieInfo *c;
FILE *fp;
bool fromfile=TRUE;
c = (struct CookieInfo *)malloc(sizeof(struct CookieInfo));
if(!c)
return NULL; /* failed to get memory */
memset(c, 0, sizeof(struct CookieInfo));
c->filename = strdup(file?file:"none"); /* copy the name just in case */
if(NULL == inc) {
/* we didn't get a struct, create one */
c = (struct CookieInfo *)malloc(sizeof(struct CookieInfo));
if(!c)
return NULL; /* failed to get memory */
memset(c, 0, sizeof(struct CookieInfo));
c->filename = strdup(file?file:"none"); /* copy the name just in case */
}
else {
/* we got an already existing one, use that */
c = inc;
}
c->running = FALSE; /* this is not running, this is init */
if(strequal(file, "-")) {
fp = stdin;
@@ -393,34 +426,35 @@ struct CookieInfo *Curl_cookie_init(char *file)
fp = file?fopen(file, "r"):NULL;
if(fp) {
char *lineptr;
bool headerline;
while(fgets(line, MAX_COOKIE_LINE, fp)) {
if(strnequal("Set-Cookie:", line, 11)) {
/* This is a cookie line, get it! */
char *lineptr=&line[11];
while(*lineptr && isspace((int)*lineptr))
lineptr++;
Curl_cookie_add(c, TRUE, lineptr);
lineptr=&line[11];
headerline=TRUE;
}
else {
/* This might be a netscape cookie-file line, get it! */
char *lineptr=line;
while(*lineptr && isspace((int)*lineptr))
lineptr++;
Curl_cookie_add(c, FALSE, lineptr);
lineptr=line;
headerline=FALSE;
}
while(*lineptr && isspace((int)*lineptr))
lineptr++;
Curl_cookie_add(c, headerline, lineptr);
}
if(fromfile)
fclose(fp);
}
c->running = TRUE; /* now, we're running */
return c;
}
/*****************************************************************************
*
* cookie_getlist()
* Curl_cookie_getlist()
*
* For a given host and path, return a linked list of cookies that the
* client should send to the server if used now. The secure boolean informs
@@ -492,9 +526,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/*****************************************************************************
*
* cookie_freelist()
* Curl_cookie_freelist()
*
* Free a list previously returned by cookie_getlist();
* Free a list of cookies previously returned by Curl_cookie_getlist();
*
****************************************************************************/
@@ -513,7 +547,7 @@ void Curl_cookie_freelist(struct Cookie *co)
/*****************************************************************************
*
* cookie_cleanup()
* Curl_cookie_cleanup()
*
* Free a "cookie object" previous created with cookie_init().
*
@@ -552,3 +586,101 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
}
}
/*
* Curl_cookie_output()
*
* Writes all internally known cookies to the specified file. Specify
* "-" as file name to write to stdout.
*
* The function returns non-zero on write failure.
*/
int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
{
struct Cookie *co;
FILE *out;
bool use_stdout=FALSE;
if((NULL == c) || (0 == c->numcookies))
/* If there are no known cookies, we don't write or even create any
destination file */
return 0;
if(strequal("-", dumphere)) {
/* use stdout */
out = stdout;
use_stdout=TRUE;
}
else {
out = fopen(dumphere, "w");
if(!out)
return 1; /* failure */
}
if(c) {
fputs("# Netscape HTTP Cookie File\n"
"# http://www.netscape.com/newsref/std/cookie_spec.html\n"
"# This is generated by libcurl! Edit on your own risk.\n\n",
out);
co = c->cookies;
while(co) {
fprintf(out,
"%s\t" /* domain */
"%s\t" /* field1 */
"%s\t" /* path */
"%s\t" /* secure */
"%u\t" /* expires */
"%s\t" /* name */
"%s\n", /* value */
co->domain,
co->field1==2?"TRUE":"FALSE",
co->path,
co->secure?"TRUE":"FALSE",
(unsigned int)co->expires,
co->name,
co->value);
co=co->next;
}
}
if(!use_stdout)
fclose(out);
return 0;
}
#ifdef CURL_COOKIE_DEBUG
/*
* On my Solaris box, this command line builds this test program:
*
* gcc -g -o cooktest -DCURL_COOKIE_DEBUG -DHAVE_CONFIG_H -I.. -I../include cookie.c strequal.o getdate.o memdebug.o mprintf.o strtok.o -lnsl -lsocket
*
*/
int main(int argc, char **argv)
{
struct CookieInfo *c=NULL;
if(argc>1) {
c = Curl_cookie_init(argv[1], c);
Curl_cookie_add(c, TRUE, "PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/ftgw; secure");
Curl_cookie_add(c, TRUE, "foobar=yes; domain=.haxx.se; path=/looser;");
c = Curl_cookie_init(argv[1], c);
Curl_cookie_output(c);
Curl_cookie_cleanup(c);
return 0;
}
return 1;
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -40,19 +40,24 @@ struct Cookie {
char *domain; /* domain = <this> */
time_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
char field1; /* read from a cookie file, 1 => FALSE, 2=> TRUE */
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
char *version; /* Version = <value> */
char *maxage; /* Max-Age = <value> */
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
};
struct CookieInfo {
/* linked list of cookies we know of */
struct Cookie *cookies;
/* linked list of cookies we know of */
struct Cookie *cookies;
char *filename; /* file we read from/write to */
char *filename; /* file we read from/write to */
bool running; /* state info, for cookie adding information */
long numcookies; /* number of cookies in the "jar" */
};
/* This is the maximum line length we accept for a cookie line */
@@ -64,9 +69,10 @@ struct CookieInfo {
#define MAX_NAME_TXT "255"
struct Cookie *Curl_cookie_add(struct CookieInfo *, bool, char *);
struct CookieInfo *Curl_cookie_init(char *);
struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *);
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
void Curl_cookie_freelist(struct Cookie *);
void Curl_cookie_cleanup(struct CookieInfo *);
int Curl_cookie_output(struct CookieInfo *, char *);
#endif

View File

@@ -43,7 +43,8 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# 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 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 CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -53,7 +54,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
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 LINK32 kernel32.lib wsock32.lib /nologo /dll /machine:I386 /out:"Release/curl.dll"
# ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"
!ELSEIF "$(CFG)" == "curllib - Win32 Debug"
@@ -69,7 +70,8 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# 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 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 CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
# SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -79,7 +81,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
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 LINK32 kernel32.lib wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/curl.dll" /pdbtype:sept
# ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept
# SUBTRACT LINK32 /nodefaultlib
!ENDIF

View File

@@ -90,7 +90,7 @@ CURLcode Curl_dict(struct connectdata *conn)
char *nthdef = NULL; /* This is not part of the protocol, but required
by RFC 2229 */
CURLcode result=CURLE_OK;
struct UrlData *data=conn->data;
struct SessionHandle *data=conn->data;
char *path = conn->path;
long *bytecount = &conn->bytecount;
@@ -232,3 +232,11 @@ CURLcode Curl_dict(struct connectdata *conn)
return CURLE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -82,3 +82,11 @@ DllMain (
return TRUE;
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -94,7 +94,7 @@ static CURLcode win32_init(void)
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup(wVersionRequested, &wsaData);
@@ -103,14 +103,14 @@ static CURLcode win32_init(void)
/* winsock.dll. */
return CURLE_FAILED_INIT;
/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Confirm that the Windows Sockets DLL supports 2.0.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* than 2.0 in addition to 2.0, it will still return */
/* 2.0 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
@@ -175,7 +175,7 @@ void curl_global_cleanup(void)
CURL *curl_easy_init(void)
{
CURLcode res;
struct UrlData *data;
struct SessionHandle *data;
/* Make sure we inited the global SSL stuff */
if (!initialized)
@@ -186,9 +186,6 @@ CURL *curl_easy_init(void)
if(res != CURLE_OK)
return NULL;
/* SAC */
data->device = NULL;
return data;
}
@@ -199,7 +196,7 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
func_T param_func = (func_T)0;
long param_long = 0;
void *param_obj = NULL;
struct UrlData *data = curl;
struct SessionHandle *data = curl;
va_start(arg, tag);
@@ -231,14 +228,14 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
CURLcode curl_easy_perform(CURL *curl)
{
struct UrlData *data = (struct UrlData *)curl;
struct SessionHandle *data = (struct SessionHandle *)curl;
return Curl_perform(data);
}
void curl_easy_cleanup(CURL *curl)
{
struct UrlData *data = (struct UrlData *)curl;
struct SessionHandle *data = (struct SessionHandle *)curl;
Curl_close(data);
}
@@ -246,10 +243,77 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
va_list arg;
void *paramp;
struct UrlData *data = (struct UrlData *)curl;
struct SessionHandle *data = (struct SessionHandle *)curl;
va_start(arg, info);
paramp = va_arg(arg, void *);
return Curl_getinfo(data, info, paramp);
}
CURL *curl_easy_duphandle(CURL *incurl)
{
struct SessionHandle *data=(struct SessionHandle *)incurl;
struct SessionHandle *outcurl = (struct SessionHandle *)
malloc(sizeof(struct SessionHandle));
if(NULL == outcurl)
return NULL; /* failure */
/* start with clearing the entire new struct */
memset(outcurl, 0, sizeof(struct SessionHandle));
/*
* We setup a few buffers we need. We should probably make them
* get setup on-demand in the code, as that would probably decrease
* the likeliness of us forgetting to init a buffer here in the future.
*/
outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
if(!outcurl->state.headerbuff) {
free(outcurl); /* free the memory again */
return NULL;
}
outcurl->state.headersize=HEADERSIZE;
/* copy all userdefined values */
outcurl->set = data->set;
outcurl->state.numconnects = data->state.numconnects;
outcurl->state.connects = (struct connectdata **)
malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
if(!outcurl->state.connects) {
free(outcurl->state.headerbuff);
free(outcurl);
return NULL;
}
memset(outcurl->state.connects, 0,
sizeof(struct connectdata *)*outcurl->state.numconnects);
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
/* duplicate all values in 'change' */
if(data->change.url) {
outcurl->change.url = strdup(data->change.url);
outcurl->change.url_alloc = TRUE;
}
if(data->change.proxy) {
outcurl->change.proxy = strdup(data->change.proxy);
outcurl->change.proxy_alloc = TRUE;
}
if(data->change.referer) {
outcurl->change.referer = strdup(data->change.referer);
outcurl->change.referer_alloc = TRUE;
}
return outcurl;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -37,7 +37,7 @@
#include "memdebug.h"
#endif
char *curl_escape(char *string, int length)
char *curl_escape(const char *string, int length)
{
int alloc = (length?length:(int)strlen(string))+1;
char *ns = malloc(alloc);
@@ -75,7 +75,7 @@ char *curl_escape(char *string, int length)
return ns;
}
char *curl_unescape(char *string, int length)
char *curl_unescape(const char *string, int length)
{
int alloc = (length?length:(int)strlen(string))+1;
char *ns = malloc(alloc);
@@ -110,3 +110,11 @@ char *curl_unescape(char *string, int length)
return ns;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -26,7 +26,7 @@
/* 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);
char *curl_escape(const char *string, int length);
char *curl_unescape(const char *string, int length);
#endif

View File

@@ -142,8 +142,8 @@ CURLcode Curl_file(struct connectdata *conn)
struct stat statbuf;
ssize_t expected_size=-1;
ssize_t nread;
struct UrlData *data = conn->data;
char *buf = data->buffer;
struct SessionHandle *data = conn->data;
char *buf = data->state.buffer;
int bytecount = 0;
struct timeval start = Curl_tvnow();
struct timeval now = start;
@@ -196,3 +196,11 @@ CURLcode Curl_file(struct connectdata *conn)
return res;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
@@ -24,7 +24,65 @@
/*
Debug the form generator stand-alone by compiling this source file with:
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
run the 'formdata' executable the output should end with:
All Tests seem to have worked ...
and the following parts should be there:
Content-Disposition: form-data; name="simple_COPYCONTENTS"
value for simple COPYCONTENTS
Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE"
Content-Type: image/gif
value for COPYCONTENTS + CONTENTTYPE
Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"
vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH
(or you might see P^@RNAME and v^@lue at the start)
Content-Disposition: form-data; name="simple_PTRCONTENTS"
value for simple PTRCONTENTS
Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH"
vlue for PTRCONTENTS + CONTENTSLENGTH
(or you might see v^@lue at the start)
Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"
Content-Type: text/plain
vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE
(or you might see v^@lue at the start)
Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h"
Content-Type: text/html
...
Content-Disposition: form-data; name="FILE1_+_FILE2"
Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Type: text/plain
...
Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3"
Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
For the old FormParse used by curl_formparse use:
gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
run the 'formdata' executable and make sure the output is ok!
@@ -64,7 +122,7 @@
/* This is a silly duplicate of the function in main.c to enable this source
to compile stand-alone for better debugging */
static void GetStr(char **string,
char *value)
const char *value)
{
if(*string)
free(*string);
@@ -227,6 +285,7 @@ int FormParse(char *input,
memset(post, 0, sizeof(struct HttpPost));
GetStr(&post->name, name); /* get the name */
GetStr(&post->contents, contp); /* get the contents */
post->contentslength = 0;
post->flags = flags;
if(type) {
GetStr(&post->contenttype, (char *)type); /* get type */
@@ -250,6 +309,7 @@ int FormParse(char *input,
memset(subpost, 0, sizeof(struct HttpPost));
GetStr(&subpost->name, name); /* get the name */
GetStr(&subpost->contents, contp); /* get the contents */
subpost->contentslength = 0;
subpost->flags = flags;
if(type) {
GetStr(&subpost->contenttype, (char *)type); /* get type */
@@ -272,10 +332,12 @@ int FormParse(char *input,
GetStr(&post->name, name); /* get the name */
if( contp[0]=='<' ) {
GetStr(&post->contents, contp+1); /* get the contents */
post->contentslength = 0;
post->flags = HTTPPOST_READFILE;
}
else {
GetStr(&post->contents, contp); /* get the contents */
post->contentslength = 0;
post->flags = 0;
}
@@ -307,6 +369,428 @@ int curl_formparse(char *input,
return FormParse(input, httppost, last_post);
}
/***************************************************************************
*
* AddHttpPost()
*
* Adds a HttpPost structure to the list, if parent_post is given becomes
* a subpost of parent_post instead of a direct list element.
*
* Returns newly allocated HttpPost on success and NULL if malloc failed.
*
***************************************************************************/
static struct HttpPost * AddHttpPost (char * name,
long namelength,
char * value,
long contentslength,
char *contenttype,
long flags,
struct HttpPost *parent_post,
struct HttpPost **httppost,
struct HttpPost **last_post)
{
struct HttpPost *post;
post = (struct HttpPost *)malloc(sizeof(struct HttpPost));
if(post) {
memset(post, 0, sizeof(struct HttpPost));
post->name = name;
post->namelength = namelength;
post->contents = value;
post->contentslength = contentslength;
post->contenttype = contenttype;
post->flags = flags;
}
else
return NULL;
if (parent_post) {
/* now, point our 'more' to the original 'more' */
post->more = parent_post->more;
/* then move the original 'more' to point to ourselves */
parent_post->more = post;
}
else {
/* make the previous point to this */
if(*last_post)
(*last_post)->next = post;
else
(*httppost) = post;
(*last_post) = post;
}
return post;
}
/***************************************************************************
*
* AddFormInfo()
*
* Adds a FormInfo structure to the list presented by parent_form_info.
*
* Returns newly allocated FormInfo on success and NULL if malloc failed/
* parent_form_info is NULL.
*
***************************************************************************/
static FormInfo * AddFormInfo (char *value,
char *contenttype,
FormInfo *parent_form_info)
{
FormInfo *form_info;
form_info = (FormInfo *)malloc(sizeof(FormInfo));
if(form_info) {
memset(form_info, 0, sizeof(FormInfo));
if (value)
form_info->value = value;
if (contenttype)
form_info->contenttype = contenttype;
form_info->flags = HTTPPOST_FILENAME;
}
else
return NULL;
if (parent_form_info) {
/* now, point our 'more' to the original 'more' */
form_info->more = parent_form_info->more;
/* then move the original 'more' to point to ourselves */
parent_form_info->more = form_info;
}
else
return NULL;
return form_info;
}
/***************************************************************************
*
* ContentTypeForFilename()
*
* Provides content type for filename if one of the known types (else
* (either the prevtype or the default is returned).
*
* Returns some valid contenttype for filename.
*
***************************************************************************/
static const char * ContentTypeForFilename (char *filename,
const char *prevtype)
{
const char *contenttype = NULL;
unsigned int i;
/*
* No type was specified, we scan through a few well-known
* extensions and pick the first we match!
*/
struct ContentType {
const char *extension;
const char *type;
};
static struct ContentType ctts[]={
{".gif", "image/gif"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".txt", "text/plain"},
{".html", "text/plain"}
};
if(prevtype)
/* default to the previously set/used! */
contenttype = prevtype;
else
/* It seems RFC1867 defines no Content-Type to default to
text/plain so we don't actually need to set this: */
contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
if(strlen(filename) >= strlen(ctts[i].extension)) {
if(strequal(filename +
strlen(filename) - strlen(ctts[i].extension),
ctts[i].extension)) {
contenttype = ctts[i].type;
break;
}
}
}
/* we have a contenttype by now */
return contenttype;
}
/***************************************************************************
*
* AllocAndCopy()
*
* Copies the data currently available under *buffer using newly allocated
* buffer (that becomes *buffer). Uses buffer_length if not null, else
* uses strlen to determine the length of the buffer to be copied
*
* Returns 0 on success and 1 if the malloc failed.
*
***************************************************************************/
static int AllocAndCopy (char **buffer, int buffer_length)
{
char *src = *buffer;
int length;
if (buffer_length)
length = buffer_length;
else
length = strlen(*buffer);
*buffer = (char*)malloc(length);
if (!*buffer)
return 1;
memcpy(*buffer, src, length);
return 0;
}
/***************************************************************************
*
* FormAdd()
*
* Stores a 'name=value' formpost parameter and builds the appropriate
* linked list.
*
* Has two principal functionalities: using files and byte arrays as
* post parts. Byte arrays are either copied or just the pointer is stored
* (as the user requests) while for files only the filename and not the
* content is stored.
*
* While you may have only one byte array for each name, multiple filenames
* are allowed (and because of this feature CURLFORM_END is needed after
* using CURLFORM_FILE).
*
* Examples:
*
* Simple name/value pair with copied contents:
* curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
* CURLFORM_COPYCONTENTS, "value");
*
* name/value pair where only the content pointer is remembered:
* curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
* CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10);
* (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
*
* storing a filename (CONTENTTYPE is optional!):
* curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
* CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
* CURLFORM_END);
*
* storing multiple filenames:
* curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
* CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
*
* Returns 0 on success, 1 if the FormInfo allocation fails, 2 if one
* option is given twice for one Form, 3 if a null pointer was given for
* a char *, 4 if the allocation of a FormInfo struct failed, 5 if an
* unknown option was used, 6 if the some FormInfo is not complete (or
* has an error), 7 if a HttpPost struct cannot be allocated, and 8
* if some allocation for string copying failed.
*
***************************************************************************/
static
int FormAdd(struct HttpPost **httppost,
struct HttpPost **last_post,
va_list params)
{
FormInfo *first_form_info, *current_form_info, *form_info;
int return_value = 0;
const char *prevtype = NULL;
struct HttpPost *post = NULL;
CURLformoption next_option;
first_form_info = (FormInfo *)malloc(sizeof(struct FormInfo));
if(first_form_info) {
memset(first_form_info, 0, sizeof(FormInfo));
current_form_info = first_form_info;
}
else
return 1;
/** TODO: first check whether char * is not NULL
TODO: transfer.c
*/
while ( ((next_option = va_arg(params, CURLformoption)) != CURLFORM_END) &&
(return_value == 0) )
{
switch (next_option)
{
case CURLFORM_PTRNAME:
current_form_info->flags |= HTTPPOST_PTRNAME; /* fall through */
case CURLFORM_COPYNAME:
if (current_form_info->name)
return_value = 2;
else {
if (next_option == CURLFORM_PTRNAME)
current_form_info->name = va_arg(params, char *);
else {
char *name = va_arg(params, char *);
if (name)
current_form_info->name = name; /* store for the moment */
else
return_value = 3;
}
}
break;
case CURLFORM_NAMELENGTH:
if (current_form_info->namelength)
return_value = 2;
else
current_form_info->namelength = va_arg(params, long);
break;
case CURLFORM_PTRCONTENTS:
current_form_info->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
case CURLFORM_COPYCONTENTS:
if (current_form_info->value)
return_value = 2;
else {
if (next_option == CURLFORM_PTRCONTENTS)
current_form_info->value = va_arg(params, char *);
else {
char *value = va_arg(params, char *);
if (value)
current_form_info->value = value; /* store for the moment */
else
return_value = 3;
}
}
break;
case CURLFORM_CONTENTSLENGTH:
if (current_form_info->contentslength)
return_value = 2;
else
current_form_info->contentslength = va_arg(params, long);
break;
case CURLFORM_FILE: {
char *filename = va_arg(params, char *);
if (current_form_info->value) {
if (current_form_info->flags & HTTPPOST_FILENAME) {
if (filename) {
if (!(current_form_info = AddFormInfo (strdup(filename),
NULL, current_form_info)))
return_value = 4;
}
else
return_value = 3;
}
else
return_value = 2;
}
else {
if (filename)
current_form_info->value = strdup(filename);
else
return_value = 3;
current_form_info->flags |= HTTPPOST_FILENAME;
}
break;
}
case CURLFORM_CONTENTTYPE: {
char *contenttype = va_arg(params, char *);
if (current_form_info->contenttype) {
if (current_form_info->flags & HTTPPOST_FILENAME) {
if (contenttype) {
if (!(current_form_info = AddFormInfo (NULL,
strdup(contenttype),
current_form_info)))
return_value = 4;
}
else
return_value = 3;
}
else
return_value = 2;
}
else {
if (contenttype)
current_form_info->contenttype = strdup(contenttype);
else
return_value = 3;
}
break;
}
default:
fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", next_option);
return_value = 5;
};
};
/* go through the list, check for copleteness and if everything is
* alright add the HttpPost item otherwise set return_value accordingly */
form_info = first_form_info;
while (form_info != NULL)
{
if ( (!first_form_info->name) ||
(!form_info->value) ||
( (!form_info->namelength) &&
(form_info->flags & HTTPPOST_PTRNAME) ) ||
( (form_info->contentslength) &&
(form_info->flags & HTTPPOST_FILENAME) ) ||
( (form_info->flags & HTTPPOST_FILENAME) &&
(form_info->flags & HTTPPOST_PTRCONTENTS) )
) {
return_value = 6;
break;
}
else {
if ( (form_info->flags & HTTPPOST_FILENAME) &&
(!form_info->contenttype) ) {
/* our contenttype is missing */
form_info->contenttype
= strdup(ContentTypeForFilename(form_info->value, prevtype));
}
if ( !(form_info->flags & HTTPPOST_PTRNAME) &&
(form_info == first_form_info) ) {
/* copy name (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form_info->name, form_info->namelength)) {
return_value = 8;
break;
}
}
if ( !(form_info->flags & HTTPPOST_FILENAME) &&
!(form_info->flags & HTTPPOST_PTRCONTENTS) ) {
/* copy value (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form_info->value, form_info->contentslength)) {
return_value = 8;
break;
}
}
if ( (post = AddHttpPost (form_info->name, form_info->namelength,
form_info->value, form_info->contentslength,
form_info->contenttype, form_info->flags,
post, httppost,
last_post)) == NULL) {
return_value = 7;
}
if (form_info->contenttype)
prevtype = form_info->contenttype;
}
form_info = form_info->more;
};
/* and finally delete the allocated memory */
form_info = first_form_info;
while (form_info != NULL) {
FormInfo *delete_form_info;
delete_form_info = form_info;
form_info = form_info->more;
free (delete_form_info);
};
return return_value;
}
int curl_formadd(struct HttpPost **httppost,
struct HttpPost **last_post,
...)
{
va_list arg;
int result;
va_start(arg, last_post);
result = FormAdd(httppost, last_post, arg);
va_end(arg);
return result;
}
static int AddFormData(struct FormData **formp,
const void *line,
long length)
@@ -404,9 +888,9 @@ void curl_formfree(struct HttpPost *form)
if(form->more)
curl_formfree(form->more);
if(form->name)
if( !(form->flags & HTTPPOST_PTRNAME) && form->name)
free(form->name); /* free the name */
if(form->contents)
if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents)
free(form->contents); /* free the contents */
if(form->contenttype)
free(form->contenttype); /* free the content type */
@@ -446,9 +930,12 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
/* boundary */
size += AddFormDataf(&form, "\r\n--%s\r\n", boundary);
size += AddFormDataf(&form,
"Content-Disposition: form-data; name=\"%s\"",
post->name);
size += AddFormData(&form,
"Content-Disposition: form-data; name=\"", 0);
size += AddFormData(&form, post->name, post->namelength);
size += AddFormData(&form, "\"", 0);
if(post->more) {
/* If used, this is a link to more file names, we must then do
@@ -525,7 +1012,7 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
}
} else {
/* include the contents we got */
size += AddFormData(&form, post->contents, 0);
size += AddFormData(&form, post->contents, post->contentslength);
}
} while((file = file->more)); /* for each specified file for this field */
@@ -568,6 +1055,52 @@ int Curl_FormReader(char *buffer,
size_t size,
size_t nitems,
FILE *mydata)
{
struct Form *form;
int wantedsize;
int gotsize = 0;
form=(struct Form *)mydata;
wantedsize = size * nitems;
if(!form->data)
return -1; /* nothing, error, empty */
do {
if( (form->data->length - form->sent ) > wantedsize - gotsize) {
memcpy(buffer + gotsize , form->data->line + form->sent,
wantedsize - gotsize);
form->sent += wantedsize-gotsize;
return wantedsize;
}
memcpy(buffer+gotsize,
form->data->line + form->sent,
(form->data->length - form->sent) );
gotsize += form->data->length - form->sent;
form->sent = 0;
form->data = form->data->next; /* advance */
} while(form->data);
/* If we got an empty line and we have more data, we proceed to the next
line immediately to avoid returning zero before we've reached the end.
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
return gotsize;
}
/* possible (old) fread() emulation that copies at most one line */
int Curl_FormReadOneLine(char *buffer,
size_t size,
size_t nitems,
FILE *mydata)
{
struct Form *form;
int wantedsize;
@@ -609,6 +1142,134 @@ int Curl_FormReader(char *buffer,
#ifdef _FORM_DEBUG
int FormAddTest(const char * errormsg,
struct HttpPost **httppost,
struct HttpPost **last_post,
...)
{
int result;
va_list arg;
va_start(arg, last_post);
if ((result = FormAdd(httppost, last_post, arg)))
fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result,
errormsg);
va_end(arg);
return result;
}
int main()
{
char name1[] = "simple_COPYCONTENTS";
char name2[] = "COPYCONTENTS_+_CONTENTTYPE";
char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH";
char name4[] = "simple_PTRCONTENTS";
char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH";
char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE";
char name7[] = "FILE1_+_CONTENTTYPE";
char name8[] = "FILE1_+_FILE2";
char name9[] = "FILE1_+_FILE2_+_FILE3";
char value1[] = "value for simple COPYCONTENTS";
char value2[] = "value for COPYCONTENTS + CONTENTTYPE";
char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH";
char value4[] = "value for simple PTRCONTENTS";
char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
char value7[] = "inet_ntoa_r.h";
char value8[] = "Makefile.b32.resp";
char type2[] = "image/gif";
char type6[] = "text/plain";
char type7[] = "text/html";
int name3length = strlen(name3);
int value3length = strlen(value3);
int value5length = strlen(value4);
int value6length = strlen(value5);
int errors = 0;
int size;
int nread;
char buffer[4096];
struct HttpPost *httppost=NULL;
struct HttpPost *last_post=NULL;
struct FormData *form;
struct Form formread;
if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post,
CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1,
CURLFORM_END))
++errors;
if (FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post,
CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2,
CURLFORM_CONTENTTYPE, type2, CURLFORM_END))
++errors;
/* make null character at start to check that contentslength works
correctly */
name3[1] = '\0';
value3[1] = '\0';
if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test",
&httppost, &last_post,
CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3,
CURLFORM_CONTENTSLENGTH, value3length,
CURLFORM_NAMELENGTH, name3length, CURLFORM_END))
++errors;
if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post,
CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4,
CURLFORM_END))
++errors;
/* make null character at start to check that contentslength works
correctly */
value5[1] = '\0';
if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post,
CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5,
CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END))
++errors;
/* make null character at start to check that contentslength works
correctly */
value6[1] = '\0';
if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test",
&httppost, &last_post,
CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6,
CURLFORM_CONTENTSLENGTH, value6length,
CURLFORM_CONTENTTYPE, type6, CURLFORM_END))
++errors;
if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post,
CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7,
CURLFORM_CONTENTTYPE, type7, CURLFORM_END))
++errors;
if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post,
CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7,
CURLFORM_FILE, value8, CURLFORM_END))
++errors;
if (FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post,
CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7,
CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END))
++errors;
form=Curl_getFormData(httppost, &size);
Curl_FormInit(&formread, form);
do {
nread = Curl_FormReader(buffer, 1, sizeof(buffer),
(FILE *)&formread);
if(-1 == nread)
break;
fwrite(buffer, nread, 1, stderr);
} while(1);
fprintf(stderr, "size: %d\n", size);
if (errors)
fprintf(stderr, "\n==> %d Test(s) failed!\n", errors);
else
fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n");
return 0;
}
#endif
#ifdef _OLD_FORM_DEBUG
int main(int argc, char **argv)
{
@@ -661,3 +1322,11 @@ int main(int argc, char **argv)
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -36,6 +36,17 @@ struct Form {
been sent in a previous invoke */
};
/* used by FormAdd for temporary storage */
typedef struct FormInfo {
char *name;
long namelength;
char *value;
long contentslength;
char *contenttype;
long flags;
struct FormInfo *more;
} FormInfo;
int Curl_FormInit(struct Form *form, struct FormData *formdata );
struct FormData *Curl_getFormData(struct HttpPost *post,
@@ -47,8 +58,15 @@ int Curl_FormReader(char *buffer,
size_t nitems,
FILE *mydata);
/* possible (old) fread() emulation that copies at most one line */
int Curl_FormReadOneLine(char *buffer,
size_t size,
size_t nitems,
FILE *mydata);
char *Curl_FormBoundary(void);
void Curl_formclean(struct FormData *);
#endif

665
lib/ftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -1524,9 +1524,11 @@ yyerrhandle:
the same signature as the function definition does. */
#include "getdate.h"
#ifndef WIN32 /* the windows dudes don't need these, does anyone really? */
extern struct tm *gmtime ();
extern struct tm *localtime ();
extern time_t mktime ();
#endif
/* Month and day table. */
static TABLE const MonthDayTable[] = {
@@ -2124,3 +2126,11 @@ main (ac, av)
/* NOTREACHED */
}
#endif /* defined (TEST) */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -477,9 +477,11 @@ o_merid : /* NULL */
the same signature as the function definition does. */
#include "getdate.h"
#ifndef WIN32 /* the windows dudes don't need these, does anyone really? */
extern struct tm *gmtime ();
extern struct tm *localtime ();
extern time_t mktime ();
#endif
/* Month and day table. */
static TABLE const MonthDayTable[] = {

View File

@@ -66,3 +66,11 @@ char *curl_getenv(const char *v)
{
return GetEnv(v);
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -35,22 +35,23 @@
* This is supposed to be called in the beginning of a permform() session
* and should reset all session-info variables
*/
CURLcode Curl_initinfo(struct UrlData *data)
CURLcode Curl_initinfo(struct SessionHandle *data)
{
struct Progress *pro = &data->progress;
struct PureInfo *info =&data->info;
pro->t_nslookup = 0;
pro->t_connect = 0;
pro->t_pretransfer = 0;
pro->httpcode = 0;
pro->httpversion=0;
pro->filetime=0;
info->httpcode = 0;
info->httpversion=0;
info->filetime=0;
return CURLE_OK;
}
CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...)
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
{
va_list arg;
long *param_longp;
@@ -80,19 +81,19 @@ CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...)
switch(info) {
case CURLINFO_EFFECTIVE_URL:
*param_charp = data->url?data->url:(char *)"";
*param_charp = data->change.url?data->change.url:(char *)"";
break;
case CURLINFO_HTTP_CODE:
*param_longp = data->progress.httpcode;
*param_longp = data->info.httpcode;
break;
case CURLINFO_FILETIME:
*param_longp = data->progress.filetime;
*param_longp = data->info.filetime;
break;
case CURLINFO_HEADER_SIZE:
*param_longp = data->header_size;
*param_longp = data->info.header_size;
break;
case CURLINFO_REQUEST_SIZE:
*param_longp = data->request_size;
*param_longp = data->info.request_size;
break;
case CURLINFO_TOTAL_TIME:
*param_doublep = data->progress.timespent;
@@ -119,7 +120,7 @@ CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...)
*param_doublep = data->progress.ulspeed;
break;
case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->ssl.certverifyresult;
*param_longp = data->set.ssl.certverifyresult;
break;
case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
*param_doublep = data->progress.size_dl;
@@ -132,3 +133,11 @@ CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...)
}
return CURLE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -22,7 +22,7 @@
*
* $Id$
*****************************************************************************/
CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...);
CURLcode Curl_initinfo(struct UrlData *data);
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
CURLcode Curl_initinfo(struct SessionHandle *data);
#endif

View File

@@ -244,3 +244,11 @@ char *getpass(const char *prompt)
return getpass_r(prompt, buf, sizeof(buf));
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -89,7 +89,7 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
}
#ifdef ENABLE_IPV6
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port)
{
@@ -119,7 +119,7 @@ struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
#define INADDR_NONE (unsigned long) ~0
#endif
struct hostent *Curl_gethost(struct UrlData *data,
struct hostent *Curl_gethost(struct SessionHandle *data,
char *hostname,
char **bufp)
{
@@ -215,3 +215,11 @@ struct hostent *Curl_gethost(struct UrlData *data,
}
return (h);
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -24,11 +24,11 @@
*****************************************************************************/
struct addrinfo;
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port);
struct hostent *Curl_gethost(struct UrlData *data,
struct hostent *Curl_gethost(struct SessionHandle *data,
char *hostname,
char **bufp);

View File

@@ -128,10 +128,10 @@ static
size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
{
size_t amount;
if(conn->data->bits.verbose) {
fputs("> ", conn->data->err);
if(conn->data->set.verbose) {
fputs("> ", conn->data->set.err);
/* this data _may_ contain binary stuff */
fwrite(in->buffer, in->size_used, 1, conn->data->err);
fwrite(in->buffer, in->size_used, 1, conn->data->set.err);
}
Curl_write(conn, sockfd, in->buffer, in->size_used, &amount);
@@ -204,31 +204,18 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
*/
static
int GetLine(int sockfd, char *buf, struct connectdata *conn)
int GetLine(int sockfd, char *ptr, struct connectdata *conn)
{
ssize_t nread;
int read_rc=1;
char *ptr;
struct UrlData *data=conn->data;
ptr=buf;
/* get us a full line, terminated with a newline */
for(nread=0;
(nread<BUFSIZE) && read_rc;
nread++, ptr++) {
for(nread=0; (nread<BUFSIZE); nread++, ptr++) {
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
(nread <= 0) ||
(*ptr == '\n'))
(nread <= 0) || (*ptr == '\n'))
break;
}
*ptr=0; /* zero terminate */
if(data->bits.verbose) {
fputs("< ", data->err);
fwrite(buf, 1, nread, data->err);
fputs("\n", data->err);
}
return nread>0?nread:0;
}
@@ -238,12 +225,12 @@ int GetLine(int sockfd, char *buf, struct connectdata *conn)
* This function checks the linked list of custom HTTP headers for a particular
* header (prefix).
*/
static bool checkheaders(struct UrlData *data, const char *thisheader)
static bool checkheaders(struct SessionHandle *data, const char *thisheader)
{
struct curl_slist *head;
size_t thislen = strlen(thisheader);
for(head = data->headers; head; head=head->next) {
for(head = data->set.headers; head; head=head->next) {
if(strnequal(head->data, thisheader, thislen)) {
return TRUE;
}
@@ -263,7 +250,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
{
int httperror=0;
int subversion=0;
struct UrlData *data=conn->data;
struct SessionHandle *data=conn->data;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
@@ -275,14 +262,17 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
"\r\n",
hostname, remote_port,
(conn->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"",
(data->useragent?conn->allocptr.uagent:"")
(data->set.useragent?conn->allocptr.uagent:"")
);
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
while(GetLine(tunnelsocket, data->buffer, conn)) {
if('\r' == data->buffer[0])
while(GetLine(tunnelsocket, data->state.buffer, conn)) {
if('\r' == data->state.buffer[0])
break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
if(data->set.verbose)
fprintf(data->set.err, "< %s\n", data->state.buffer);
if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d",
&subversion,
&httperror)) {
;
@@ -306,7 +296,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
*/
CURLcode Curl_http_connect(struct connectdata *conn)
{
struct UrlData *data;
struct SessionHandle *data;
CURLcode result;
data=conn->data;
@@ -318,7 +308,7 @@ CURLcode Curl_http_connect(struct connectdata *conn)
* has occured, can we start talking SSL
*/
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
if (data->change.proxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
conn->hostname, conn->remote_port);
@@ -332,42 +322,33 @@ CURLcode Curl_http_connect(struct connectdata *conn)
return result;
}
if(conn->bits.user_passwd && !data->bits.this_is_a_follow) {
if(conn->bits.user_passwd && !data->state.this_is_a_follow) {
/* Authorization: is requested, this is not a followed location, get the
original host name */
data->auth_host = strdup(conn->hostname);
data->state.auth_host = strdup(conn->hostname);
}
return CURLE_OK;
}
/* called from curl_close() when this struct is about to get wasted, free
protocol-specific resources */
CURLcode Curl_http_close(struct connectdata *conn)
{
if(conn->data->auth_host)
free(conn->data->auth_host);
return CURLE_OK;
}
CURLcode Curl_http_done(struct connectdata *conn)
{
struct UrlData *data;
struct SessionHandle *data;
long *bytecount = &conn->bytecount;
struct HTTP *http;
data=conn->data;
http=conn->proto.http;
if(HTTPREQ_POST_FORM == data->httpreq) {
if(HTTPREQ_POST_FORM == data->set.httpreq) {
*bytecount = http->readbytecount + http->writebytecount;
Curl_formclean(http->sendit); /* Now free that whole lot */
data->fread = http->storefread; /* restore */
data->in = http->in; /* restore */
data->set.fread = http->storefread; /* restore */
data->set.in = http->in; /* restore */
}
else if(HTTPREQ_PUT == data->httpreq) {
else if(HTTPREQ_PUT == data->set.httpreq) {
*bytecount = http->readbytecount + http->writebytecount;
}
@@ -377,8 +358,8 @@ CURLcode Curl_http_done(struct connectdata *conn)
CURLcode Curl_http(struct connectdata *conn)
{
struct UrlData *data=conn->data;
char *buf = data->buffer; /* this is a short cut to the buffer */
struct SessionHandle *data=conn->data;
char *buf = data->state.buffer; /* this is a short cut to the buffer */
CURLcode result=CURLE_OK;
struct HTTP *http;
struct Cookie *co=NULL; /* no cookies from start */
@@ -402,8 +383,8 @@ CURLcode Curl_http(struct connectdata *conn)
conn->bits.close = FALSE;
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
data->bits.upload) {
data->httpreq = HTTPREQ_PUT;
data->set.upload) {
data->set.httpreq = HTTPREQ_PUT;
}
/* The User-Agent string has been built in url.c already, because it might
@@ -420,45 +401,45 @@ CURLcode Curl_http(struct connectdata *conn)
/* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */
if(!data->bits.this_is_a_follow ||
!data->auth_host ||
strequal(data->auth_host, conn->hostname)) {
sprintf(data->buffer, "%s:%s", data->user, data->passwd);
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
if(!data->state.this_is_a_follow ||
!data->state.auth_host ||
strequal(data->state.auth_host, conn->hostname)) {
sprintf(data->state.buffer, "%s:%s",
data->state.user, data->state.passwd);
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
&authorization) >= 0) {
if(conn->allocptr.userpwd)
free(conn->allocptr.userpwd);
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
authorization);
authorization);
free(authorization);
}
}
}
if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
if((data->change.referer) && !checkheaders(data, "Referer:")) {
if(conn->allocptr.ref)
free(conn->allocptr.ref);
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->referer);
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
}
if(data->cookie && !checkheaders(data, "Cookie:")) {
if(data->set.cookie && !checkheaders(data, "Cookie:")) {
if(conn->allocptr.cookie)
free(conn->allocptr.cookie);
conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->cookie);
conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie);
}
if(data->cookies) {
co = Curl_cookie_getlist(data->cookies,
host,
ppath,
host, ppath,
conn->protocol&PROT_HTTPS?TRUE:FALSE);
}
if ((data->bits.httpproxy) && !(conn->protocol&PROT_HTTPS)) {
if ((data->change.proxy) && !(conn->protocol&PROT_HTTPS)) {
/* The path sent to the proxy is in fact the entire URL */
ppath = data->url;
ppath = data->change.url;
}
if(HTTPREQ_POST_FORM == data->httpreq) {
if(HTTPREQ_POST_FORM == data->set.httpreq) {
/* we must build the whole darned post sequence first, so that we have
a size of the whole shebang before we start to send it */
http->sendit = Curl_getFormData(data->httppost, &http->postsize);
http->sendit = Curl_getFormData(data->set.httppost, &http->postsize);
}
if(!checkheaders(data, "Host:")) {
@@ -486,9 +467,9 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
if(( (HTTPREQ_POST == data->httpreq) ||
(HTTPREQ_POST_FORM == data->httpreq) ||
(HTTPREQ_PUT == data->httpreq) ) &&
if(( (HTTPREQ_POST == data->set.httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq) ||
(HTTPREQ_PUT == data->set.httpreq) ) &&
conn->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
@@ -521,7 +502,8 @@ CURLcode Curl_http(struct connectdata *conn)
readthisamountnow = BUFSIZE;
actuallyread =
data->fread(data->buffer, 1, readthisamountnow, data->in);
data->set.fread(data->state.buffer, 1, readthisamountnow,
data->set.in);
passed += actuallyread;
if(actuallyread != readthisamountnow) {
@@ -532,10 +514,10 @@ CURLcode Curl_http(struct connectdata *conn)
} while(passed != conn->resume_from); /* loop until done */
/* now, decrease the size of the read */
if(data->infilesize>0) {
data->infilesize -= conn->resume_from;
if(data->set.infilesize>0) {
data->set.infilesize -= conn->resume_from;
if(data->infilesize <= 0) {
if(data->set.infilesize <= 0) {
failf(data, "File already completely uploaded\n");
return CURLE_PARTIAL_FILE;
}
@@ -549,16 +531,16 @@ CURLcode Curl_http(struct connectdata *conn)
* or uploading and we always let customized headers override our internal
* ones if any such are specified.
*/
if((data->httpreq == HTTPREQ_GET) &&
if((data->set.httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) {
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
}
else if((data->httpreq != HTTPREQ_GET) &&
else if((data->set.httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) {
if(conn->resume_from) {
/* This is because "resume" was selected */
long total_expected_size= conn->resume_from + data->infilesize;
long total_expected_size= conn->resume_from + data->set.infilesize;
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
conn->range, total_expected_size-1,
total_expected_size);
@@ -567,14 +549,14 @@ CURLcode Curl_http(struct connectdata *conn)
/* Range was selected and then we just pass the incoming range and
append total size */
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
conn->range, data->infilesize);
conn->range, data->set.infilesize);
}
}
}
do {
send_buffer *req_buffer;
struct curl_slist *headers=data->headers;
struct curl_slist *headers=data->set.headers;
/* initialize a dynamic send-buffer */
req_buffer = add_buffer_init();
@@ -593,11 +575,11 @@ CURLcode Curl_http(struct connectdata *conn)
"%s" /* accept */
"%s", /* referer */
data->customrequest?data->customrequest:
(data->bits.no_body?"HEAD":
((HTTPREQ_POST == data->httpreq) ||
(HTTPREQ_POST_FORM == data->httpreq))?"POST":
(HTTPREQ_PUT == data->httpreq)?"PUT":"GET"),
data->set.customrequest?data->set.customrequest:
(data->set.no_body?"HEAD":
((HTTPREQ_POST == data->set.httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq))?"POST":
(HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"),
ppath,
(conn->bits.proxy_user_passwd &&
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
@@ -605,13 +587,13 @@ CURLcode Curl_http(struct connectdata *conn)
conn->allocptr.userpwd:"",
(conn->bits.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"",
(data->useragent && *data->useragent && conn->allocptr.uagent)?
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
conn->allocptr.uagent:"",
(conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
http->p_pragma?http->p_pragma:"",
http->p_accept?http->p_accept:"",
(data->bits.http_set_referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
);
if(co) {
@@ -636,7 +618,7 @@ CURLcode Curl_http(struct connectdata *conn)
co=NULL;
}
if(data->timecondition) {
if(data->set.timecondition) {
struct tm *thistime;
/* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since
@@ -651,9 +633,9 @@ CURLcode Curl_http(struct connectdata *conn)
/* 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;
thistime = (struct tm *)gmtime_r(&data->timevalue, &keeptime);
thistime = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
#else
thistime = gmtime(&data->timevalue);
thistime = gmtime(&data->set.timevalue);
#endif
if(NULL == thistime) {
failf(data, "localtime() failed!");
@@ -667,7 +649,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* TODO: Right, we *could* write a replacement here */
strcpy(buf, "no strftime() support");
#endif
switch(data->timecondition) {
switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE:
default:
add_bufferf(req_buffer,
@@ -702,53 +684,80 @@ CURLcode Curl_http(struct connectdata *conn)
headers = headers->next;
}
if(HTTPREQ_POST_FORM == data->httpreq) {
if(HTTPREQ_POST_FORM == data->set.httpreq) {
char contentType[256];
int linelength=0;
if(Curl_FormInit(&http->form, http->sendit)) {
failf(data, "Internal HTTP POST error!\n");
return CURLE_HTTP_POST_ERROR;
}
http->storefread = data->fread; /* backup */
http->in = data->in; /* backup */
http->storefread = data->set.fread; /* backup */
http->in = data->set.in; /* backup */
data->fread = (curl_read_callback)
data->set.fread = (curl_read_callback)
Curl_FormReader; /* set the read function to read from the
generated form data */
data->in = (FILE *)&http->form;
data->set.in = (FILE *)&http->form;
add_bufferf(req_buffer,
"Content-Length: %d\r\n", http->postsize-2);
if(!checkheaders(data, "Expect:")) {
/* if not disabled explicitly we add a Expect: 100-continue
to the headers which actually speeds up post operations (as
there is one packet coming back from the web server) */
add_bufferf(req_buffer,
"Expect: 100-continue\r\n");
data->set.expect100header = TRUE;
/* Get Content-Type: line from Curl_FormReadOneLine, which happens
to always be the first line. We can know this for sure since
we always build the formpost linked list the same way! */
linelength = Curl_FormReadOneLine (contentType,
sizeof(contentType),
1,
(FILE *)&http->form);
if(linelength == -1) {
failf(data, "Could not get Content-Type header line!\n");
return CURLE_HTTP_POST_ERROR;
}
add_buffer(req_buffer, contentType, linelength);
}
/* set upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
data->request_size =
/* fire away the whole request to the server */
data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount,
conn->firstsocket,
&http->writebytecount);
&http->readbytecount,
conn->firstsocket,
&http->writebytecount);
if(result) {
Curl_formclean(http->sendit); /* free that whole lot */
return result;
}
}
else if(HTTPREQ_PUT == data->httpreq) {
else if(HTTPREQ_PUT == data->set.httpreq) {
/* Let's PUT the data to the server! */
if(data->infilesize>0) {
if(data->set.infilesize>0) {
add_bufferf(req_buffer,
"Content-Length: %d\r\n\r\n", /* file size */
data->infilesize );
data->set.infilesize );
}
else
add_bufferf(req_buffer, "\015\012");
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, data->infilesize);
Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* this sends the buffer and frees all the buffer resources */
data->request_size =
data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* prepare for transfer */
@@ -761,17 +770,17 @@ CURLcode Curl_http(struct connectdata *conn)
}
else {
if(HTTPREQ_POST == data->httpreq) {
if(HTTPREQ_POST == data->set.httpreq) {
/* this is the simple POST, using x-www-form-urlencoded style */
if(!data->postfields) {
if(!data->set.postfields) {
/*
* This is an attempt to do a POST without having anything to
* actually send. Let's make a NULL pointer equal "" here. Good/bad
* ?
*/
data->postfields = (char *)"";
data->postfieldsize = 0; /* it might been set to something illegal,
data->set.postfields = (char *)"";
data->set.postfieldsize = 0; /* it might been set to something illegal,
anything > 0 would be! */
}
@@ -780,32 +789,32 @@ CURLcode Curl_http(struct connectdata *conn)
actually set your own */
add_bufferf(req_buffer,
"Content-Length: %d\r\n",
(data->postfieldsize?data->postfieldsize:
strlen(data->postfields)) );
(data->set.postfieldsize?data->set.postfieldsize:
strlen(data->set.postfields)) );
if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n");
/* and here comes the actual data */
if(data->postfieldsize) {
if(data->set.postfieldsize) {
add_buffer(req_buffer, "\r\n", 2);
add_buffer(req_buffer, data->postfields,
data->postfieldsize);
add_buffer(req_buffer, data->set.postfields,
data->set.postfieldsize);
add_buffer(req_buffer, "\r\n", 2);
}
else {
add_bufferf(req_buffer,
"\r\n"
"%s\r\n",
data->postfields );
data->set.postfields );
}
}
else
add_buffer(req_buffer, "\r\n", 2);
/* issue the request */
data->request_size =
data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* HTTP GET/HEAD download: */
@@ -820,3 +829,11 @@ CURLcode Curl_http(struct connectdata *conn)
return CURLE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -33,7 +33,6 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
CURLcode Curl_http(struct connectdata *conn);
CURLcode Curl_http_done(struct connectdata *conn);
CURLcode Curl_http_connect(struct connectdata *conn);
CURLcode Curl_http_close(struct connectdata *conn);
/* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn);

View File

@@ -44,7 +44,7 @@
* Chunk format (simplified):
*
* <HEX SIZE>[ chunk extension ] CRLF
* <DATA>
* <DATA> CRLF
*
* Highlights from RFC2616 section 3.6 say:
@@ -220,3 +220,11 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
return CHUNKE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -124,3 +124,11 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
#else
#define if2ip(x) NULL
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -248,17 +248,17 @@ krb4_auth(void *app_data, struct connectdata *conn)
Curl_ftpsendf(conn->firstsocket, conn, "ADAT %s", p);
nread = Curl_GetFTPResponse(conn->firstsocket,
conn->data->buffer, conn, NULL);
conn->data->state.buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
free(p);
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){
printf("Server didn't accept auth data.\n");
return AUTH_ERROR;
}
p = strstr(conn->data->buffer, "ADAT=");
p = strstr(conn->data->state.buffer, "ADAT=");
if(!p){
printf("Remote host didn't send adat reply.\n");
return AUTH_ERROR;
@@ -314,20 +314,20 @@ void Curl_krb_kauth(struct connectdata *conn)
save = Curl_set_command_prot(conn, prot_private);
Curl_ftpsendf(conn->firstsocket, conn,
"SITE KAUTH %s", conn->data->user);
"SITE KAUTH %s", conn->data->state.user);
nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer,
nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->state.buffer,
conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
if(/*ret != CONTINUE*/conn->data->state.buffer[0] != '3'){
Curl_set_command_prot(conn, save);
/*code = -1;***/
return;
}
p = strstr(conn->data->buffer, "T=");
p = strstr(conn->data->state.buffer, "T=");
if(!p) {
printf("Bad reply from server.\n");
Curl_set_command_prot(conn, save);
@@ -344,7 +344,7 @@ void Curl_krb_kauth(struct connectdata *conn)
tkt.length = tmp;
tktcopy.length = tkt.length;
p = strstr(conn->data->buffer, "P=");
p = strstr(conn->data->state.buffer, "P=");
if(!p) {
printf("Bad reply from server.\n");
Curl_set_command_prot(conn, save);
@@ -354,7 +354,7 @@ void Curl_krb_kauth(struct connectdata *conn)
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
*p = 0;
des_string_to_key (conn->data->passwd, &key);
des_string_to_key (conn->data->state.passwd, &key);
des_key_sched(&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
@@ -383,7 +383,7 @@ void Curl_krb_kauth(struct connectdata *conn)
Curl_ftpsendf(conn->firstsocket, conn,
"SITE KAUTH %s %s", name, p);
nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer,
nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->state.buffer,
conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
@@ -392,3 +392,11 @@ void Curl_krb_kauth(struct connectdata *conn)
}
#endif /* KRB4 */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -116,7 +116,7 @@ static void * DynaGetFunction(const char *name)
static int WriteProc(void *param, char *text, int len)
{
struct UrlData *data = (struct UrlData *)param;
struct SessionHandle *data = (struct SessionHandle *)param;
len = 0; /* prevent compiler warning */
Curl_client_write(data, CLIENTWRITE_BODY, text, 0);
return 0;
@@ -142,9 +142,9 @@ CURLcode Curl_ldap(struct connectdata *conn)
void *entryIterator;
int ldaptext;
struct UrlData *data=conn->data;
struct SessionHandle *data=conn->data;
infof(data, "LDAP: %s %s\n", data->url);
infof(data, "LDAP: %s %s\n", data->change.url);
DynaOpen();
if (libldap == NULL) {
@@ -152,7 +152,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
return CURLE_LIBRARY_NOT_FOUND;
}
ldaptext = data->bits.ftp_ascii; /* This is a dirty hack */
ldaptext = data->set.ftp_ascii; /* This is a dirty hack */
/* The types are needed because ANSI C distinguishes between
* pointer-to-object (data) and pointer-to-function.
@@ -173,12 +173,12 @@ CURLcode Curl_ldap(struct connectdata *conn)
conn->hostname, conn->port);
status = CURLE_COULDNT_CONNECT;
} else {
rc = ldap_simple_bind_s(server, data->user, data->passwd);
rc = ldap_simple_bind_s(server, data->state.user, data->state.passwd);
if (rc != 0) {
failf(data, "LDAP: %s", ldap_err2string(rc));
status = CURLE_LDAP_CANNOT_BIND;
} else {
rc = ldap_url_search_s(server, data->url, 0, &result);
rc = ldap_url_search_s(server, data->change.url, 0, &result);
if (rc != 0) {
failf(data, "LDAP: %s", ldap_err2string(rc));
status = CURLE_LDAP_SEARCH_FAILED;
@@ -213,3 +213,11 @@ CURLcode Curl_ldap(struct connectdata *conn)
return status;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -31,4 +31,5 @@ EXPORTS
curl_mvfprintf @ 22 ;
curl_strequal @ 23 ;
curl_strnequal @ 24 ;
curl_easy_duphandle @ 25 ;

View File

@@ -156,3 +156,11 @@ int curl_fclose(FILE *file, int line, const char *source)
}
#endif /* MALLOCDEBUG */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -1151,7 +1151,9 @@ int curl_msprintf(char *buffer, const char *format, ...)
return retcode;
}
#ifndef WIN32 /* not needed on win32 */
extern int fputc(int, FILE *);
#endif
int curl_mprintf(const char *format, ...)
{
@@ -1230,3 +1232,11 @@ int main()
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -201,3 +201,11 @@ int main(int argc, char **argv)
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -93,17 +93,17 @@ static char *max5data(double bytes, char *max5)
void Curl_pgrsDone(struct connectdata *conn)
{
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
if(!(data->progress.flags & PGRS_HIDE)) {
data->progress.lastshow=0;
Curl_pgrsUpdate(conn); /* the final (forced) update */
if(!data->progress.callback)
/* only output if we don't use progress callback */
fprintf(data->err, "\n");
fprintf(data->set.err, "\n");
}
}
void Curl_pgrsTime(struct UrlData *data, timerid timer)
void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
{
switch(timer) {
default:
@@ -135,23 +135,23 @@ void Curl_pgrsTime(struct UrlData *data, timerid timer)
}
}
void Curl_pgrsStartNow(struct UrlData *data)
void Curl_pgrsStartNow(struct SessionHandle *data)
{
data->progress.speeder_c = 0; /* reset the progress meter display */
data->progress.start = Curl_tvnow();
}
void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size)
void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size)
{
data->progress.downloaded = size;
}
void Curl_pgrsSetUploadCounter(struct UrlData *data, double size)
void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size)
{
data->progress.uploaded = size;
}
void Curl_pgrsSetDownloadSize(struct UrlData *data, double size)
void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size)
{
if(size > 0) {
data->progress.size_dl = size;
@@ -159,7 +159,7 @@ void Curl_pgrsSetDownloadSize(struct UrlData *data, double size)
}
}
void Curl_pgrsSetUploadSize(struct UrlData *data, double size)
void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size)
{
if(size > 0) {
data->progress.size_ul = size;
@@ -188,7 +188,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
double total_transfer;
double total_expected_transfer;
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
@@ -211,9 +211,9 @@ int Curl_pgrsUpdate(struct connectdata *conn)
else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if (!data->progress.callback) {
if(conn->resume_from)
fprintf(data->err, "** Resuming transfer from byte position %d\n",
fprintf(data->set.err, "** Resuming transfer from byte position %d\n",
conn->resume_from);
fprintf(data->err,
fprintf(data->set.err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n");
}
@@ -254,12 +254,12 @@ int Curl_pgrsUpdate(struct connectdata *conn)
if(data->progress.flags & PGRS_HIDE)
return 0;
else if(data->fprogress) {
result= data->fprogress(data->progress_client,
data->progress.size_dl,
data->progress.downloaded,
data->progress.size_ul,
data->progress.uploaded);
else if(data->set.fprogress) {
result= data->set.fprogress(data->set.progress_client,
data->progress.size_dl,
data->progress.downloaded,
data->progress.size_ul,
data->progress.uploaded);
if(result)
failf(data, "Callback aborted");
return result;
@@ -310,7 +310,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
if(total_expected_transfer)
total_percen=(double)(total_transfer/total_expected_transfer)*100;
fprintf(data->err,
fprintf(data->set.err,
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
(int)total_percen, /* total % */
max5data(total_expected_transfer, max5[2]), /* total size */
@@ -327,5 +327,16 @@ int Curl_pgrsUpdate(struct connectdata *conn)
max5data(data->progress.current_speed, max5[5]) /* current speed */
);
/* we flush the output stream to make it appear as soon as possible */
fflush(data->set.err);
return 0;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -37,13 +37,13 @@ typedef enum {
} timerid;
void Curl_pgrsDone(struct connectdata *);
void Curl_pgrsStartNow(struct UrlData *data);
void Curl_pgrsSetDownloadSize(struct UrlData *data, double size);
void Curl_pgrsSetUploadSize(struct UrlData *data, double size);
void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size);
void Curl_pgrsSetUploadCounter(struct UrlData *data, double size);
void Curl_pgrsStartNow(struct SessionHandle *data);
void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size);
void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size);
void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size);
void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size);
int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsTime(struct UrlData *data, timerid timer);
void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
/* Don't show progress for sizes smaller than: */

View File

@@ -417,15 +417,15 @@ sec_prot_internal(struct connectdata *conn, int level)
"PBSZ %u", s);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
conn->data->buffer, conn, NULL);
conn->data->state.buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){
failf(conn->data, "Failed to set protection buffer size.\n");
return -1;
}
conn->buffer_size = s;
p = strstr(/*reply_string*/conn->data->buffer, "PBSZ=");
p = strstr(/*reply_string*/conn->data->state.buffer, "PBSZ=");
if(p)
sscanf(p, "PBSZ=%u", &s);
if(s < conn->buffer_size)
@@ -436,10 +436,10 @@ sec_prot_internal(struct connectdata *conn, int level)
"PROT %c", level["CSEP"]);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
conn->data->buffer, conn, NULL);
conn->data->state.buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){
failf(conn->data, "Failed to set protection level.\n");
return -1;
}
@@ -472,7 +472,7 @@ Curl_sec_login(struct connectdata *conn)
int ret;
struct Curl_sec_client_mech **m;
ssize_t nread;
struct UrlData *data=conn->data;
struct SessionHandle *data=conn->data;
for(m = mechs; *m && (*m)->name; m++) {
void *tmp;
@@ -494,18 +494,18 @@ Curl_sec_login(struct connectdata *conn)
"AUTH %s", (*m)->name);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
conn->data->buffer, conn, NULL);
conn->data->state.buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
if(/*code == 504*/strncmp(conn->data->buffer,"504",3) == 0) {
if(/*ret != CONTINUE*/conn->data->state.buffer[0] != '3'){
if(/*code == 504*/strncmp(conn->data->state.buffer,"504",3) == 0) {
infof(data,
"%s is not supported by the server.\n", (*m)->name);
}
else if(/*code == 534*/strncmp(conn->data->buffer,"534",3) == 0) {
else if(/*code == 534*/strncmp(conn->data->state.buffer,"534",3) == 0) {
infof(data, "%s rejected as security mechanism.\n", (*m)->name);
}
else if(/*ret == ERROR*/conn->data->buffer[0] == '5') {
else if(/*ret == ERROR*/conn->data->state.buffer[0] == '5') {
infof(data, "The server doesn't support the FTP "
"security extensions.\n");
return -1;
@@ -546,3 +546,11 @@ Curl_sec_end(struct connectdata *conn)
}
#endif /* KRB4 */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -122,13 +122,13 @@ void curl_slist_free_all(struct curl_slist *list)
/* Curl_infof() is for info message along the way */
void Curl_infof(struct UrlData *data, const char *fmt, ...)
void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
{
va_list ap;
if(data->bits.verbose) {
if(data->set.verbose) {
va_start(ap, fmt);
fputs("* ", data->err);
vfprintf(data->err, fmt, ap);
fputs("* ", data->set.err);
vfprintf(data->set.err, fmt, ap);
va_end(ap);
}
}
@@ -136,12 +136,12 @@ void Curl_infof(struct UrlData *data, const char *fmt, ...)
/* Curl_failf() is for messages stating why we failed, the LAST one will be
returned for the user (if requested) */
void Curl_failf(struct UrlData *data, const char *fmt, ...)
void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if(data->errorbuffer)
vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap);
if(data->set.errorbuffer)
vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
va_end(ap);
}
@@ -149,7 +149,7 @@ void Curl_failf(struct UrlData *data, const char *fmt, ...)
size_t Curl_sendf(int sockfd, struct connectdata *conn,
const char *fmt, ...)
{
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
size_t bytes_written;
char *s;
va_list ap;
@@ -158,8 +158,8 @@ size_t Curl_sendf(int sockfd, struct connectdata *conn,
va_end(ap);
if(!s)
return 0; /* failure */
if(data->bits.verbose)
fprintf(data->err, "> %s", s);
if(data->set.verbose)
fprintf(data->set.err, "> %s", s);
/* Write the buffer to the socket */
Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
@@ -219,7 +219,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
The bit pattern defines to what "streams" to write to. Body and/or header.
The defines are in sendf.h of course.
*/
CURLcode Curl_client_write(struct UrlData *data,
CURLcode Curl_client_write(struct SessionHandle *data,
int type,
char *ptr,
size_t len)
@@ -230,22 +230,22 @@ CURLcode Curl_client_write(struct UrlData *data,
len = strlen(ptr);
if(type & CLIENTWRITE_BODY) {
wrote = data->fwrite(ptr, 1, len, data->out);
wrote = data->set.fwrite(ptr, 1, len, data->set.out);
if(wrote != len) {
failf (data, "Failed writing body");
return CURLE_WRITE_ERROR;
}
}
if((type & CLIENTWRITE_HEADER) &&
(data->fwrite_header || data->writeheader) ) {
(data->set.fwrite_header || data->set.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;
data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
wrote = writeit(ptr, 1, len, data->writeheader);
wrote = writeit(ptr, 1, len, data->set.writeheader);
if(wrote != len) {
failf (data, "Failed writing header");
return CURLE_WRITE_ERROR;
@@ -291,3 +291,11 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd,
return CURLE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -24,8 +24,8 @@
*****************************************************************************/
size_t Curl_sendf(int fd, struct connectdata *, const char *fmt, ...);
void Curl_infof(struct UrlData *, const char *fmt, ...);
void Curl_failf(struct UrlData *, const char *fmt, ...);
void Curl_infof(struct SessionHandle *, const char *fmt, ...);
void Curl_failf(struct SessionHandle *, const char *fmt, ...);
#define infof Curl_infof
#define failf Curl_failf
@@ -41,7 +41,7 @@ typedef struct send_buffer send_buffer;
#define CLIENTWRITE_HEADER 2
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr,
size_t len);
/* internal read-function, does plain socket, SSL and krb4 */

View File

@@ -96,24 +96,6 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#endif
#endif
#if 0 /* zlib experiments are halted 17th october, 1999 (Daniel) */
#if defined(HAVE_ZLIB_H) && defined(HAVE_LIBZ)
/* Both lib and header file exist, we have libz! */
#define USE_ZLIB
#endif
#endif
#if 0
#ifdef HAVE_STRCASECMP
#define strnequal(x,y,z) !(strncasecmp)(x,y,z)
#define strequal(x,y) !(strcasecmp)(x,y)
#else
#define strnequal(x,y,z) !strnicmp(x,y,z)
#define strequal(x,y) !stricmp(x,y)
#endif
#endif
/* Below we define four functions. They should
1. close a socket
2. read from a socket

View File

@@ -34,37 +34,44 @@
#include "sendf.h"
#include "speedcheck.h"
void Curl_speedinit(struct UrlData *data)
void Curl_speedinit(struct SessionHandle *data)
{
memset(&data->keeps_speed, 0, sizeof(struct timeval));
memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
}
CURLcode Curl_speedcheck(struct UrlData *data,
CURLcode Curl_speedcheck(struct SessionHandle *data,
struct timeval now)
{
if((data->progress.current_speed >= 0) &&
data->low_speed_time &&
(Curl_tvlong(data->keeps_speed) != 0) &&
(data->progress.current_speed < data->low_speed_limit)) {
data->set.low_speed_time &&
(Curl_tvlong(data->state.keeps_speed) != 0) &&
(data->progress.current_speed < data->set.low_speed_limit)) {
/* We are now below the "low speed limit". If we are below it
for "low speed time" seconds we consider that enough reason
to abort the download. */
if( Curl_tvdiff(now, data->keeps_speed) > data->low_speed_time) {
if( Curl_tvdiff(now, data->state.keeps_speed) > data->set.low_speed_time) {
/* we have been this slow for long enough, now die */
failf(data,
"Operation too slow. "
"Less than %d bytes/sec transfered the last %d seconds",
data->low_speed_limit,
data->low_speed_time);
data->set.low_speed_limit,
data->set.low_speed_time);
return CURLE_OPERATION_TIMEOUTED;
}
}
else {
/* we keep up the required speed all right */
data->keeps_speed = now;
data->state.keeps_speed = now;
}
return CURLE_OK;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -27,8 +27,8 @@
#include "timeval.h"
void Curl_speedinit(struct UrlData *data);
CURLcode Curl_speedcheck(struct UrlData *data,
void Curl_speedinit(struct SessionHandle *data);
CURLcode Curl_speedcheck(struct SessionHandle *data,
struct timeval now);
#endif

View File

@@ -94,9 +94,9 @@ bool seed_enough(struct connectdata *conn, /* unused for now */
static
int random_the_seed(struct connectdata *conn)
{
char *buf = conn->data->buffer; /* point to the big buffer */
char *buf = conn->data->state.buffer; /* point to the big buffer */
int nread=0;
struct UrlData *data=conn->data;
struct SessionHandle *data=conn->data;
/* Q: should we add support for a random file name as a libcurl option?
A: Yes, it is here */
@@ -104,13 +104,13 @@ int random_the_seed(struct connectdata *conn)
#ifndef RANDOM_FILE
/* if RANDOM_FILE isn't defined, we only perform this if an option tells
us to! */
if(data->ssl.random_file)
if(data->set.ssl.random_file)
#define RANDOM_FILE "" /* doesn't matter won't be used */
#endif
{
/* let the option override the define */
nread += RAND_load_file((data->ssl.random_file?
data->ssl.random_file:RANDOM_FILE),
nread += RAND_load_file((data->set.ssl.random_file?
data->set.ssl.random_file:RANDOM_FILE),
16384);
if(seed_enough(conn, nread))
return nread;
@@ -122,13 +122,13 @@ int random_the_seed(struct connectdata *conn)
#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)
if(data->set.ssl.egdsocket)
#define EGD_SOCKET "" /* doesn't matter won't be used */
#endif
{
/* 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);
int ret = RAND_egd(data->set.ssl.egdsocket?data->set.ssl.egdsocket:EGD_SOCKET);
if(-1 != ret) {
nread += ret;
if(seed_enough(conn, nread))
@@ -176,23 +176,23 @@ int cert_stuff(struct connectdata *conn,
char *cert_file,
char *key_file)
{
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
if (cert_file != NULL) {
SSL *ssl;
X509 *x509;
if(data->cert_passwd) {
if(data->set.cert_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
/*
* If password has been given, we store that in the global
* area (*shudder*) for a while:
*/
strcpy(global_passwd, data->cert_passwd);
strcpy(global_passwd, data->set.cert_passwd);
#else
/*
* We set the password in the callback userdata
*/
SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->cert_passwd);
SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->set.cert_passwd);
#endif
/* Set passwd callback: */
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
@@ -200,7 +200,7 @@ int cert_stuff(struct connectdata *conn,
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
cert_file,
SSL_FILETYPE_PEM) <= 0) {
SSL_FILETYPE_PEM) != 1) {
failf(data, "unable to set certificate file (wrong password?)\n");
return(0);
}
@@ -209,7 +209,7 @@ int cert_stuff(struct connectdata *conn,
if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
key_file,
SSL_FILETYPE_PEM) <= 0) {
SSL_FILETYPE_PEM) != 1) {
failf(data, "unable to set public key file\n");
return(0);
}
@@ -263,7 +263,6 @@ static int init_ssl=0;
void Curl_SSL_init(void)
{
#ifdef USE_SSLEAY
/* make sure this is only done once */
if(0 != init_ssl)
return;
@@ -275,6 +274,8 @@ void Curl_SSL_init(void)
/* Setup all the global SSL stuff */
SSLeay_add_ssl_algorithms();
#else
/* SSL disabled, do nothing */
#endif
}
@@ -292,9 +293,233 @@ void Curl_SSL_cleanup(void)
table. */
EVP_cleanup();
}
#endif
#else
/* SSL disabled, do nothing */
#endif
}
#ifdef USE_SSLEAY
/*
* This function is called when an SSL connection is closed.
*/
void Curl_SSL_Close(struct connectdata *conn)
{
if (conn->ssl.use) {
/*
ERR_remove_state() frees the error queue associated with
thread pid. If pid == 0, the current thread will have its
error queue removed.
Since error queue data structures are allocated
automatically for new threads, they must be freed when
threads are terminated in oder to avoid memory leaks.
*/
ERR_remove_state(0);
if(conn->ssl.handle) {
(void)SSL_shutdown(conn->ssl.handle);
SSL_set_connect_state(conn->ssl.handle);
SSL_free (conn->ssl.handle);
conn->ssl.handle = NULL;
}
if(conn->ssl.ctx) {
SSL_CTX_free (conn->ssl.ctx);
conn->ssl.ctx = NULL;
}
conn->ssl.use = FALSE; /* get back to ordinary socket usage */
}
}
/*
* This sets up a session cache to the specified size.
*/
CURLcode Curl_SSL_InitSessions(struct SessionHandle *data, long amount)
{
struct curl_ssl_session *session;
if(data->state.session)
/* this is just a precaution to prevent multiple inits */
return CURLE_OK;
session = (struct curl_ssl_session *)
malloc(amount * sizeof(struct curl_ssl_session));
if(!session)
return CURLE_OUT_OF_MEMORY;
/* "blank out" the newly allocated memory */
memset(session, 0, amount * sizeof(struct curl_ssl_session));
/* store the info in the SSL section */
data->set.ssl.numsessions = amount;
data->state.session = session;
data->state.sessionage = 1; /* this is brand new */
return CURLE_OK;
}
/*
* Check if there's a session ID for the given connection in the cache,
* and if there's one suitable, it is returned.
*/
static int Get_SSL_Session(struct connectdata *conn,
SSL_SESSION **ssl_sessionid)
{
struct curl_ssl_session *check;
struct SessionHandle *data = conn->data;
long i;
for(i=0; i< data->set.ssl.numsessions; i++) {
check = &data->state.session[i];
if(!check->sessionid)
/* not session ID means blank entry */
continue;
if(strequal(conn->name, check->name) &&
(conn->remote_port == check->remote_port) ) {
/* yes, we have a session ID! */
data->state.sessionage++; /* increase general age */
check->age = data->state.sessionage; /* set this as used in this age */
*ssl_sessionid = check->sessionid;
return FALSE;
}
}
*ssl_sessionid = (SSL_SESSION *)NULL;
return TRUE;
}
/*
* Kill a single session ID entry in the cache.
*/
static int Kill_Single_Session(struct curl_ssl_session *session)
{
if(session->sessionid) {
/* defensive check */
/* free the ID */
SSL_SESSION_free(session->sessionid);
session->sessionid=NULL;
session->age = 0; /* fresh */
free(session->name);
session->name = NULL; /* no name */
return 0; /* ok */
}
else
return 1;
}
/*
* This function is called when the 'data' struct is going away. Close
* down everything and free all resources!
*/
int Curl_SSL_Close_All(struct SessionHandle *data)
{
int i;
if(data->state.session) {
for(i=0; i< data->set.ssl.numsessions; i++)
/* the single-killer function handles empty table slots */
Kill_Single_Session(&data->state.session[i]);
/* free the cache data */
free(data->state.session);
}
return 0;
}
/*
* Extract the session id and store it in the session cache.
*/
static int Store_SSL_Session(struct connectdata *conn)
{
SSL_SESSION *ssl_sessionid;
struct curl_ssl_session *store;
int i;
struct SessionHandle *data=conn->data; /* the mother of all structs */
int oldest_age=data->state.session[0].age; /* zero if unused */
/* ask OpenSSL, say please */
ssl_sessionid = SSL_get1_session(conn->ssl.handle);
/* SSL_get1_session() will increment the reference
count and the session will stay in memory until explicitly freed with
SSL_SESSION_free(3), regardless of its state. */
/* Now we should add the session ID and the host name to the cache, (remove
the oldest if necessary) */
/* find an empty slot for us, or find the oldest */
for(i=0; (i<data->set.ssl.numsessions) && data->state.session[i].sessionid; i++) {
if(data->state.session[i].age < oldest_age) {
oldest_age = data->state.session[i].age;
store = &data->state.session[i];
}
}
if(i == data->set.ssl.numsessions)
/* cache is full, we must "kill" the oldest entry! */
Kill_Single_Session(store);
else
store = &data->state.session[i]; /* use this slot */
/* now init the session struct wisely */
store->sessionid = ssl_sessionid;
store->age = data->state.sessionage; /* set current age */
store->name = strdup(conn->name); /* clone host name */
store->remote_port = conn->remote_port; /* port number */
return 0;
}
static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
const char *prefix,
ASN1_UTCTIME *tm)
{
char *asn1_string;
int gmt=FALSE;
int i;
int year=0,month=0,day=0,hour=0,minute=0,second=0;
struct SessionHandle *data = conn->data;
if(!data->set.verbose)
return 0;
i=tm->length;
asn1_string=(char *)tm->data;
if (i < 10)
return 1;
if (asn1_string[i-1] == 'Z')
gmt=TRUE;
for (i=0; i<10; i++)
if ((asn1_string[i] > '9') || (asn1_string[i] < '0'))
return 2;
year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
if (year < 50)
year+=100;
month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
if ((month > 12) || (month < 1))
return 3;
day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
if ( (asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
(asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
infof(data,
"%s%04d-%02d-%02d %02d:%02d:%02d %s\n",
prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
return 0;
}
#endif
/* ====================================================== */
CURLcode
@@ -303,10 +528,12 @@ Curl_SSLConnect(struct connectdata *conn)
CURLcode retcode = CURLE_OK;
#ifdef USE_SSLEAY
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
int err;
char * str;
SSL_METHOD *req_method;
SSL_SESSION *ssl_sessionid=NULL;
ASN1_TIME *certdate;
/* mark this is being ssl enabled from here on out. */
conn->ssl.use = TRUE;
@@ -314,7 +541,7 @@ Curl_SSLConnect(struct connectdata *conn)
/* Make funny stuff to get random input */
random_the_seed(conn);
switch(data->ssl.version) {
switch(data->set.ssl.version) {
default:
req_method = SSLv23_client_method();
break;
@@ -333,21 +560,29 @@ Curl_SSLConnect(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY;
}
if(data->cert) {
if (!cert_stuff(conn, data->cert, data->cert)) {
if(data->set.cert) {
if (!cert_stuff(conn, data->set.cert, data->set.cert)) {
/* failf() is already done in cert_stuff() */
return CURLE_SSL_CONNECT_ERROR;
}
}
if(data->ssl.verifypeer){
if(data->set.ssl.cipher_list) {
if (!SSL_CTX_set_cipher_list(conn->ssl.ctx,
data->set.ssl.cipher_list)) {
failf(data, "failed setting cipher list\n");
return CURLE_SSL_CONNECT_ERROR;
}
}
if(data->set.ssl.verifypeer){
SSL_CTX_set_verify(conn->ssl.ctx,
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
SSL_VERIFY_CLIENT_ONCE,
cert_verify_callback);
if (!SSL_CTX_load_verify_locations(conn->ssl.ctx,
data->ssl.CAfile,
data->ssl.CApath)) {
data->set.ssl.CAfile,
data->set.ssl.CApath)) {
failf(data,"error setting cerficate verify locations\n");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -362,11 +597,25 @@ Curl_SSLConnect(struct connectdata *conn)
conn->ssl.server_cert = 0x0;
if(!conn->bits.reuse) {
/* We're not re-using a connection, check if there's a cached ID we
can/should use here! */
if(!Get_SSL_Session(conn, &ssl_sessionid)) {
/* we got a session id, use it! */
SSL_set_session(conn->ssl.handle, ssl_sessionid);
/* Informational message */
infof (data, "SSL re-using session ID\n");
}
}
/* pass the raw socket into the SSL layers */
SSL_set_fd (conn->ssl.handle, conn->firstsocket);
err = SSL_connect (conn->ssl.handle);
if (-1 == err) {
/* 1 is fine
0 is "not successful but was shut down controlled"
<0 is "handshake was not successful, because a fatal error occurred" */
if (err <= 0) {
err = ERR_get_error();
failf(data, "SSL: %s", ERR_error_string(err, NULL));
return CURLE_SSL_CONNECT_ERROR;
@@ -375,6 +624,13 @@ Curl_SSLConnect(struct connectdata *conn)
/* Informational message */
infof (data, "SSL connection using %s\n",
SSL_get_cipher(conn->ssl.handle));
if(!ssl_sessionid) {
/* Since this is not a cached session ID, then we want to stach this one
in the cache! */
Store_SSL_Session(conn);
}
/* Get server's certificate (note: beware of dynamic allocation) - opt */
/* major serious hack alert -- we should check certificates
@@ -399,23 +655,35 @@ Curl_SSLConnect(struct connectdata *conn)
infof(data, "\t subject: %s\n", str);
CRYPTO_free(str);
if (data->ssl.verifyhost) {
certdate = X509_get_notBefore(conn->ssl.server_cert);
Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);
certdate = X509_get_notAfter(conn->ssl.server_cert);
Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);
if (data->set.ssl.verifyhost) {
char peer_CN[257];
if (X509_NAME_get_text_by_NID(X509_get_subject_name(conn->ssl.server_cert), NID_commonName, peer_CN, sizeof(peer_CN)) < 0) {
if (X509_NAME_get_text_by_NID(X509_get_subject_name(conn->ssl.server_cert),
NID_commonName,
peer_CN,
sizeof(peer_CN)) < 0) {
failf(data, "SSL: unable to obtain common name from peer certificate");
X509_free(conn->ssl.server_cert);
return CURLE_SSL_PEER_CERTIFICATE;
}
if (strcasecmp(peer_CN, conn->hostname) != 0) {
if (data->ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name '%s' does not match target host name '%s'",
peer_CN, conn->hostname);
if (!strequal(peer_CN, conn->hostname)) {
if (data->set.ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'",
peer_CN, conn->hostname);
X509_free(conn->ssl.server_cert);
return CURLE_SSL_PEER_CERTIFICATE;
}
else
infof(data, "\t common name: %s (does not match '%s')\n", peer_CN, conn->hostname);
infof(data,
"\t common name: %s (does not match '%s')\n",
peer_CN, conn->hostname);
}
else
infof(data, "\t common name: %s (matched)\n", peer_CN);
@@ -434,16 +702,16 @@ Curl_SSLConnect(struct connectdata *conn)
/* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */
if(data->ssl.verifypeer) {
data->ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
if (data->ssl.certverifyresult != X509_V_OK) {
if(data->set.ssl.verifypeer) {
data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
if (data->set.ssl.certverifyresult != X509_V_OK) {
failf(data, "SSL certificate verify result: %d\n",
data->ssl.certverifyresult);
data->set.ssl.certverifyresult);
retcode = CURLE_SSL_PEER_CERTIFICATE;
}
}
else
data->ssl.certverifyresult=0;
data->set.ssl.certverifyresult=0;
X509_free(conn->ssl.server_cert);
#else /* USE_SSLEAY */
@@ -452,3 +720,11 @@ Curl_SSLConnect(struct connectdata *conn)
#endif
return retcode;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -24,8 +24,15 @@
*****************************************************************************/
#include "urldata.h"
CURLcode Curl_SSLConnect(struct connectdata *conn);
/* Global SSL init */
void Curl_SSL_init(void);
/* Global SSL cleanup */
void Curl_SSL_cleanup(void);
void Curl_SSL_init(void); /* Global SSL init */
void Curl_SSL_cleanup(void); /* Global SSL cleanup */
/* init the SSL session ID cache */
CURLcode Curl_SSL_InitSessions(struct SessionHandle *, long);
void Curl_SSL_Close(struct connectdata *conn); /* close a SSL connection */
/* tell the SSL stuff to close down all open information regarding
connections (and thus session ID caching etc) */
int Curl_SSL_Close_All(struct SessionHandle *data);
#endif

View File

@@ -28,11 +28,11 @@
int curl_strequal(const char *first, const char *second)
{
#if defined(HAVE_STRCASECMP)
return !strcasecmp(first, second);
return !(strcasecmp)(first, second);
#elif defined(HAVE_STRCMPI)
return !strcmpi(first, second);
return !(strcmpi)(first, second);
#elif defined(HAVE_STRICMP)
return !stricmp(first, second);
return !(stricmp)(first, second);
#else
while (*first && *second) {
if (toupper(*first) != toupper(*second)) {
@@ -107,3 +107,11 @@ size_t Curl_strlcat(char *dst, const char *src, size_t siz)
return(dlen + (s - src)); /* count does not include NUL */
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
@@ -21,108 +21,54 @@
* $Id$
*****************************************************************************/
#include "setup.h"
#ifndef HAVE_STRTOK_R
/*
* Copyright (c) 1998 Softweyr LLC. All rights reserved.
*
* strtok_r, from Berkeley strtok
* Oct 13, 1998 by Wes Peters <wes@softweyr.com>
*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notices, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notices, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
*
* This product includes software developed by Softweyr LLC, the
* University of California, Berkeley, and its contributors.
*
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
* REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stddef.h>
#include <string.h>
char *
Curl_strtok_r(char *s, const char *delim, char **last)
Curl_strtok_r(char *ptr, const char *sep, char **end)
{
char *spanp;
int c, sc;
char *tok;
if (!ptr)
/* we got NULL input so then we get our last position instead */
ptr = *end;
if (s == NULL && (s = *last) == NULL) {
return NULL;
}
/* pass all letters that are including in the separator string */
while (*ptr && strchr(sep, *ptr))
++ptr;
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0; ) {
if (c == sc) {
goto cont;
if (*ptr) {
/* so this is where the next piece of string starts */
char *start = ptr;
/* set the end pointer to the first byte after the start */
*end = start + 1;
/* scan through the string to find where it ends, it ends on a
null byte or a character that exists in the separator string */
while (**end && !strchr(sep, **end))
++*end;
if (**end) {
/* the end is not a null byte */
**end = '\0'; /* zero terminate it! */
++*end; /* advance the last pointer to beyond the null byte */
}
return start; /* return the position where the string starts */
}
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
return NULL;
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0) {
s = NULL;
}
else {
char *w = s - 1;
*w = '\0';
}
*last = s;
return tok;
}
}
while (sc != 0);
}
/* NOTREACHED */
/* we ended up on a null byte, there are no more strings to find! */
return NULL;
}
#endif
#endif /* this was only compiled if strtok_r wasn't present */
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -35,7 +35,7 @@
#include <errno.h>
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <winsock2.h>
#include <time.h>
#include <io.h>
#else
@@ -105,7 +105,7 @@ void telrcv(struct connectdata *,
unsigned char *inbuf, /* Data received from socket */
int count); /* Number of bytes received */
static void printoption(struct UrlData *data,
static void printoption(struct SessionHandle *data,
const char *direction,
int cmd, int option);
@@ -114,7 +114,7 @@ static void send_negotiation(struct connectdata *, int cmd, int option);
static void set_local_option(struct connectdata *, int cmd, int option);
static void set_remote_option(struct connectdata *, int cmd, int option);
static void printsub(struct UrlData *data,
static void printsub(struct SessionHandle *data,
int direction, unsigned char *pointer, int length);
static void suboption(struct connectdata *);
@@ -152,8 +152,8 @@ struct TELNET {
int him[256];
int himq[256];
int him_preferred[256];
char *subopt_ttype; /* Set with suboption TTYPE */
char *subopt_xdisploc; /* Set with suboption XDISPLOC */
char subopt_ttype[32]; /* Set with suboption TTYPE */
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
struct curl_slist *telnet_vars; /* Environment variables */
/* suboptions */
@@ -215,13 +215,13 @@ static void negotiate(struct connectdata *conn)
}
}
static void printoption(struct UrlData *data,
static void printoption(struct SessionHandle *data,
const char *direction, int cmd, int option)
{
const char *fmt;
const char *opt;
if (data->bits.verbose)
if (data->set.verbose)
{
if (cmd == IAC)
{
@@ -627,14 +627,14 @@ void rec_dont(struct connectdata *conn, int option)
}
static void printsub(struct UrlData *data,
static void printsub(struct SessionHandle *data,
int direction, /* '<' or '>' */
unsigned char *pointer, /* where suboption data is */
int length) /* length of suboption data */
{
int i = 0;
if (data->bits.verbose)
if (data->set.verbose)
{
if (direction)
{
@@ -745,7 +745,7 @@ static int check_telnet_options(struct connectdata *conn)
char option_keyword[128];
char option_arg[256];
char *buf;
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
/* Add the user name as an environment variable if it
@@ -753,26 +753,28 @@ static int check_telnet_options(struct connectdata *conn)
if(conn->bits.user_passwd)
{
char *buf = malloc(256);
sprintf(buf, "USER,%s", data->user);
sprintf(buf, "USER,%s", data->state.user);
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
tn->us_preferred[TELOPT_NEW_ENVIRON] = YES;
}
for(head = data->telnet_options; head; head=head->next) {
for(head = data->set.telnet_options; head; head=head->next) {
if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
option_keyword, option_arg) == 2) {
/* Terminal type */
if(strequal(option_keyword, "TTYPE")) {
tn->subopt_ttype = option_arg;
strncpy(tn->subopt_ttype, option_arg, 31);
tn->subopt_ttype[31] = 0; /* String termination */
tn->us_preferred[TELOPT_TTYPE] = YES;
continue;
}
/* Display variable */
if(strequal(option_keyword, "XDISPLOC")) {
tn->subopt_xdisploc = option_arg;
strncpy(tn->subopt_xdisploc, option_arg, 127);
tn->subopt_xdisploc[127] = 0; /* String termination */
tn->us_preferred[TELOPT_XDISPLOC] = YES;
continue;
}
@@ -814,7 +816,7 @@ static void suboption(struct connectdata *conn)
int tmplen;
char varname[128];
char varval[128];
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
printsub(data, '<', (unsigned char *)tn->subbuffer, SB_LEN(tn)+2);
@@ -868,7 +870,7 @@ void telrcv(struct connectdata *conn,
{
unsigned char c;
int index = 0;
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
while(count--)
@@ -1031,13 +1033,20 @@ CURLcode Curl_telnet_done(struct connectdata *conn)
CURLcode Curl_telnet(struct connectdata *conn)
{
CURLcode code;
struct UrlData *data = conn->data;
struct SessionHandle *data = conn->data;
int sockfd = conn->firstsocket;
#ifdef WIN32
WSAEVENT event_handle;
WSANETWORKEVENTS events;
HANDLE stdin_handle;
HANDLE objs[2];
DWORD waitret;
#else
fd_set readfd;
fd_set keepfd;
#endif
bool keepon = TRUE;
char *buf = data->buffer;
char *buf = data->state.buffer;
ssize_t nread;
struct TELNET *tn;
@@ -1050,7 +1059,87 @@ CURLcode Curl_telnet(struct connectdata *conn)
code = check_telnet_options(conn);
if(code)
return code;
#ifdef WIN32
/* We want to wait for both stdin and the socket. Since
** the select() function in winsock only works on sockets
** we have to use the WaitForMultipleObjects() call.
*/
/* First, create a sockets event object */
event_handle = WSACreateEvent();
/* The get the Windows file handle for stdin */
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
/* Create the list of objects to wait for */
objs[0] = stdin_handle;
objs[1] = event_handle;
/* Tell winsock what events we want to listen to */
if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
return 0;
}
/* Keep on listening and act on events */
while(keepon) {
waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE);
switch(waitret - WAIT_OBJECT_0)
{
case 0:
{
unsigned char outbuf[2];
int out_count = 0;
size_t bytes_written;
char *buffer = buf;
if(!ReadFile(stdin_handle, buf, 255, &nread, NULL)) {
keepon = FALSE;
break;
}
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == IAC)
outbuf[out_count++] = IAC;
Curl_write(conn, conn->firstsocket, outbuf,
out_count, &bytes_written);
}
}
break;
case 1:
if(WSAEnumNetworkEvents(sockfd, event_handle, &events)
!= SOCKET_ERROR)
{
if(events.lNetworkEvents & FD_READ)
{
Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
telrcv(conn, (unsigned char *)buf, nread);
fflush(stdout);
/* Negotiate if the peer has started negotiating,
otherwise don't. We don't want to speak telnet with
non-telnet servers, like POP or SMTP. */
if(tn->please_negotiate && !tn->already_negotiated) {
negotiate(conn);
tn->already_negotiated = 1;
}
}
if(events.lNetworkEvents & FD_CLOSE)
{
keepon = FALSE;
}
}
break;
}
}
#else
FD_ZERO (&readfd); /* clear it */
FD_SET (sockfd, &readfd);
FD_SET (1, &readfd);
@@ -1108,6 +1197,15 @@ CURLcode Curl_telnet(struct connectdata *conn)
}
}
}
#endif
/* mark this as "no further transfer wanted" */
return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -74,3 +74,11 @@ long Curl_tvlong (struct timeval t1)
{
return t1.tv_sec;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -92,6 +92,7 @@
#include "http.h"
#include "url.h"
#include "getinfo.h"
#include "ssluse.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -197,6 +198,9 @@ Transfer(struct connectdata *c_conn)
Content-Range: header */
int httpcode = 0; /* error code from the 'HTTP/1.? XXX' line */
int httpversion = -1; /* the HTTP version*10 */
bool write_after_100_header = FALSE; /* should we enable the write after
we received a 100-continue/timeout
or directly */
/* for the low speed checks: */
CURLcode urg;
@@ -205,16 +209,16 @@ Transfer(struct connectdata *c_conn)
int writetype;
/* the highest fd we use + 1 */
struct UrlData *data;
struct SessionHandle *data;
struct connectdata *conn = (struct connectdata *)c_conn;
char *buf;
int maxfd;
data = conn->data; /* there's the root struct */
buf = data->buffer;
buf = data->state.buffer;
maxfd = (conn->sockfd>conn->writesockfd?conn->sockfd:conn->writesockfd)+1;
hbufp = data->headerbuff;
hbufp = data->state.headerbuff;
myalarm (0); /* switch off the alarm-style timeout */
@@ -240,7 +244,7 @@ Transfer(struct connectdata *c_conn)
}
/* we want header and/or body, if neither then don't do this! */
if(conn->getheader ||
!data->bits.no_body) {
!data->set.no_body) {
fd_set readfd;
fd_set writefd;
fd_set rkeepfd;
@@ -263,8 +267,13 @@ Transfer(struct connectdata *c_conn)
FD_ZERO (&writefd); /* clear it */
if(conn->writesockfd != -1) {
FD_SET (conn->writesockfd, &writefd); /* write socket */
keepon |= KEEP_WRITE;
if (data->set.expect100header)
/* wait with write until we either got 100-continue or a timeout */
write_after_100_header = TRUE;
else {
FD_SET (conn->writesockfd, &writefd); /* write socket */
keepon |= KEEP_WRITE;
}
}
/* get these in backup variables to be able to restore them on each lap in
@@ -290,6 +299,12 @@ Transfer(struct connectdata *c_conn)
keepon = 0; /* no more read or write */
continue;
case 0: /* timeout */
if (write_after_100_header) {
write_after_100_header = FALSE;
FD_SET (conn->writesockfd, &writefd); /* write socket */
keepon |= KEEP_WRITE;
wkeepfd = writefd;
}
break;
default:
if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) {
@@ -335,19 +350,19 @@ Transfer(struct connectdata *c_conn)
* We enlarge the header buffer if it seems to be too
* smallish
*/
if (hbuflen + (int)str_length >= data->headersize) {
if (hbuflen + (int)str_length >= data->state.headersize) {
char *newbuff;
long newsize=MAX((hbuflen+str_length)*3/2,
data->headersize*2);
hbufp_index = hbufp - data->headerbuff;
newbuff = (char *)realloc(data->headerbuff, newsize);
data->state.headersize*2);
hbufp_index = hbufp - data->state.headerbuff;
newbuff = (char *)realloc(data->state.headerbuff, newsize);
if(!newbuff) {
failf (data, "Failed to alloc memory for big header!");
return CURLE_READ_ERROR;
}
data->headersize=newsize;
data->headerbuff = newbuff;
hbufp = data->headerbuff + hbufp_index;
data->state.headersize=newsize;
data->state.headerbuff = newbuff;
hbufp = data->state.headerbuff + hbufp_index;
}
strcpy (hbufp, str);
hbufp += strlen (str);
@@ -363,19 +378,19 @@ Transfer(struct connectdata *c_conn)
* fit in the allocated header buffer, or else we enlarge
* it.
*/
if (hbuflen + (str - str_start) >= data->headersize) {
if (hbuflen + (str - str_start) >= data->state.headersize) {
char *newbuff;
long newsize=MAX((hbuflen+(str-str_start))*3/2,
data->headersize*2);
hbufp_index = hbufp - data->headerbuff;
newbuff = (char *)realloc(data->headerbuff, newsize);
data->state.headersize*2);
hbufp_index = hbufp - data->state.headerbuff;
newbuff = (char *)realloc(data->state.headerbuff, newsize);
if(!newbuff) {
failf (data, "Failed to alloc memory for big header!");
return CURLE_READ_ERROR;
}
data->headersize= newsize;
data->headerbuff = newbuff;
hbufp = data->headerbuff + hbufp_index;
data->state.headersize= newsize;
data->state.headerbuff = newbuff;
hbufp = data->state.headerbuff + hbufp_index;
}
/* copy to end of line */
@@ -384,7 +399,7 @@ Transfer(struct connectdata *c_conn)
hbuflen += str - str_start;
*hbufp = 0;
p = data->headerbuff;
p = data->state.headerbuff;
/****
* We now have a FULL header line that p points to
@@ -408,22 +423,41 @@ Transfer(struct connectdata *c_conn)
*/
header = TRUE;
headerline = 0; /* we restart the header line counter */
/* if we did wait for this do enable write now! */
if (write_after_100_header) {
write_after_100_header = FALSE;
FD_SET (conn->writesockfd, &writefd); /* write socket */
keepon |= KEEP_WRITE;
wkeepfd = writefd;
}
}
else
else
header = FALSE; /* no more header to parse! */
if (417 == httpcode) {
/*
* we got: "417 Expectation Failed" this means:
* we have made a HTTP call and our Expect Header
* seems to cause a problem => abort the write operations
* (or prevent them from starting
*/
write_after_100_header = FALSE;
keepon &= ~KEEP_WRITE;
FD_ZERO(&wkeepfd);
}
/* now, only output this if the header AND body are requested:
*/
writetype = CLIENTWRITE_HEADER;
if (data->bits.http_include_header)
if (data->set.http_include_header)
writetype |= CLIENTWRITE_BODY;
urg = Curl_client_write(data, writetype, data->headerbuff,
p - data->headerbuff);
urg = Curl_client_write(data, writetype, data->state.headerbuff,
p - data->state.headerbuff);
if(urg)
return urg;
data->header_size += p - data->headerbuff;
data->info.header_size += p - data->state.headerbuff;
if(!header) {
/*
@@ -432,7 +466,7 @@ Transfer(struct connectdata *c_conn)
* If we requested a "no body", this is a good time to get
* out and return home.
*/
if(data->bits.no_body)
if(data->set.no_body)
return CURLE_OK;
if(!conn->bits.close) {
@@ -455,7 +489,7 @@ Transfer(struct connectdata *c_conn)
/* We continue reading headers, so reset the line-based
header parsing variables hbufp && hbuflen */
hbufp = data->headerbuff;
hbufp = data->state.headerbuff;
hbuflen = 0;
continue;
}
@@ -482,17 +516,17 @@ Transfer(struct connectdata *c_conn)
}
if (nc) {
data->progress.httpcode = httpcode;
data->progress.httpversion = httpversion;
data->info.httpcode = httpcode;
data->info.httpversion = httpversion;
/* 404 -> URL not found! */
if (
( ((data->bits.http_follow_location) &&
( ((data->set.http_follow_location) &&
(httpcode >= 400))
||
(!data->bits.http_follow_location &&
(!data->set.http_follow_location &&
(httpcode >= 300)))
&& (data->bits.http_fail_on_error)) {
&& (data->set.http_fail_on_error)) {
/* If we have been told to fail hard on HTTP-errors,
here is the check for that: */
/* serious error, go home! */
@@ -590,14 +624,14 @@ Transfer(struct connectdata *c_conn)
}
else if(strnequal("Last-Modified:", p,
strlen("Last-Modified:")) &&
(data->timecondition || data->bits.get_filetime) ) {
(data->set.timecondition || data->set.get_filetime) ) {
time_t secs=time(NULL);
timeofdoc = curl_getdate(p+strlen("Last-Modified:"), &secs);
if(data->bits.get_filetime)
data->progress.filetime = timeofdoc;
if(data->set.get_filetime)
data->info.filetime = timeofdoc;
}
else if ((httpcode >= 300 && httpcode < 400) &&
(data->bits.http_follow_location) &&
(data->set.http_follow_location) &&
strnequal("Location:", p, 9)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
@@ -626,17 +660,17 @@ Transfer(struct connectdata *c_conn)
*/
writetype = CLIENTWRITE_HEADER;
if (data->bits.http_include_header)
if (data->set.http_include_header)
writetype |= CLIENTWRITE_BODY;
urg = Curl_client_write(data, writetype, p, hbuflen);
if(urg)
return urg;
data->header_size += hbuflen;
data->info.header_size += hbuflen;
/* reset hbufp pointer && hbuflen */
hbufp = data->headerbuff;
hbufp = data->state.headerbuff;
hbuflen = 0;
}
while (*str); /* header line within buffer */
@@ -672,7 +706,7 @@ Transfer(struct connectdata *c_conn)
}
else if (conn->resume_from &&
!content_range &&
(data->httpreq==HTTPREQ_GET)) {
(data->set.httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server
doesn't seem to support this and we did this with a GET
(if it wasn't a GET we did a POST or PUT resume) */
@@ -680,23 +714,23 @@ Transfer(struct connectdata *c_conn)
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
else if(data->timecondition && !conn->range) {
else if(data->set.timecondition && !conn->range) {
/* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of
RFC 2616 defines to be the correct action for a
HTTP/1.1 client */
if((timeofdoc > 0) && (data->timevalue > 0)) {
switch(data->timecondition) {
if((timeofdoc > 0) && (data->set.timevalue > 0)) {
switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE:
default:
if(timeofdoc < data->timevalue) {
if(timeofdoc < data->set.timevalue) {
infof(data,
"The requested document is not new enough\n");
return CURLE_OK;
}
break;
case TIMECOND_IFUNMODSINCE:
if(timeofdoc > data->timevalue) {
if(timeofdoc > data->set.timevalue) {
infof(data,
"The requested document is not old enough\n");
return CURLE_OK;
@@ -763,14 +797,10 @@ Transfer(struct connectdata *c_conn)
if((keepon & KEEP_WRITE) && FD_ISSET(conn->writesockfd, &writefd)) {
/* write */
char scratch[BUFSIZE * 2];
int i, si;
size_t bytes_written;
if(data->crlf)
buf = data->buffer; /* put it back on the buffer */
nread = data->fread(buf, 1, conn->upload_bufsize, data->in);
nread = data->set.fread(buf, 1, conn->upload_bufsize, data->set.in);
/* the signed int typecase of nread of for systems that has
unsigned size_t */
@@ -784,18 +814,18 @@ Transfer(struct connectdata *c_conn)
Curl_pgrsSetUploadCounter(data, (double)writebytecount);
/* convert LF to CRLF if so asked */
if (data->crlf) {
if (data->set.crlf) {
for(i = 0, si = 0; i < (int)nread; i++, si++) {
if (buf[i] == 0x0a) {
scratch[si++] = 0x0d;
scratch[si] = 0x0a;
data->state.scratch[si++] = 0x0d;
data->state.scratch[si] = 0x0a;
}
else {
scratch[si] = buf[i];
data->state.scratch[si] = buf[i];
}
}
nread = si;
buf = scratch; /* point to the new buffer */
buf = data->state.scratch; /* point to the new buffer */
}
/* write to socket */
@@ -806,6 +836,8 @@ Transfer(struct connectdata *c_conn)
failf(data, "Failed uploading data");
return CURLE_WRITE_ERROR;
}
if(data->set.crlf)
buf = data->state.buffer; /* put it back on the buffer */
}
@@ -829,7 +861,7 @@ Transfer(struct connectdata *c_conn)
conn->upload_bufsize=(long)min(data->progress.ulspeed, BUFSIZE);
}
if (data->timeout && (Curl_tvdiff (now, start) > data->timeout)) {
if (data->set.timeout && (Curl_tvdiff (now, start) > data->set.timeout)) {
failf (data, "Operation timed out with %d out of %d bytes received",
bytecount, conn->size);
return CURLE_OPERATION_TIMEOUTED;
@@ -842,7 +874,7 @@ Transfer(struct connectdata *c_conn)
* returning.
*/
if(!(data->bits.no_body) && contentlength &&
if(!(data->set.no_body) && contentlength &&
(bytecount != contentlength)) {
failf(data, "transfer closed with %d bytes remaining to read",
contentlength-bytecount);
@@ -864,19 +896,26 @@ Transfer(struct connectdata *c_conn)
return CURLE_OK;
}
CURLcode Curl_perform(struct UrlData *data)
CURLcode Curl_perform(struct SessionHandle *data)
{
CURLcode res;
struct connectdata *conn=NULL;
bool port=TRUE; /* allow data->use_port to set port to use */
bool port=TRUE; /* allow data->set.use_port to set port to use */
char *newurl = NULL; /* possibly a new URL to follow to! */
if(!data->url)
if(!data->change.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 */
#ifdef USE_SSLEAY
/* Init the SSL session ID cache here. We do it here since we want to
do it after the *_setopt() calls (that could change the size) but
before any transfer. */
Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
#endif
data->set.followlocation=0; /* reset the location-follow counter */
data->state.this_is_a_follow = FALSE; /* reset this */
Curl_initinfo(data); /* reset session-specific information "variables" */
@@ -923,30 +962,28 @@ CURLcode Curl_perform(struct UrlData *data)
port=TRUE; /* by default we use the user set port number even after
a Location: */
if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->maxredirs);
if (data->set.maxredirs && (data->set.followlocation >= data->set.maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
res=CURLE_TOO_MANY_REDIRECTS;
break;
}
/* mark the next request as a followed location: */
data->bits.this_is_a_follow = TRUE;
data->state.this_is_a_follow = TRUE;
data->followlocation++; /* count location-followers */
data->set.followlocation++; /* count location-followers */
if(data->bits.http_auto_referer) {
if(data->set.http_auto_referer) {
/* We are asked to automatically set the previous URL as the
referer when we get the next URL. We pick the ->url field,
which may or may not be 100% correct */
if(data->free_referer) {
if(data->change.referer_alloc)
/* If we already have an allocated referer, free this first */
free(data->referer);
}
free(data->change.referer);
data->referer = strdup(data->url);
data->free_referer = TRUE; /* yes, free this later */
data->bits.http_set_referer = TRUE; /* might have been false */
data->change.referer = strdup(data->change.url);
data->change.referer_alloc = TRUE; /* yes, free this later */
}
if(2 != sscanf(newurl, "%15[^:]://%c", prot, &letter)) {
@@ -964,7 +1001,7 @@ CURLcode Curl_perform(struct UrlData *data)
/* 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);
char *url_clone=strdup(data->change.url);
if(!url_clone)
return CURLE_OUT_OF_MEMORY;
@@ -1014,16 +1051,16 @@ CURLcode Curl_perform(struct UrlData *data)
port = FALSE;
}
if(data->bits.urlstringalloc)
free(data->url);
if(data->change.url_alloc)
free(data->change.url);
else
data->change.url_alloc = TRUE; /* the URL is allocated */
/* TBD: set the URL with curl_setopt() */
data->url = newurl;
data->change.url = newurl;
newurl = NULL; /* don't free! */
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->change.url);
/*
* We get here when the HTTP code is 300-399. We need to perform
@@ -1031,7 +1068,7 @@ CURLcode Curl_perform(struct UrlData *data)
* Discussed on the curl mailing list and posted about on the 26th
* of January 2001.
*/
switch(data->progress.httpcode) {
switch(data->info.httpcode) {
case 300: /* Multiple Choices */
case 301: /* Moved Permanently */
case 306: /* Not used */
@@ -1062,7 +1099,7 @@ CURLcode Curl_perform(struct UrlData *data)
case 303: /* See Other */
/* Disable both types of POSTs, since doing a second POST when
* following isn't what anyone would want! */
data->httpreq = HTTPREQ_GET; /* enforce GET request */
data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
infof(data, "Disables POST, goes with GET\n");
break;
case 304: /* Not Modified */
@@ -1091,7 +1128,7 @@ CURLcode Curl_perform(struct UrlData *data)
free(newurl);
/* make sure the alarm is switched off! */
if(data->timeout || data->connecttimeout)
if(data->set.timeout || data->set.connecttimeout)
myalarm(0);
return res;
@@ -1125,3 +1162,10 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -22,7 +22,7 @@
*
* $Id$
*****************************************************************************/
CURLcode Curl_perform(struct UrlData *data);
CURLcode Curl_perform(struct SessionHandle *data);
/* This sets up a forthcoming transfer */
CURLcode

665
lib/url.c

File diff suppressed because it is too large Load Diff

View File

@@ -27,10 +27,10 @@
* Prototypes for library-wide functions provided by url.c
*/
CURLcode Curl_open(struct UrlData **curl);
CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...);
CURLcode Curl_close(struct UrlData *data); /* the opposite of curl_open() */
CURLcode Curl_connect(struct UrlData *,
CURLcode Curl_open(struct SessionHandle **curl);
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
CURLcode Curl_close(struct SessionHandle *data); /* the opposite of curl_open() */
CURLcode Curl_connect(struct SessionHandle *,
struct connectdata **,
bool allow_port);
CURLcode Curl_do(struct connectdata *);

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
@@ -27,10 +27,6 @@
#include "setup.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
#define PORT_FTP 21
#define PORT_TELNET 23
#define PORT_GOPHER 70
@@ -125,6 +121,14 @@ struct ssl_connect_data {
#endif /* USE_SSLEAY */
};
/* information about one single SSL session */
struct curl_ssl_session {
char *name; /* host name for which this ID was used */
void *sessionid; /* as returned from the SSL layer */
long age; /* just a number, the higher the more recent */
unsigned short remote_port; /* remote port to connect to */
};
struct ssl_config_data {
long version; /* what version the client wants to use */
long certverifyresult; /* result from the certificate verification */
@@ -134,6 +138,9 @@ struct ssl_config_data {
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 */
char *cipher_list; /* list of ciphers to use */
long numsessions; /* SSL session id cache size */
};
/****************************************************************************
@@ -183,8 +190,8 @@ struct ConnectBits {
bool close; /* if set, we close the connection after this request */
bool reuse; /* if set, this is a re-used connection */
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 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;
@@ -200,7 +207,7 @@ struct ConnectBits {
*/
struct connectdata {
/**** Fields set when inited and not modified again */
struct UrlData *data; /* link to the root CURL struct */
struct SessionHandle *data; /* link to the root CURL struct */
int connectindex; /* what index in the connects index this particular
struct has */
@@ -336,9 +343,21 @@ struct connectdata {
void *generic;
} proto;
};
/*
* Struct to keep statistical and informational data.
*/
struct PureInfo {
int httpcode;
int httpversion;
time_t filetime; /* If requested, this is might get set. It may be 0 if
the time was unretrievable */
long header_size; /* size of read header(s) in bytes */
long request_size; /* the amount of bytes sent in the request(s) */
};
struct Progress {
long lastshow; /* time() of the last displayed progress meter or NULL to
force redraw at next call */
@@ -356,17 +375,12 @@ struct Progress {
double dlspeed;
double ulspeed;
struct timeval start;
struct timeval t_startsingle;
/* various data stored for possible later report */
double t_nslookup;
double t_connect;
double t_pretransfer;
int httpcode;
int httpversion;
time_t filetime; /* If requested, this is might get set. It may be 0 if
the time was unretrievable */
struct timeval start;
struct timeval t_startsingle;
#define CURR_TIME 5
double speeder[ CURR_TIME ];
@@ -383,9 +397,144 @@ typedef enum {
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
/* This struct is for boolean settings that define how to behave during
this session. */
struct Configbits {
/*
* Values that are generated, temporary or calculated internally for a
* "session handle" must be defined within the 'struct urlstate'. This struct
* will be used within the SessionHandle struct. When the 'SessionHandle'
* struct is cloned, this data MUST NOT be copied.
*
* Remember that any "state" information goes globally for the curl handle.
* Session-data MUST be put in the connectdata struct and here. */
#define MAX_CURL_USER_LENGTH 256
#define MAX_CURL_PASSWORD_LENGTH 256
struct UrlState {
/* buffers to store authentication data in, as parsed from input options */
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
char proxyuser[MAX_CURL_USER_LENGTH];
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
struct timeval keeps_speed; /* for the progress meter really */
/* 'connects' will be an allocated array with pointers. If the pointer is
set, it holds an allocated connection. */
struct connectdata **connects;
long numconnects; /* size of the 'connects' array */
char *headerbuff; /* allocated buffer to store headers in */
int headersize; /* size of the allocation */
char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
double current_speed; /* the ProgressShow() funcion sets this */
bool this_is_a_follow; /* this is a followed Location: request */
char *auth_host; /* if set, this should be the host name that we will
sent authorization to, no else. Used to make Location:
following not keep sending user+password... This is
strdup() data.
*/
struct curl_ssl_session *session; /* array of 'numsessions' size */
long sessionage; /* number of the most recent session */
char scratch[BUFSIZE*2]; /* huge buffer when doing upload CRLF replacing */
};
/*
* This 'DynamicStatic' struct defines dynamic states that actually change
* values in the 'UserDefined' area, which MUST be taken into consideration
* if the UserDefined struct is cloned or similar. You can probably just
* copy these, but each one indicate a special action on other data.
*/
struct DynamicStatic {
char *url; /* work URL, copied from UserDefined */
bool url_alloc; /* URL string is malloc()'ed */
char *proxy; /* work proxy, copied from UserDefined */
bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */
};
/*
* This 'UserDefined' struct must only contain data that is set once to go
* for many (perhaps) independent connections. Values that are generated or
* calculated internally for the "session handle" MUST be defined within the
* 'struct urlstate' instead. The only exceptions MUST note the changes in
* the 'DynamicStatic' struct.
*/
struct UserDefined {
FILE *err; /* the stderr writes goes here */
char *errorbuffer; /* store failure messages in here */
char *proxyuserpwd; /* Proxy <user:password>, if used */
long proxyport; /* If non-zero, use this port number by default. If the
proxy string features a ":[port]" that one will override
this. */
void *out; /* the fetched file goes here */
void *in; /* the uploaded file is read from here */
void *writeheader; /* write the header to this is non-NULL */
char *set_url; /* what original URL to work on */
char *set_proxy; /* proxy to use */
long use_port; /* which port to use (when not using default) */
char *userpwd; /* <user:password>, if used */
char *set_range; /* range, if used. See README for detailed specification
on this syntax. */
long followlocation; /* as in HTTP Location: */
long maxredirs; /* maximum no. of http(s) redirects to follow */
char *set_referer; /* custom string */
bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */
char *useragent; /* User-Agent string */
char *postfields; /* if POST, set the fields' values here */
size_t postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain
zero bytes) */
char *ftpport; /* port to send with the FTP PORT command */
char *device; /* network interface to use */
curl_write_callback fwrite; /* function that stores the output */
curl_write_callback fwrite_header; /* function that stores headers */
curl_read_callback fread; /* function that reads the input */
curl_progress_callback fprogress; /* function for progress information */
void *progress_client; /* pointer to pass to the progress callback */
curl_passwd_callback fpasswd; /* call for password */
void *passwd_client; /* pass to the passwd callback */
long timeout; /* in seconds, 0 means no timeout */
long connecttimeout; /* in seconds, 0 means no timeout */
long infilesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
int set_resume_from; /* continue [ftp] transfer from here */
char *cookie; /* HTTP cookie string to send */
struct curl_slist *headers; /* linked list of extra headers */
struct HttpPost *httppost; /* linked list of POST data */
char *cert; /* PEM-formatted certificate */
char *cert_passwd; /* plain text certificate password */
char *cookiejar; /* dump all cookies to this file */
bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* before the transfer */
struct curl_slist *postquote; /* after the transfer */
struct curl_slist *telnet_options; /* linked list of telnet options */
TimeCond timecondition; /* kind of time/date comparison */
time_t timevalue; /* what time to compare with */
curl_closepolicy closepolicy; /* connection cache close concept */
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
char *customrequest; /* HTTP/FTP request to use */
char *auth_host; /* if set, this is the allocated string to the host name
* to which to send the authorization data to, and no other
* host (which location-following otherwise could lead to)
*/
char *krb4_level; /* what security level */
struct ssl_config_data ssl; /* user defined SSL stuff */
/* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially
and they don't change during operations. */
bool get_filetime;
bool tunnel_thru_httpproxy;
bool ftp_append;
@@ -398,183 +547,39 @@ struct Configbits {
bool http_include_header;
bool http_set_referer;
bool http_auto_referer; /* set "correct" referer when following location: */
bool httpproxy;
bool no_body;
bool set_port;
bool set_range;
bool upload;
bool use_netrc;
bool verbose;
bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */
bool proxystringalloc; /* the http proxy 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 */
bool krb4; /* kerberos4 connection requested */
bool reuse_forbid; /* forbidden to be reused, close after use */
bool reuse_fresh; /* do not re-use an existing connection */
bool expect100header; /* TRUE if we added Expect: 100-continue */
};
/*
* As of April 11, 2000 we're now trying to split up the urldata struct in
* three different parts:
* In August 2001, this struct was redesigned and is since stricter than
* before. The 'connectdata' struct MUST have all the connection oriented
* stuff as we may now have several simultaneous connections and connection
* structs in memory.
*
* (Global)
* 1 - No matter how many hosts and requests that are being performed, this
* goes for all of them.
*
* (Session)
* 2 - Host and protocol-specific. No matter if we do several transfers to and
* from this host, these variables stay the same.
*
* (Request)
* 3 - Request-specific. Variables that are of interest for this particular
* transfer being made right now. THIS IS WRONG STRUCT FOR THOSE.
*
* In Febrary 2001, this is being done stricter. The 'connectdata' struct
* MUST have all the connection oriented stuff as we may now have several
* simultaneous connections and connection structs in memory.
*
* From now on, the 'UrlData' must only contain data that is set once to go
* for many (perhaps) independent connections. Values that are generated or
* calculated internally MUST NOT be a part of this struct.
*/
* From now on, the 'SessionHandle' must only contain data that is set once to
* go for many (perhaps) independent connections. Values that are generated or
* calculated internally for the "session handle" must be defined within the
* 'struct urlstate' instead. */
struct UrlData {
/*************** Global - specific items ************/
FILE *err; /* the stderr writes goes here */
char *errorbuffer; /* store failure messages in here */
/*************** Session - specific items ************/
char *proxy; /* if proxy, set it here */
char *proxyuserpwd; /* Proxy <user:password>, if used */
long proxyport; /* If non-zero, use this port number by default. If the
proxy string features a ":[port]" that one will override
this. */
long header_size; /* size of read header(s) in bytes */
long request_size; /* the amount of bytes sent in the request(s) */
void *out; /* the fetched file goes here */
void *in; /* the uploaded file is read from here */
void *writeheader; /* write the header to this is non-NULL */
char *url; /* what to get */
char *freethis; /* if non-NULL, an allocated string for the URL */
long use_port; /* which port to use (when not using default) */
struct Configbits bits; /* new-style (v7) flag data */
struct ssl_config_data ssl; /* this is for ssl-stuff */
char *userpwd; /* <user:password>, if used */
char *set_range; /* range, if used. See README for detailed specification on
this syntax. */
/* stuff related to HTTP */
long followlocation;
long maxredirs; /* maximum no. of http(s) redirects to follow */
char *referer;
bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */
char *useragent; /* User-Agent string */
char *postfields; /* if POST, set the fields' values here */
size_t postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain
zero bytes) */
/* stuff related to FTP */
char *ftpport; /* port to send with the PORT command */
/* general things */
char *device; /* Interface to use */
/* function that stores the output:*/
curl_write_callback fwrite;
/* optional function that stores the header output:*/
curl_write_callback fwrite_header;
/* function that reads the input:*/
curl_read_callback fread;
/* function that wants progress information */
curl_progress_callback fprogress;
void *progress_client; /* pointer to pass to the progress callback */
/* function to call instead of the internal for password */
curl_passwd_callback fpasswd;
void *passwd_client; /* pointer to pass to the passwd callback */
long timeout; /* in seconds, 0 means no timeout */
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 */
double current_speed; /* the ProgressShow() funcion sets this */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
int set_resume_from; /* continue [ftp] transfer from here */
char *cookie; /* HTTP cookie string to send */
struct curl_slist *headers; /* linked list of extra headers */
struct HttpPost *httppost; /* linked list of POST data */
char *cert; /* PEM-formatted certificate */
char *cert_passwd; /* plain text certificate password */
struct CookieInfo *cookies;
long crlf;
struct curl_slist *quote; /* before the transfer */
struct curl_slist *postquote; /* after the transfer */
/* Telnet negotiation options */
struct curl_slist *telnet_options; /* linked list of telnet options */
TimeCond timecondition; /* kind of comparison */
time_t timevalue; /* what time to compare with */
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
char *customrequest; /* http/ftp request to use */
char *headerbuff; /* allocated buffer to store headers in */
int headersize; /* size of the allocation */
struct Progress progress; /* for all the progress meter data */
#define MAX_CURL_USER_LENGTH 128
#define MAX_CURL_PASSWORD_LENGTH 128
char *auth_host; /* if set, this is the allocated string to the host name
* to which to send the authorization data to, and no other
* host (which location-following otherwise could lead to)
*/
/* buffers to store authentication data in */
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
char proxyuser[MAX_CURL_USER_LENGTH];
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
char *krb4_level; /* what security level */
struct timeval keeps_speed; /* this should be request-specific */
/* 'connects' will be an allocated array with pointers. If the pointer is
set, it holds an allocated connection. */
struct connectdata **connects;
long numconnects; /* size of the 'connects' array */
curl_closepolicy closepolicy;
struct SessionHandle {
struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */
struct CookieInfo *cookies; /* the cookies, read from files and servers */
struct Progress progress; /* for all the progress meter data */
struct UrlState state; /* struct for fields used for state info and
other dynamic purposes */
struct PureInfo info; /* stats, reports and info data */
};
#define LIBCURL_NAME "libcurl"
#define LIBCURL_ID LIBCURL_NAME " " LIBCURL_VERSION " " SSL_ID
#endif

View File

@@ -103,3 +103,11 @@ char *curl_version(void)
return version;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
* vim<600: et sw=2 ts=2 sts=2 tw=78
*/

138
ltmain.sh
View File

@@ -55,8 +55,8 @@ modename="$progname"
# Constants.
PROGRAM=ltmain.sh
PACKAGE=libtool
VERSION=1.4
TIMESTAMP=" (1.920 2001/04/24 23:26:18)"
VERSION=1.4.2
TIMESTAMP=" (1.922.2.53 2001/09/11 03:18:52)"
default_mode=
help="Try \`$progname --help' for more information."
@@ -84,6 +84,9 @@ if test "${LANG+set}" = set; then
save_LANG="$LANG"; LANG=C; export LANG
fi
# Make sure IFS has a sensible default
: ${IFS=" "}
if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
echo "$modename: not configured to build any kind of library" 1>&2
echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
@@ -202,6 +205,11 @@ if test -n "$prevopt"; then
exit 1
fi
# If this variable is set in any of the actions, the command in it
# will be execed at the end. This prevents here-documents from being
# left over by shells.
exec_cmd=
if test -z "$show_help"; then
# Infer the operation mode.
@@ -329,7 +337,7 @@ if test -z "$show_help"; then
-Wc,*)
args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
lastarg=
IFS="${IFS= }"; save_ifs="$IFS"; IFS=','
save_ifs="$IFS"; IFS=','
for arg in $args; do
IFS="$save_ifs"
@@ -615,6 +623,10 @@ compiler."
# Now arrange that obj and lo_libobj become the same file
$show "(cd $xdir && $LN_S $baseobj $libobj)"
if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
# Unlock the critical section if it was locked
if test "$need_locks" != no; then
$run $rm "$lockfile"
fi
exit 0
else
error=$?
@@ -1031,6 +1043,17 @@ compiler."
# These systems don't actually have a C library (as such)
test "X$arg" = "X-lc" && continue
;;
*-*-openbsd*)
# Do not include libc due to us having libc/libc_r.
test "X$arg" = "X-lc" && continue
;;
esac
elif test "X$arg" = "X-lc_r"; then
case $host in
*-*-openbsd*)
# Do not include libc_r directly, use -pthread flag.
continue
;;
esac
fi
deplibs="$deplibs $arg"
@@ -1122,7 +1145,7 @@ compiler."
-Wc,*)
args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
arg=
IFS="${IFS= }"; save_ifs="$IFS"; IFS=','
save_ifs="$IFS"; IFS=','
for flag in $args; do
IFS="$save_ifs"
case $flag in
@@ -1140,7 +1163,7 @@ compiler."
-Wl,*)
args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
arg=
IFS="${IFS= }"; save_ifs="$IFS"; IFS=','
save_ifs="$IFS"; IFS=','
for flag in $args; do
IFS="$save_ifs"
case $flag in
@@ -1750,7 +1773,7 @@ compiler."
if test -f "$output_objdir/$soname-def"; then :
else
$show "extracting exported symbol list from \`$soname'"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
eval cmds=\"$extract_expsyms_cmds\"
for cmd in $cmds; do
IFS="$save_ifs"
@@ -1763,7 +1786,7 @@ compiler."
# Create $newlib
if test -f "$output_objdir/$newlib"; then :; else
$show "generating import library for \`$soname'"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
eval cmds=\"$old_archive_from_expsyms_cmds\"
for cmd in $cmds; do
IFS="$save_ifs"
@@ -1911,17 +1934,17 @@ compiler."
echo "*** Therefore, libtool will create a static module, that should work "
echo "*** as long as the dlopening application is linked with the -dlopen flag."
if test -z "$global_symbol_pipe"; then
echo
echo "*** However, this would only work if libtool was able to extract symbol"
echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
echo "*** not find such a program. So, this module is probably useless."
echo "*** \`nm' from GNU binutils and a full rebuild may help."
echo
echo "*** However, this would only work if libtool was able to extract symbol"
echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
echo "*** not find such a program. So, this module is probably useless."
echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
if test "$build_old_libs" = no; then
build_libtool_libs=module
build_old_libs=yes
build_libtool_libs=module
build_old_libs=yes
else
build_libtool_libs=no
build_libtool_libs=no
fi
fi
else
@@ -2175,7 +2198,7 @@ compiler."
else
# Parse the version information argument.
IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
save_ifs="$IFS"; IFS=':'
set dummy $vinfo 0 0 0
IFS="$save_ifs"
@@ -2312,6 +2335,16 @@ compiler."
if test -z "$vinfo" && test -n "$release"; then
major=
verstring="0.0"
case $version_type in
darwin)
# we can't check for "0.0" in archive_cmds due to quoting
# problems, so we reset it completely
verstring=""
;;
*)
verstring="0.0"
;;
esac
if test "$need_version" = no; then
versuffix=
else
@@ -2408,6 +2441,9 @@ compiler."
*-*-netbsd*)
# Don't link with libc until the a.out ld.so is fixed.
;;
*-*-openbsd*)
# Do not include libc due to us having libc/libc_r.
;;
*)
# Add libc to deplibs on all other systems if necessary.
if test $build_libtool_need_lc = "yes"; then
@@ -2784,7 +2820,7 @@ EOF
export_symbols="$output_objdir/$libname.exp"
$run $rm $export_symbols
eval cmds=\"$export_symbols_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -2860,7 +2896,7 @@ EOF
else
eval cmds=\"$archive_cmds\"
fi
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -2988,7 +3024,7 @@ EOF
output="$obj"
eval cmds=\"$reload_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -3024,7 +3060,7 @@ EOF
reload_objs="$libobjs $reload_conv_objs"
output="$libobj"
eval cmds=\"$reload_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -3287,27 +3323,25 @@ extern \"C\" {
#undef lt_preloaded_symbols
#if defined (__STDC__) && __STDC__
# define lt_ptr_t void *
# define lt_ptr void *
#else
# define lt_ptr_t char *
# define lt_ptr char *
# define const
#endif
/* The mapping between symbol names and symbols. */
const struct {
const char *name;
lt_ptr_t address;
lt_ptr address;
}
lt_preloaded_symbols[] =
{\
"
sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
-e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
< "$nlist" >> "$output_objdir/$dlsyms"
eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
$echo >> "$output_objdir/$dlsyms" "\
{0, (lt_ptr_t) 0}
{0, (lt_ptr) 0}
};
/* This works around a problem in FreeBSD linker */
@@ -3618,8 +3652,9 @@ else
# relink executable if necessary
if test -n \"\$relink_command\"; then
if (eval \$relink_command); then :
if relink_command_output=\`eval \$relink_command 2>&1\`; then :
else
$echo \"\$relink_command_output\" >&2
$rm \"\$progdir/\$file\"
exit 1
fi
@@ -3790,7 +3825,7 @@ fi\
eval cmds=\"$old_archive_cmds\"
fi
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4165,7 +4200,7 @@ relink_command=\"$relink_command\""
# Do each command in the postinstall commands.
lib="$destdir/$realname"
eval cmds=\"$postinstall_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4352,7 +4387,7 @@ relink_command=\"$relink_command\""
# Do each command in the postinstall commands.
eval cmds=\"$old_postinstall_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4368,11 +4403,10 @@ relink_command=\"$relink_command\""
if test -n "$current_libdirs"; then
# Maybe just do a dry run.
test -n "$run" && current_libdirs=" -n$current_libdirs"
exec $SHELL $0 --finish$current_libdirs
exit 1
exec_cmd='$SHELL $0 --finish$current_libdirs'
else
exit 0
fi
exit 0
;;
# libtool finish mode
@@ -4391,7 +4425,7 @@ relink_command=\"$relink_command\""
if test -n "$finish_cmds"; then
# Do each command in the finish commands.
eval cmds=\"$finish_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4575,11 +4609,8 @@ relink_command=\"$relink_command\""
LANG="$save_LANG"; export LANG
fi
# Now actually exec the command.
eval "exec \$cmd$args"
$echo "$modename: cannot exec \$cmd$args"
exit 1
# Now prepare to actually exec the command.
exec_cmd='"$cmd"$args'
else
# Display what would be done.
if test -n "$shlibpath_var"; then
@@ -4641,14 +4672,14 @@ relink_command=\"$relink_command\""
# Don't error if the file doesn't exist and rm -f was used.
if (test -L "$file") >/dev/null 2>&1 \
|| (test -h "$file") >/dev/null 2>&1 \
|| (test -h "$file") >/dev/null 2>&1 \
|| test -f "$file"; then
:
:
elif test -d "$file"; then
exit_status=1
exit_status=1
continue
elif test "$rmforce" = yes; then
continue
continue
fi
rmfiles="$file"
@@ -4670,7 +4701,7 @@ relink_command=\"$relink_command\""
if test -n "$library_names"; then
# Do each command in the postuninstall commands.
eval cmds=\"$postuninstall_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4685,7 +4716,7 @@ relink_command=\"$relink_command\""
if test -n "$old_library"; then
# Do each command in the old_postuninstall commands.
eval cmds=\"$old_postuninstall_cmds\"
IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
$show "$cmd"
@@ -4744,11 +4775,18 @@ relink_command=\"$relink_command\""
;;
esac
$echo "$modename: invalid operation mode \`$mode'" 1>&2
$echo "$generic_help" 1>&2
exit 1
if test -z "$exec_cmd"; then
$echo "$modename: invalid operation mode \`$mode'" 1>&2
$echo "$generic_help" 1>&2
exit 1
fi
fi # test -z "$show_help"
if test -n "$exec_cmd"; then
eval exec $exec_cmd
exit 1
fi
# We need to display help for each of the modes.
case $mode in
"") $echo \

View File

@@ -76,6 +76,12 @@ else
automake --include-deps Makefile
fi
############################################################################
#
# Make sure we have updated HTML versions of all man pages:
#
make html
############################################################################
#
# Now run make dist

133
missing
View File

@@ -1,7 +1,7 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,11 +18,37 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
@@ -35,6 +61,7 @@ error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
@@ -43,13 +70,15 @@ Supported PROGRAM values:
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
echo "missing 0.3 - GNU automake"
;;
-*)
@@ -61,7 +90,7 @@ Supported PROGRAM values:
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
@@ -70,7 +99,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
@@ -79,29 +108,31 @@ WARNING: \`$1' is missing on your system. You should only need it if
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER([^):]*:\([^)]*\)).*/\1/p' configure.in`
if test -z "$files"; then
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^):]*\)).*/\1/p' configure.in`
test -z "$files" || files="$files.in"
else
files=`echo "$files" | sed -e 's/:/ /g'`
fi
test -z "$files" && files="config.h.in"
touch $files
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print \
| sed 's/^\(.*\).am$/touch \1.in/' \
| sh
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
@@ -157,7 +188,32 @@ WARNING: \`$1' is missing on your system. You should only need it if
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
@@ -173,6 +229,45 @@ WARNING: \`$1' is missing on your system. You should only need it if
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar ${1+"$@"} && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar ${1+"$@"} && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your

View File

@@ -1,6 +1,22 @@
Revision history for Perl extension Curl::easy.
Check out the file README for more info.
1.1.8 Thu Sep 20 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Re-generate CURLOPT_ constants from curl.h and enhance makefile
to allow this to be repeated in future or for older versions of
libcurl. Constants up-to-date for libcurl-7.9(pre)
- Split tests into t/*.t to simplify each case
- Add test cases for new SSL switches. This needs ca-bundle.crt
(from mod_ssl) for verifying test cases.
1.1.7 Thu Sep 13 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Documentation Update only - Explicitly state that Curl_easy
is released under the MIT-X/MPL dual licence. No code changes.
1.1.6 Mon Sep 10 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Fix segfault due to changes in header callback behaviour
since curl-7.8.1-pre3
1.1.5 Fri Apr 20 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Add latest CURLOPT_ and CURLINFO_ constants to the constants list

View File

@@ -4,4 +4,13 @@ Makefile.PL
README
easy.pm
easy.xs
test.pl
curlopt-constants.c
t/00constants.t
t/01basic.t
t/02header-callback.t
t/03body-callback.t
t/04abort-test.t
t/05progress.t
t/06http-post.t
t/07ftp-upload.t
t/08ssl.t

View File

@@ -12,3 +12,76 @@ WriteMakefile(
'INC' => '', # e.g., '-I/usr/include/other'
'clean' => {FILES => "head.out body.out"}
);
#
# This utility helper generates the constants function from curl.h
#
# It is normally only used by the maintainer, but if you're curl is older
# or missing some constants, you can delete curlopt-constants.c and re-run 'perl Makefile.PL'
#
if (!open(CONSTANTS,"<curlopt-constants.c")) {
print "Rebuilding curlopt-constants.c for your libcurl version\n";
close(CONSTANTS);
#
# You may need to specify where to find curl.h on your platform
# These are guesses only
#
my $curl_h;
HEADER: foreach my $try (qw(
curl.h
../../include/curl.h
/usr/include/curl/curl.h
/usr/local/include/curl/curl.h
C:\\INCLUDE\\CURL\\CURL.H
))
{
if (-e $try) {
$curl_h=$try;
last HEADER;
}
}
if (!defined($curl_h)) {
die "Could not rebuild curlopt-constants.c - can't find curl.h\n";
}
print "Found curl.h in $curl_h\n";
open (CURL_H,"<".$curl_h) or die "Can't open curl.h\n";
my %types;
my %codes;
while(<CURL_H>) {
if ($_ =~ m/CINIT\(/ and $_ !~ m/#/) {
my ($option,$type,$code)=m/.*CINIT\((\w*)\s*,\s*(\w+)\s*,\s*(\d+).*/;
$types{$option}=$type;
$codes{$option}=$code;
}
}
close(CURL_H);
# some things are ifdefed out...
foreach my $ifdef0 (qw(FLAGS PROGRESSMODE))
{
delete $types{$ifdef0}; delete $codes{$ifdef0};
}
open(CURL_XS,">curlopt-constants.c") or die "Can't write curlopt-constants.c\n";
foreach my $next_initial ('A'..'Z') {
print CURL_XS " case '$next_initial':\n";
my $count=0;
foreach my $option (sort keys %types) {
my $initial=substr($option,0,1);
if ($next_initial eq $initial) {
print CURL_XS " if (strEQ(name, \"$option\")) return CURLOPT_$option;\n";
$count++;
}
}
if ($count) {
print CURL_XS " break;\n";
}
}
close(CURL_XS);
}

View File

@@ -1 +1,3 @@
EXTRA_DIST = Changes easy.pm easy.xs Makefile.PL MANIFEST README test.pl
SUBDIRS = t
EXTRA_DIST = Changes easy.pm easy.xs curlopt-constants.c Makefile.PL MANIFEST README

View File

@@ -11,17 +11,30 @@ installed. You then may install this module via the usual way:
make test
make install
If you have an older version of libcurl, you can remove 'curlopt-constants.c'
and have it rebuilt by 'perl Makefile.PL'.
You can also do this for a later version of libcurl, except currently
you will have to update the module EXPORTS list manually.
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.
t/*.t.
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 original author of this software is Georg Horn <horn@koblenz-net.de>
Parts of the callback support, tests and documentation have been added by
Cris Bailiff <c.bailiff@devsecure.com> and Forrest Cahoon <forrest.cahoon@merrillcorp.com>
The latest version can be downloaded from http://koblenz-net.de/~horn/export/
The current maintainer is Cris Bailiff <c.bailiff@devsecure.com>
The latest version can be downloaded from http://curl.haxx.se/libcurl/perl/
Copyright (C) 2000, Daniel Stenberg, , et al.
You may opt to use, copy, modify, merge, publish, distribute and/or sell
copies of the Software, and permit persons to whom the Software is
furnished to do so, under the terms of the MPL or the MIT/X-derivate
licenses. You may pick one of these licenses.

View File

@@ -0,0 +1,125 @@
case 'A':
if (strEQ(name, "AUTOREFERER")) return CURLOPT_AUTOREFERER;
break;
case 'B':
case 'C':
if (strEQ(name, "CAINFO")) return CURLOPT_CAINFO;
if (strEQ(name, "CLOSEFUNCTION")) return CURLOPT_CLOSEFUNCTION;
if (strEQ(name, "CLOSEPOLICY")) return CURLOPT_CLOSEPOLICY;
if (strEQ(name, "CONNECTTIMEOUT")) return CURLOPT_CONNECTTIMEOUT;
if (strEQ(name, "COOKIE")) return CURLOPT_COOKIE;
if (strEQ(name, "COOKIEFILE")) return CURLOPT_COOKIEFILE;
if (strEQ(name, "COOKIEJAR")) return CURLOPT_COOKIEJAR;
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, "FRESH_CONNECT")) return CURLOPT_FRESH_CONNECT;
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;
break;
case 'G':
case 'H':
if (strEQ(name, "HEADER")) return CURLOPT_HEADER;
if (strEQ(name, "HEADERFUNCTION")) return CURLOPT_HEADERFUNCTION;
if (strEQ(name, "HTTPGET")) return CURLOPT_HTTPGET;
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':
if (strEQ(name, "INFILE")) return CURLOPT_INFILE;
if (strEQ(name, "INFILESIZE")) return CURLOPT_INFILESIZE;
if (strEQ(name, "INTERFACE")) return CURLOPT_INTERFACE;
break;
case 'J':
case 'K':
if (strEQ(name, "KRB4LEVEL")) return CURLOPT_KRB4LEVEL;
break;
case 'L':
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;
if (strEQ(name, "MUTE")) return CURLOPT_MUTE;
break;
case 'N':
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, "SSL_CIPHER_LIST")) return CURLOPT_SSL_CIPHER_LIST;
if (strEQ(name, "SSL_VERIFYHOST")) return CURLOPT_SSL_VERIFYHOST;
if (strEQ(name, "SSL_VERIFYPEER")) return CURLOPT_SSL_VERIFYPEER;
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':
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;
break;
case 'V':
if (strEQ(name, "VERBOSE")) return CURLOPT_VERBOSE;
break;
case 'W':
if (strEQ(name, "WRITEFUNCTION")) return CURLOPT_WRITEFUNCTION;
if (strEQ(name, "WRITEHEADER")) return CURLOPT_WRITEHEADER;
if (strEQ(name, "WRITEINFO")) return CURLOPT_WRITEINFO;
break;
case 'X':
case 'Y':
case 'Z':

View File

@@ -16,20 +16,30 @@ require AutoLoader;
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
CURLOPT_AUTOREFERER
CURLOPT_CAINFO
CURLOPT_CLOSEFUNCTION
CURLOPT_CLOSEPOLICY
CURLOPT_CONNECTTIMEOUT
CURLOPT_COOKIE
CURLOPT_COOKIEFILE
CURLOPT_COOKIEJAR
CURLOPT_CRLF
CURLOPT_CUSTOMREQUEST
CURLOPT_EGDSOCKET
CURLOPT_ERRORBUFFER
CURLOPT_FAILONERROR
CURLOPT_FILE
CURLOPT_FILETIME
CURLOPT_FOLLOWLOCATION
CURLOPT_FORBID_REUSE
CURLOPT_FRESH_CONNECT
CURLOPT_FTPAPPEND
CURLOPT_FTPASCII
CURLOPT_FTPLISTONLY
CURLOPT_FTPPORT
CURLOPT_HEADER
CURLOPT_HEADERFUNCTION
CURLOPT_HTTPGET
CURLOPT_HTTPHEADER
CURLOPT_HTTPPOST
CURLOPT_HTTPPROXYTUNNEL
@@ -40,6 +50,8 @@ CURLOPT_INTERFACE
CURLOPT_KRB4LEVEL
CURLOPT_LOW_SPEED_LIMIT
CURLOPT_LOW_SPEED_TIME
CURLOPT_MAXCONNECTS
CURLOPT_MAXREDIRS
CURLOPT_MUTE
CURLOPT_NETRC
CURLOPT_NOBODY
@@ -59,6 +71,7 @@ CURLOPT_PROXYPORT
CURLOPT_PROXYUSERPWD
CURLOPT_PUT
CURLOPT_QUOTE
CURLOPT_RANDOM_FILE
CURLOPT_RANGE
CURLOPT_READFUNCTION
CURLOPT_REFERER
@@ -66,7 +79,11 @@ CURLOPT_RESUME_FROM
CURLOPT_SSLCERT
CURLOPT_SSLCERTPASSWD
CURLOPT_SSLVERSION
CURLOPT_SSL_CIPHER_LIST
CURLOPT_SSL_VERIFYHOST
CURLOPT_SSL_VERIFYPEER
CURLOPT_STDERR
CURLOPT_TELNETOPTIONS
CURLOPT_TIMECONDITION
CURLOPT_TIMEOUT
CURLOPT_TIMEVALUE
@@ -78,17 +95,7 @@ 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
CURLOPT_WRITEINFO
CURLINFO_EFFECTIVE_URL
CURLINFO_HTTP_CODE
@@ -110,7 +117,7 @@ CURLINFO_CONTENT_LENGTH_UPLOAD
USE_INTERNAL_VARS
);
$VERSION = '1.1.5';
$VERSION = '1.1.8';
$Curl::easy::headers = "";
$Curl::easy::content = "";
@@ -133,25 +140,31 @@ bootstrap Curl::easy $VERSION;
__END__
# Below is the stub of documentation for your module. You better edit it!
=pod
=head1 NAME
Curl::easy - Perl extension for libcurl
=head1 SYNOPSIS
use Curl::easy;
use Curl::easy;
$curl = Curl::easy::init();
$CURLcode = Curl::easy::setopt($curl, CURLoption, Value);
$CURLcode = Curl::easy::perform($curl);
Curl::easy::cleanup($curl);
$curl = Curl::easy::init();
$CURLcode = Curl::easy::setopt($curl, CURLoption, Value);
$CURLcode = Curl::easy::perform($curl);
Curl::easy::cleanup($curl);
Read curl_easy_setopt for details of most CURLoption values
=head1 DESCRIPTION
=head1 DESCRIPTION
This perl module provides an interface to the libcurl C library. See
B<Curl::easy> provides an interface to the libcurl C library. See
http://curl.haxx.se/ for more information on cURL and libcurl.
=head1 FILES and CALLBACKS
=head2 FILES and CALLBACKS
Curl::easy supports the various options of curl_easy_setopt which require either a FILE * or
a callback function.
@@ -254,9 +267,20 @@ indicate an error.
Georg Horn <horn@koblenz-net.de>
Additional callback,pod and tes work by Cris Bailiff <c.bailiff@devsecure.com>
Additional callback, pod and test work by Cris Bailiff <c.bailiff@devsecure.com>
and Forrest Cahoon <forrest.cahoon@merrillcorp.com>
Currently maintained by Cris Bailiff <c.bailiff@devsecure.com>
=head1 Copyright
Copyright (C) 2000, Daniel Stenberg, , et al.
You may opt to use, copy, modify, merge, publish, distribute and/or sell
copies of the Software, and permit persons to whom the Software is furnished
to do so, under the terms of the MPL or the MIT/X-derivate licenses. You may
pick one of these licenses.
=head1 SEE ALSO
http://curl.haxx.se/

View File

@@ -1,4 +1,12 @@
/* Perl interface for libcurl. Check out the file README for more info. */
/*
Copyright (C) 2000, Daniel Stenberg, , et al.
You may opt to use, copy, modify, merge, publish, distribute and/or
sell copies of the Software, and permit persons to whom the
Software is furnished to do so, under the terms of the MPL or
the MIT/X-derivate licenses. You may pick one of these licenses.
*/
#include "EXTERN.h"
#include "perl.h"
@@ -101,12 +109,14 @@ fwrite_wrapper (const void *ptr,
if (stream == stdout) {
sv = newSViv(0); /* FIXME: should cast stdout to GLOB somehow? */
} else { /* its already an SV */
} else if (stream == NULL) {
sv = &PL_sv_undef;
} else { /* its already an SV */
sv = stream;
}
if (ptr != NULL) {
XPUSHs(sv_2mortal(newSVpvn(ptr, size * nmemb)));
XPUSHs(sv_2mortal(newSVpvn((char *)ptr, (STRLEN)(size * nmemb))));
} else {
XPUSHs(sv_2mortal(newSVpv("", 0)));
}
@@ -130,15 +140,20 @@ fwrite_wrapper (const void *ptr,
} else {
/* default to a normal 'fwrite' */
/* stream could be a FILE * or an SV * */
/* or NULL since libcurl-7.8.1pre3 */
FILE *f;
if (stream == stdout) { /* the only possible FILE ? Think so */
if (stream == stdout ||
stream == NULL) { /* 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);
if (f)
return fwrite(ptr, size, nmemb, f);
else
return (size_t) size*nmemb;
}
}
@@ -422,123 +437,7 @@ constant(char *name, int arg)
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;
#include "curlopt-constants.c"
}
}
if (strEQ(name, "USE_INTERNAL_VARS")) return USE_INTERNAL_VARS;

View File

@@ -0,0 +1,48 @@
# Test script for Perl extension Curl::easy.
# Check out the file README for more info.
use strict;
use Curl::easy;
my $url = "http://curl.haxx.se/dev/";
print "Testing curl version ",&Curl::easy::version(),"\n";
# Init the curl session
my $curl= Curl::easy::init();
if(!$curl) {
die "curl init failed!\n";
}
# Follow location headers
Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
# Add some additional headers to the http-request:
my @myheaders;
$myheaders[0] = "I-am-a-silly-programmer: yes indeed you are";
$myheaders[1] = "User-Agent: Perl interface for libcURL";
Curl::easy::setopt($curl, Curl::easy::CURLOPT_HTTPHEADER, \@myheaders);
my $errbuf;
Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "errbuf");
Curl::easy::setopt($curl, CURLOPT_URL, $url);
sub body_callback {
my ($chunk,$handle)=@_;
push @$handle, $chunk;
return length($chunk); # OK
}
Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&body_callback);
my @body;
Curl::easy::setopt($curl, CURLOPT_FILE, \@body);
if (Curl::easy::perform($curl) != 0) {
print "Failed :$errbuf\n";
};
# Cleanup
Curl::easy::cleanup($curl);
print @body;

View File

@@ -0,0 +1,38 @@
# 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 thisfile.t'
######################### 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..2\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):
my $count=1;
print STDERR "Testing curl version ",&Curl::easy::version(),"\n";
if (CURLOPT_URL != 10000+2) {
print "not ";
}
print "ok ".++$count;
exit;

View File

@@ -0,0 +1,93 @@
# 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 t/thisfile.t'. After `make install' it should work as `perl thisfile.t'
######################### We start with some black magic to print on failure.
# Change 1..1 below to 1..last_test_to_print .
use strict;
BEGIN { $| = 1; print "1..6\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):
my $count=1;
# Read URL to get
my $defurl = "http://localhost/cgi-bin/printenv";
my $url;
if (defined ($ENV{CURL_TEST_URL})) {
$url=$ENV{CURL_TEST_URL};
} else {
$url = "";
print "Please enter an URL to fetch [$defurl]: ";
$url = <STDIN>;
if ($url =~ /^\s*\n/) {
$url = $defurl;
}
}
# Init the curl session
my $curl = Curl::easy::init();
if ($curl == 0) {
print "not ";
}
print "ok ".++$count."\n";
Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
Curl::easy::setopt($curl, CURLOPT_MUTE, 1);
Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
open HEAD, ">head.out";
Curl::easy::setopt($curl, CURLOPT_WRITEHEADER, *HEAD);
print "ok ".++$count."\n";
open BODY, ">body.out";
Curl::easy::setopt($curl, CURLOPT_FILE,*BODY);
print "ok ".++$count."\n";
my $errbuf;
Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "errbuf");
print "ok ".++$count."\n";
Curl::easy::setopt($curl, CURLOPT_URL, $url);
print "ok ".++$count."\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, CURLOPT_HTTPHEADER, \@myheaders);
my $bytes;
my $realurl;
my $httpcode;
# Go get it
my $retcode=Curl::easy::perform($curl);
if ($retcode == 0) {
Curl::easy::getinfo($curl, CURLINFO_SIZE_DOWNLOAD, $bytes);
print STDERR "$bytes bytes read ";
Curl::easy::getinfo($curl, CURLINFO_EFFECTIVE_URL, $realurl);
Curl::easy::getinfo($curl, CURLINFO_HTTP_CODE, $httpcode);
print STDERR "effective fetched url (http code: $httpcode) was: $url ";
} else {
# We can acces the error message in $errbuf here
print STDERR "$retcode / '$errbuf'\n";
print "not ";
}
print "ok ".++$count."\n";
exit;

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