Compare commits

...

73 Commits

Author SHA1 Message Date
Daniel Stenberg
d2174da641 7.10.2 2002-11-18 22:10:06 +00:00
Daniel Stenberg
255b1e68d0 as requested, CURLE_OPERATION_TIMEDOUT is now the same as
CURLE_OPERATION_TIMEOUTED
2002-11-18 21:58:46 +00:00
Daniel Stenberg
fbee6b87f5 fflush() the trace stream on each call 2002-11-15 14:15:28 +00:00
Daniel Stenberg
3836a70f97 removed nroff mistake 2002-11-15 14:13:46 +00:00
Daniel Stenberg
e0ec9fa294 no more dllinit.o usage 2002-11-15 14:13:05 +00:00
Daniel Stenberg
80fe50590f recent fixes 2002-11-15 14:11:45 +00:00
Daniel Stenberg
ae18d1c55a attempts to filter off optimize flags when --enable-debug is used 2002-11-15 14:11:20 +00:00
Daniel Stenberg
75194373e0 language 2002-11-14 09:55:00 +00:00
Daniel Stenberg
f3875048f6 clarified that strings need to be kept around until the handle is closed or
until the pointers are set to another value
2002-11-14 09:54:10 +00:00
Daniel Stenberg
210af986ad dllinit.c is removed 2002-11-13 22:16:44 +00:00
Daniel Stenberg
c03044f492 not used and we don't have permission to distribute this! 2002-11-13 22:16:16 +00:00
Daniel Stenberg
522b85ae21 4.11 Why does my HTTP range requests return the full document? 2002-11-12 20:00:02 +00:00
Daniel Stenberg
208e56dbe9 removed dllinit.c as MSVC doesn't need it 2002-11-12 08:15:38 +00:00
Daniel Stenberg
42acb00c81 moved the bools in the connectdata struct into the substruct named
ConnectBits where the other bools already are
2002-11-11 23:03:03 +00:00
Daniel Stenberg
ca6e770837 The test for DNS cache entries left locked is now only built if
AGGRESIVE_TEST is also defined, as an addition to MALLOCDEBUG. It doesn't
work for multi interface usage and should only be used with careful
consideration.
2002-11-11 22:51:09 +00:00
Daniel Stenberg
775968003c changed header 2002-11-11 22:41:45 +00:00
Daniel Stenberg
323d3e9b5d include SSLCERTS and not UPGRADE. We leave UPGRADE a while in CVS, but it
should be removed soonish.
2002-11-11 22:38:32 +00:00
Daniel Stenberg
16f9755e73 UPGRADE was renamed into this "SSLCERTS" 2002-11-11 22:37:59 +00:00
Daniel Stenberg
66eb98bb0a unlock dns cache entries with a function call instead of a variable fiddle 2002-11-11 22:36:00 +00:00
Daniel Stenberg
299546f5c0 Dave Halbakken added curl_version_info 2002-11-11 21:57:14 +00:00
Daniel Stenberg
7be9b4c418 transfer-encoding: chunked was implemented 2002-11-11 10:00:48 +00:00
Daniel Stenberg
03c22b4576 Now supports "Transfer-Encoding: chunked" for HTTP PUT operations where the
size of the uploaded file is unknown.
2002-11-11 08:40:37 +00:00
Daniel Stenberg
ef749fa9ce Bug report #634625 identified how curl returned timeout immediately when
CURLOPT_CONNECTTIMEOUT was used and provided a fix.
2002-11-07 08:45:10 +00:00
Daniel Stenberg
a23c92596e recent changes 2002-11-06 08:30:08 +00:00
Daniel Stenberg
abb1497c98 output all test case numbers with three digits 2002-11-06 08:29:48 +00:00
Daniel Stenberg
7a8594da43 language fix 2002-11-06 08:29:26 +00:00
Daniel Stenberg
cbf28daed9 Lehel Bernadt's fix to prevent debug message to get sent on errors when
debug wasn't enabled
2002-11-05 11:11:10 +00:00
Daniel Stenberg
0ff1ca30c3 ipv4-fixes for the new Curl_dns_entry struct and Curl_resolv() proto 2002-11-05 11:07:49 +00:00
Daniel Stenberg
2cff251863 Curl_resolv() now returns a different struct, and it contains a reference
counter so that the caller needs to decrease that counter when done with
the returned data.

If compiled with MALLOCDEBUG I've added some extra checking that the counter
is decreased before a handle is closed etc.
2002-11-05 10:51:41 +00:00
Daniel Stenberg
73d996bf26 Soren Spies filled in some info about Mac OS X 10.2 2002-10-31 13:25:03 +00:00
Daniel Stenberg
5bc78cb724 Disable the DNS cache (by setting the timeout to 0) made libcurl leak
memory. Avery Fay brought the example code that proved this.
2002-10-31 13:09:11 +00:00
Daniel Stenberg
cdba92ac3c when using checkprefix(), the first argument must be the prefix! 2002-10-28 22:19:23 +00:00
Daniel Stenberg
6d28f92ffe Transfer-Encoding: needs 17 bytes passed, not 18 2002-10-28 21:52:27 +00:00
Daniel Stenberg
01387f42c5 kromJx@crosswinds.net's fix that now uses checkprefix() instead of
strnequal() when the third argument was strlen(first argument) anyway.
This makes it less prone to errors. (Slightly edited by me)
2002-10-28 21:52:00 +00:00
Daniel Stenberg
8f52b731f4 the malloc debug system assumes single thread 2002-10-28 21:05:14 +00:00
Daniel Stenberg
d442088ed3 kromJx@crosswinds.net fixed typos 2002-10-28 20:58:28 +00:00
Daniel Stenberg
22a323890a works now with autoconf 2.54 2002-10-28 20:39:23 +00:00
Daniel Stenberg
163bba1410 Kevin Roth's patch that checks for the CA cert file at two more places if the
--cacert option is not used.

1. An environment variable named CURL_CA_BUNDLE may contain the full file
name to the file.

2. On Windows, the cert file may be named curl-ca-bundle.crt and put in the
same dir as curl is located (or the CWD) and curl will then use that file
instead.
2002-10-28 19:49:58 +00:00
Daniel Stenberg
db1c618fcf Kevin Roth's patch. $(RM) instead of @erase, and it also passes on the
USE_SSLEAY variable
2002-10-28 19:39:58 +00:00
Daniel Stenberg
01bdfa7b6d Kevin Roth's fixes that use $(RM) instead of @erase and modified SSL version 2002-10-28 19:38:46 +00:00
Daniel Stenberg
6a88c8d845 prevent compiler warning 2002-10-28 19:21:30 +00:00
Daniel Stenberg
b8a6913e09 prevent compiler warnings 2002-10-28 19:20:59 +00:00
Daniel Stenberg
744d8c1006 fixes 2002-10-28 19:17:49 +00:00
Daniel Stenberg
c2e2c98d81 fixed the cygwin check for -no-undefined 2002-10-23 14:45:28 +00:00
Daniel Stenberg
3fa353a2d3 improved the check for an ISO cpp by checking specificly for __BORLANDC__
too, as Emiliano Ida has confirmed it to work
2002-10-23 14:15:29 +00:00
Daniel Stenberg
c27c9f80d2 kromJx@crosswinds.net made it run properly with stunnel >=4.0 2002-10-23 14:07:34 +00:00
Daniel Stenberg
b5a74715cf bad headers can come in two kinds, we either treat everything as one big
badly assumed header, or we think that parts of the buffer is a bad header
and the rest is treated as a normal body part
2002-10-23 13:48:37 +00:00
Daniel Stenberg
13ee2901f4 another week, 7 fixes 2002-10-21 14:04:26 +00:00
Daniel Stenberg
32c03eadd6 glibc 2.2.93 gethostbyname_r() no longer returns ERANGE if the given buffer
size isn't big enough. For some reason they now return EAGAIN.

Redhat 8 ships with this glibc version.
2002-10-21 13:20:30 +00:00
Daniel Stenberg
0fa512f26d Nikita Schmidt's fix to debian bug report #165382. This is verified with
the new test case 55.
2002-10-21 12:07:02 +00:00
Daniel Stenberg
219d88518c Added test 55, follow location with a single slash in the original path.
This caused curl 7.10.1 to crash.
2002-10-21 12:02:44 +00:00
Daniel Stenberg
ecf3aee43a check for cygwin and if built on that, enable the no-undefined option for
libtool. Otherwise disable it.
2002-10-21 06:49:42 +00:00
Daniel Stenberg
7f08cab73e test 54 added, blank Location: field 2002-10-21 06:18:51 +00:00
Daniel Stenberg
c4e9ef199e --enable-debug now checks if gcc is used before it sets all those gcc-
specific options. This should make this option work on more platforms with
other compilers.
2002-10-21 05:52:05 +00:00
Daniel Stenberg
9e612b5550 make very sure that we return 'done' properly when a transfer is done, as
otherwise the multi interface gets problems
2002-10-18 15:28:33 +00:00
Daniel Stenberg
203633d34d return call_multi when we follow a location 2002-10-18 15:27:49 +00:00
Daniel Stenberg
45bd009bb1 if we found no string on the Location: line, don't try to follow it 2002-10-18 13:51:00 +00:00
Daniel Stenberg
ee656415c4 moved comments to first column and automake stopped complaining 2002-10-18 07:55:38 +00:00
Daniel Stenberg
156aad198f Make the COOKIESESSION work better by creating a list of cookie files files
when given in the curl_easy_setopt() and then parse them all on the first
curl_easy_perform() call instead.
2002-10-17 07:10:39 +00:00
Daniel Stenberg
b1ffb79a50 junk cookies test53 added 2002-10-17 07:03:26 +00:00
Daniel Stenberg
d6654bfe00 mucho fixed 2002-10-16 09:53:38 +00:00
Daniel Stenberg
eefdd67d22 Added new mirror 2002-10-15 14:18:31 +00:00
Daniel Stenberg
86a86d7afd Andrs Garca's corrections 2002-10-15 08:39:30 +00:00
Daniel Stenberg
b6dac2b484 ignore .ps and .pdf files too 2002-10-14 07:47:40 +00:00
Daniel Stenberg
e6367abae9 generate and include PDF versions of the docs in the release archive 2002-10-14 07:39:49 +00:00
Daniel Stenberg
fc4d1d9a60 my first take at a memory leak detection document 2002-10-13 10:34:33 +00:00
Daniel Stenberg
94bae20776 some more 2002-10-13 10:28:38 +00:00
Daniel Stenberg
bb8c8d273c added more info 2002-10-13 10:18:10 +00:00
Daniel Stenberg
ee600ace37 three silly bugs 2002-10-12 12:35:30 +00:00
Daniel Stenberg
da86e32eb4 -y and -Y was switched in the examples 2002-10-12 12:14:09 +00:00
Daniel Stenberg
b5bbc04ad1 return error properly when a non-blocking connect fails using the multi
interface
2002-10-12 11:18:08 +00:00
Daniel Stenberg
265c58611f When we receive a "bad header" we must sure not to write down the data part
as well, as then we write the same data twice.
2002-10-11 20:55:08 +00:00
Daniel Stenberg
25c973a39e fix bad free() that caused segfault 2002-10-11 17:44:36 +00:00
59 changed files with 1297 additions and 563 deletions

110
CHANGES
View File

@@ -7,6 +7,114 @@
Changelog
Version 7.10.2 (18 Nov 2002)
Daniel (11 Nov 2002)
- Dave Halbakken added curl_version_info to lib/libcurl.def to make libcurl
properly build with MSVC on Windows.
Daniel (8 Nov 2002)
- Doing HTTP PUT without a specified file size now makes libcurl use
Transfer-Encoding: chunked.
Daniel (7 Nov 2002)
- Bug report #634625 identified how curl returned timeout immediately when
CURLOPT_CONNECTTIMEOUT was used and provided a fix.
Version 7.10.2-pre4 (6 Nov 2002)
Daniel (5 Nov 2002)
- Lehel Bernadt found out and fixed. libcurl sent error message to the debug
output when it stored the error message.
- Avery Fay found some problems with the DNS cache (when the cache time was
set to 0 we got a memory leak, but when the leak was fixed he got a crash
when he used the CURLOPT_INTERFACE with that) that had me do some real
restructuring so that we now have a reference counter in the dns cache
entries to prevent an entry to get flushed while still actually in use.
I also detected that we previously didn't update the time stamp when we
extracted an entry from the cache so that must've been a reason for some
very weird dns cache bugs.
Version 7.10.2-pre3
Daniel (31 Oct 2002)
- Downgraded automake to 1.6.3 in an attempt to fix cygwin problems. (It
turned out this didn't help though.)
- Disable the DNS cache (by setting the timeout to 0) made libcurl leak
memory. Avery Fay brought the example code that proved this.
Version 7.10.2-pre2
Daniel (28 Oct 2002)
- Upgraded to autoconf 2.54 and automake 1.7 on the release-build host.
- Kevin Roth made the command line tool check for a CURL_CA_BUNDLE environment
variable (if --cacert isn't used) and if not set, the Windows version will
check for a file named "curl-ca-bundle.crt" in the current directory or the
directory where curl is located. That file is then used as CA root cert
bundle.
- Avery Fay pointed out that curl's configure scrip didn't get right if you
used autoconf newer than 2.52. This was due to some badly quoted code.
Version 7.10.2-pre1
Daniel (23 Oct 2002)
- Emiliano Ida confirmed that we now build properly with the Borland C++
compiler too. We needed yet another fix for the ISO cpp check in the curl.h
header file.
- Yet another fix was needed to get the HTTP download without headers to work.
This time it was needed if the first "believed header" was read all in the
first read. Test 306 has not run properly since the 11th october fix.
Daniel (21 Oct 2002)
- Zvi Har'El pointed out a problem with curl's name resolving on Redhat 8
machines (running IPv6 disabled). Mats Lidell let me use an account on his
machine and I could verify that gethostbyname_r() has been changed to return
EAGAIN instead of ERANGE when the given buffer size is too small. This is
glibc 2.2.93.
- Albert Chin helped me get the -no-undefined option corrected in
lib/Makefile.am since Cygwin builds want it there while Solaris builds don't
want it present. Kevin Roth helped me try it out on cygwin.
- Nikita Schmidt provided a bug fix for a FOLLOWLOCATION bug introduced when
the ../ support got in (7.10.1).
Daniel (18 Oct 2002)
- Fabrizio Ammollo pointed out a remaining problem with FOLLOWLOCATION in
the multi interface.
Daniel (17 Oct 2002)
- Richard Cooper's experimenting proved that -j (CURLOPT_COOKIESESSION) didn't
work quite as supposed. You needed to set it *before* you use
CURLOPT_COOKIEFILE, and we dont' want that kind of dependencies.
Daniel (15 Oct 2002)
- Andr<64>s Garc<72>a provided corrections for erratas in four libcurl man pages.
Daniel (13 Oct 2002)
- Starting now, we generate and include PDF versions of all the docs in the
release archives.
Daniel (12 Oct 2002)
- Trying to connect to a host on a bad port number caused the multi interface
to never return failure and it appeared to keep on trying forever (it just
didn't do anything).
Daniel (11 Oct 2002)
- Downloading HTTP without headers didn't work 100%, some of the initial data
got written twice. Kevin Roth reported.
- Kevin Roth found out the "config file" parser in the client code could
segfault, like if DOS newlines were used.
Version 7.10.1 (11 Oct 2002)
Daniel (10 Oct 2002)
- Jeff Lawson fixed a few problems with connection re-use that remained when
you set CURLOPT_PROXY to "".
@@ -31,7 +139,7 @@ Daniel (7 Oct 2002)
- Kevin Roth pointed out that make install didn't do right if build outside
the source tree (ca-bundle wise).
- FOLLOW_LOCATION bugfix for the multi interface
- FOLLOWLOCATION bugfix for the multi interface
Daniel (4 Oct 2002)
- Kevin Roth got problems with his cygwin build with -no-undefined was not

View File

@@ -48,7 +48,9 @@ REQUIREMENTS
MAC OS X
For Mac OS X users, Guido Neitzer write down the following step-by-step guide:
With Mac OS X 10.2 and the associated Developer Tools, the installed versions
of the build tools are adequate. For Mac OS X 10.1 users, Guido Neitzer
wrote the following step-by-step guide:
1. Install fink (http://fink.sourceforge.net)
2. Update fink to the newest version (with the installed fink)

View File

@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = CHANGES COPYING maketgz UPGRADE reconf Makefile.dist \
EXTRA_DIST = CHANGES COPYING maketgz SSLCERTS reconf Makefile.dist \
curl-config.in build_vms.com curl-mode.el
bin_SCRIPTS = curl-config
@@ -18,6 +18,9 @@ dist-hook:
html:
cd docs; make html
pdf:
cd docs; make pdf
check: test
test:

5
README
View File

@@ -19,16 +19,19 @@ README
Study the LEGAL file for distribution terms and similar.
Visit the curl web site or mirror for the latest news:
Visit the curl web site or mirrors for the latest news:
http://curl.haxx.se/
http://curl.sf.net/
http://curl.planetmirror.com/
The official download mirror sites are:
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Sweden -- http://cool.haxx.se/curl/
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
Australia -- http://curl.planetmirror.com/pub/curl/
US -- http://curl.sourceforge.net/download.html
To download the very latest source off the CVS server do this:

35
SSLCERTS Normal file
View File

@@ -0,0 +1,35 @@
Peer SSL Certificate Verification
=================================
Starting in 7.10, libcurl performs peer SSL certificate verification by
default. This is done by installing a default CA cert bundle on 'make install'
(or similar), that CA bundle package is used by default on operations against
SSL servers.
Alas, if you communicate with HTTPS servers using certifcates that are signed
by CAs present in the bundle, you will not notice any changed behavior and you
will seeminglessly get a higher security level on your SSL connections since
can be sure that the remote server really is the one it claims to be.
If the remote server uses a self-signed certificate, or if you don't install
curl's CA cert bundle or if it uses a certificate signed by a CA that isn't
included in the bundle, then you need to do one of the following:
1. Tell libcurl to *not* verify the peer. With libcurl you disable with with
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
With the curl command tool, you disable this with -k/--insecure.
2. Get a CA certificate that can verify the remote server and use the proper
option to point out this CA cert for verification when connecting. For
libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);
With the curl command tool: --cacert [file]
This upgrade procedure has been deemed The Right Thing even though it adds
this extra trouble for some users, since it adds security to a majority of the
SSL connections that previously weren't really secure.
It turned out many people were using previous versions of curl/libcurl without
realizing the need for the CA cert options to get truly secure SSL
connections.

View File

@@ -34,7 +34,7 @@ dnl
AC_CANONICAL_HOST
dnl Get system canonical name
AC_DEFINE_UNQUOTED(OS, "${host}")
AC_DEFINE_UNQUOTED(OS, "${host}", [cpu-machine-OS])
dnl Check for AIX weirdos
AC_AIX
@@ -51,6 +51,17 @@ AC_LIBTOOL_WIN32_DLL
dnl libtool setup
AM_PROG_LIBTOOL
case $host in
*-*-cygwin | *-*-mingw* | *-*-pw32*)
need_no_undefined=yes
;;
*)
need_no_undefined=no
;;
esac
AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET
@@ -65,9 +76,9 @@ AC_ARG_ENABLE(http,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_HTTP)
AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP])
AC_MSG_WARN([disable HTTP disables FTP over proxy and GOPHER too])
AC_DEFINE(CURL_DISABLE_GOPHER)
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
AC_SUBST(CURL_DISABLE_HTTP)
AC_SUBST(CURL_DISABLE_GOPHER)
;;
@@ -83,7 +94,7 @@ AC_ARG_ENABLE(ftp,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_FTP)
AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP])
AC_SUBST(CURL_DISABLE_FTP)
;;
*) AC_MSG_RESULT(yes)
@@ -98,7 +109,7 @@ AC_ARG_ENABLE(gopher,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_GOPHER)
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
AC_SUBST(CURL_DISABLE_GOPHER)
;;
*) AC_MSG_RESULT(yes)
@@ -113,7 +124,7 @@ AC_ARG_ENABLE(file,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_FILE)
AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE])
AC_SUBST(CURL_DISABLE_FILE)
;;
*) AC_MSG_RESULT(yes)
@@ -128,7 +139,7 @@ AC_ARG_ENABLE(ldap,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_LDAP)
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
AC_SUBST(CURL_DISABLE_LDAP)
;;
*) AC_MSG_RESULT(yes)
@@ -143,7 +154,7 @@ AC_ARG_ENABLE(dict,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_DICT)
AC_DEFINE(CURL_DISABLE_DICT, 1 [to disable DICT])
AC_SUBST(CURL_DISABLE_DICT)
;;
*) AC_MSG_RESULT(yes)
@@ -158,7 +169,7 @@ AC_ARG_ENABLE(telnet,
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_TELNET)
AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET])
AC_SUBST(CURL_DISABLE_TELNET)
;;
*) AC_MSG_RESULT(yes)
@@ -215,11 +226,11 @@ dnl Checks for libraries.
dnl **********************************************************************
dnl gethostbyname in the nsl lib?
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNC(gethostbyname, , [ AC_CHECK_LIB(nsl, gethostbyname) ])
if test "$ac_cv_lib_nsl_gethostbyname" != "yes" -a "$ac_cv_func_gethostbyname" != "yes"; then
dnl gethostbyname in the socket lib?
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(socket, gethostbyname))
AC_CHECK_FUNC(gethostbyname, , [ AC_CHECK_LIB(socket, gethostbyname) ])
fi
dnl At least one system has been identified to require BOTH nsl and
@@ -244,7 +255,7 @@ if test "$ac_cv_lib_nsl_gethostbyname" = "$ac_cv_func_gethostbyname"; then
fi
dnl resolve lib?
AC_CHECK_FUNC(strcasecmp, , AC_CHECK_LIB(resolve, strcasecmp))
AC_CHECK_FUNC(strcasecmp, , [ AC_CHECK_LIB(resolve, strcasecmp) ])
if test "$ac_cv_lib_resolve_strcasecmp" = "$ac_cv_func_strcasecmp"; then
AC_CHECK_LIB(resolve, strcasecmp,
@@ -254,10 +265,10 @@ if test "$ac_cv_lib_resolve_strcasecmp" = "$ac_cv_func_strcasecmp"; then
fi
dnl socket lib?
AC_CHECK_FUNC(connect, , AC_CHECK_LIB(socket, connect))
AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ])
dnl dl lib?
AC_CHECK_FUNC(dlclose, , AC_CHECK_LIB(dl, dlopen))
AC_CHECK_FUNC(dlclose, , [ AC_CHECK_LIB(dl, dlopen) ])
dnl **********************************************************************
dnl Check how non-blocking sockets are set
@@ -268,7 +279,8 @@ AC_ARG_ENABLE(nonblocking,
[
if test "$enableval" = "no" ; then
AC_MSG_WARN([non-blocking sockets disabled])
AC_DEFINE(HAVE_DISABLED_NONBLOCKING)
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
[to disable NON-BLOCKING connections])
else
CURL_CHECK_NONBLOCKING_SOCKET
fi
@@ -286,7 +298,8 @@ AC_ARG_WITH(egd-socket,
[ EGD_SOCKET="$withval" ]
)
if test -n "$EGD_SOCKET" ; then
AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET")
AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET",
[your Entropy Gathering Daemon socket pathname] )
fi
dnl Check for user-specified random device
@@ -295,16 +308,13 @@ AC_ARG_WITH(random,
[ RANDOM_FILE="$withval" ],
[
dnl Check for random device
AC_CHECK_FILE("/dev/urandom",
[
RANDOM_FILE="/dev/urandom";
]
)
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
]
)
if test -n "$RANDOM_FILE" ; then
AC_SUBST(RANDOM_FILE)
AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE")
AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE",
[a suitable file to read random data from])
fi
dnl **********************************************************************
@@ -366,7 +376,7 @@ then
AC_CHECK_HEADERS(des.h)
dnl resolv lib?
AC_CHECK_FUNC(res_search, , AC_CHECK_LIB(resolv, res_search))
AC_CHECK_FUNC(res_search, , [AC_CHECK_LIB(resolv, res_search)])
dnl Check for the Kerberos4 library
AC_CHECK_LIB(krb, krb_net_read,
@@ -382,7 +392,8 @@ then
AC_CHECK_FUNCS(krb_get_our_ip_for_realm)
dnl add define KRB4
AC_DEFINE(KRB4)
AC_DEFINE(KRB4, 1,
[if you have the Kerberos4 libraries (including -ldes)])
dnl substitute it too!
KRB4_ENABLED=1
@@ -483,7 +494,7 @@ else
dnl If the ENGINE library seems to be around, check for the OpenSSL engine
dnl header, it is kind of "separated" from the main SSL check
AC_CHECK_FUNC(ENGINE_init, AC_CHECK_HEADERS(openssl/engine.h))
AC_CHECK_FUNC(ENGINE_init, [ AC_CHECK_HEADERS(openssl/engine.h) ])
AC_SUBST(OPENSSL_ENABLED)
@@ -675,7 +686,7 @@ if test "$ac_cv_func_sigsetjmp" != "yes"; then
[sigjmp_buf jmpenv;
sigsetjmp(jmpenv, 1);],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SIGSETJMP),
AC_DEFINE(HAVE_SIGSETJMP, 1, [If you have sigsetjmp]),
AC_MSG_RESULT(no)
)
fi
@@ -743,7 +754,12 @@ AC_ARG_ENABLE(debug,
*) AC_MSG_RESULT(yes)
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
CFLAGS="-W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs -g"
CFLAGS="$CFLAGS -g"
if test "$GCC" = "yes"; then
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs"
fi
dnl strip off optimizer flags
CFLAGS=`echo $CFLAGS | sed -e 's/-O[0-9 ]//g'`
;;
esac ],
AC_MSG_RESULT(no)

View File

@@ -1,3 +1,5 @@
Makefile
Makefile.in
*html
*ps
*pdf

View File

@@ -1,4 +1,4 @@
Updated: October 8, 2002 (http://curl.haxx.se/docs/faq.html)
Updated: November 12, 2002 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -58,6 +58,7 @@ FAQ
4.8 I found a bug!
4.9 Curl can't authenticate to the server that requires NTLM?
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
4.11 Why does my HTTP range requests return the full document?
5. libcurl Issues
5.1 Is libcurl thread-safe?
@@ -601,6 +602,10 @@ FAQ
software you're trying to interact with. This is not anything curl can do
anything about.
4.11 Why does my HTTP range requests return the full document?
Because the range may not be supported by the server, or the server may
choose to ignore it and return the full document anyway.
5. libcurl Issues

View File

@@ -4,7 +4,7 @@
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
How cURL Become Like This
How cURL Became Like This
In the second half of 1997, Daniel Stenberg came up with the idea to make
@@ -58,8 +58,8 @@ visits daily.
Released curl 6.0 in September. 15000 lines of code.
December 28 1999, added project to Sourceforge and started using its services
for managing the project.
December 28 1999, added the project on Sourceforge and started using its
services for managing the project.
Spring 2000, major internal overhaul to provide a suitable library interface.
The first non-beta release was named 7.1 and arrived in August. This offered

View File

@@ -404,12 +404,28 @@ SPEED LIMIT
To have curl abort the download if the speed is slower than 3000 bytes per
second for 1 minute, run:
curl -y 3000 -Y 60 www.far-away-site.com
curl -Y 3000 -y 60 www.far-away-site.com
This can very well be used in combination with the overall time limit, so
that the above operatioin must be completed in whole within 30 minutes:
curl -m 1800 -y 3000 -Y 60 www.far-away-site.com
curl -m 1800 -Y 3000 -y 60 www.far-away-site.com
Forcing curl not to transfer data faster than a given rate is also possible,
which might be useful if you're using a limited bandwidth connection and you
don't want your transfer to use all of it.
Make curl transfer data no faster than 10 kilobytes per second:
curl --limit-rate 10K www.far-away-site.com
or
curl --limit-rate 10240 www.far-away-site.com
Or prevent curl from uploading data faster than 1 megabyte per second:
curl -T upload --limit-rate 1M ftp://uploadshereplease.com
CONFIG FILE
@@ -548,7 +564,7 @@ HTTPS
from sites that require valid certificates. The only drawback is that the
certificate needs to be in PEM-format. PEM is a standard and open format to
store certificates with, but it is not used by the most commonly used
browsers (Netscape and MSEI both use the so called PKCS#12 format). If you
browsers (Netscape and MSIE both use the so called PKCS#12 format). If you
want curl to use the certificates you use with your (favourite) browser, you
may need to download/compile a converter that can convert your browser's
formatted certificates to PEM formatted ones. This kind of converter is
@@ -567,8 +583,8 @@ HTTPS
Many older SSL-servers have problems with SSLv3 or TLS, that newer versions
of OpenSSL etc is using, therefore it is sometimes useful to specify what
SSL-version curl should use. Use -3 or -2 to specify that exact SSL version
to use:
SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL
version to use (for SSLv3, SSLv2 or TLSv1 respectively):
curl -2 https://secure.site.com/
@@ -826,13 +842,13 @@ MAILING LISTS
Receives notifications on all CVS commits done to the curl source module.
This can become quite a large amount of mails during intense development,
be aware. This is for us who liks email...
be aware. This is for us who like email...
curl-www-commits
Receives notifications on all CVS commits done to the curl www module
(basicly the web site). This can become quite a large amount of mails
during intense changing, be aware. This is for us who liks email...
during intense changing, be aware. This is for us who like email...
Please direct curl questions, feature requests and trouble reports to one of
these mailing lists instead of mailing any individual.

View File

@@ -12,16 +12,20 @@ HTMLPAGES = \
curl.html \
curl-config.html
PDFPAGES = \
curl.pdf \
curl-config.pdf
SUBDIRS = examples libcurl
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
HISTORY INSTALL libcurl-the-guide
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
MAN2HTML= gnroff -man $< | man2html >$@
SUFFIXES = .1 .3 .html
SUFFIXES = .1 .3 .html .pdf
html: $(HTMLPAGES)
cd libcurl; make html
@@ -31,3 +35,13 @@ html: $(HTMLPAGES)
.1.html:
$(MAN2HTML)
MAN2PDF = groff -Tps -man curl.1 $< >$@
pdf:
for file in $(man_MANS); do \
foo=`echo $$file | sed -e 's/\.[0-9]$$//g'`; \
groff -Tps -man $$file >$$foo.ps; \
ps2pdf $$foo.ps $$foo.pdf; \
done
cd libcurl; make pdf

View File

@@ -97,11 +97,6 @@ TODO
HTTP
* 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] When the filter
system mentioned above gets real, it'll be a piece of cake to add.
* Pass a list of host name to libcurl to which we allow the user name and
password to get sent to. Currently, it only get sent to the host name that
the first URL uses (to prevent others from being able to read it), but this

View File

@@ -1,3 +1,5 @@
Makefile
Makefile.in
*html
*ps
*pdf

View File

@@ -75,7 +75,42 @@ HTMLPAGES = \
libcurl-errors.html \
index.html
EXTRA_DIST = $(man_MANS) $(HTMLPAGES)
PDFPAGES = \
curl_easy_cleanup.pdf \
curl_easy_getinfo.pdf \
curl_easy_init.pdf \
curl_easy_perform.pdf \
curl_easy_setopt.pdf \
curl_easy_duphandle.pdf \
curl_formadd.pdf \
curl_formparse.pdf \
curl_formfree.pdf \
curl_getdate.pdf \
curl_getenv.pdf \
curl_slist_append.pdf \
curl_slist_free_all.pdf \
curl_version.pdf \
curl_version_info.pdf \
curl_escape.pdf \
curl_unescape.pdf \
curl_free.pdf \
curl_strequal.pdf \
curl_strnequal.pdf \
curl_mprintf.pdf \
curl_global_init.pdf \
curl_global_cleanup.pdf \
libcurl.pdf \
curl_multi_add_handle.pdf \
curl_multi_cleanup.pdf \
curl_multi_fdset.pdf \
curl_multi_info_read.pdf \
curl_multi_init.pdf \
curl_multi_perform.pdf \
curl_multi_remove_handle.pdf \
libcurl-multi.pdf \
libcurl-errors.pdf
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) $(PDFPAGES)
MAN2HTML= gnroff -man $< | man2html >$@
@@ -88,3 +123,10 @@ html: $(HTMLPAGES)
.1.html:
$(MAN2HTML)
pdf:
for file in $(man_MANS); do \
foo=`echo $$file | sed -e 's/\.[0-9]$$//g'`; \
groff -Tps -man $$file >$$foo.ps; \
ps2pdf $$foo.ps $$foo.pdf; \
done

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" $Id$
.\"
.TH curl_easy_cleanup 3 "4 March 2002" "libcurl 7.7" "libcurl Manual"
.TH curl_easy_cleanup 3 "13 Nov 2002" "libcurl 7.7" "libcurl Manual"
.SH NAME
curl_easy_cleanup - End a libcurl easy session
.SH SYNOPSIS
@@ -18,6 +18,9 @@ opposite of the \fIcurl_easy_init\fP function and must be called with the same
This will effectively close all connections this handle has used and possibly
has kept open until now. Don't call this function if you intend to transfer
more files.
When you've called this, you can safely remove all the strings you've
previously told libcurl to use, as it won't use them anymore now.
.SH RETURN VALUE
None
.SH "SEE ALSO"

View File

@@ -1,8 +1,7 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" $Id$
.\"
.TH curl_easy_setopt 3 "18 Sep 2002" "libcurl 7.10" "libcurl Manual"
.TH curl_easy_setopt 3 "13 Nov 2002" "libcurl 7.10" "libcurl Manual"
.SH NAME
curl_easy_setopt - set options for a curl easy handle
.SH SYNOPSIS
@@ -23,7 +22,8 @@ curl_easy_setopt() calls in the setup phase.
\fBNOTE:\fP strings passed to libcurl as 'char *' arguments, will not be
copied by the library. Instead you should keep them available until libcurl no
longer needs them. Failing to do so will cause very odd behavior or even
crashes.
crashes. libcurl will need them until you call curl_easy_cleanup() or you set
the same option again to use a different pointer.
\fBNOTE2:\fP options set with this function call are valid for the forthcoming
data transfers that are performed when you invoke \fIcurl_easy_perform\fP.
@@ -166,7 +166,7 @@ code). (Added in 7.7.2)
.B CURLOPT_WRITEHEADER
Pass a pointer to be used to write the header part of the received data to. If
you don't use your own callback to take care of the writing, this must be a
valid FILE *. See also the \fICURLOPT_HEADERFUNCTION\fP option below on how to
valid FILE *. See also the \fICURLOPT_HEADERFUNCTION\fP option above on how to
set a custom get-all-headers callback.
.TP
.B CURLOPT_DEBUGFUNCTION
@@ -235,7 +235,7 @@ you tunnel through the HTTP proxy. Such tunneling is activated with
Pass a long with this option to set the proxy port to connect to unless it is
specified in the proxy string \fICURLOPT_PROXY\fP.
.TP
.B CURLOPT_PROXTYPE
.B CURLOPT_PROXYTYPE
Pass a long with this option to set type of the proxy. Available options for
this are CURLPROXY_HTTP and CURLPROXY_SOCKS5, with the HTTP one being
default. (Added in 7.10)
@@ -322,6 +322,12 @@ prompt function.
.PP
.SH HTTP OPTIONS
.TP 0.4i
.B CURLOPT_ENCODING
Two encodings are supported \fIdentity\fP, which does nothing, and
\fIdeflate\fP to request the server to compress its reponse using the
zlib algorithm. This is not an order, the server may or may not do it.
See the special file lib/README.encoding for details.
.TP
.B CURLOPT_FOLLOWLOCATION
A non-zero parameter tells the library to follow any Location: header that the
server sends as part of a HTTP header.
@@ -577,7 +583,7 @@ aborting perfectly normal operations. This option will cause curl to use the
SIGALRM to enable time-outing system calls.
\fBNOTE:\fP this is not recommended to use in unix multi-threaded programs, as
it uses signals unless CURLOPT_NOSIGNAL (see below) is set.
it uses signals unless CURLOPT_NOSIGNAL (see above) is set.
.TP
.B CURLOPT_LOW_SPEED_LIMIT
Pass a long as parameter. It contains the transfer speed in bytes per second
@@ -640,7 +646,7 @@ connection timeout (it will then only timeout on the system's internal
timeouts). See also the \fICURLOPT_TIMEOUT\fP option.
\fBNOTE:\fP this is not recommended to use in unix multi-threaded programs, as
it uses signals unless CURLOPT_NOSIGNAL (see below) is set.
it uses signals unless CURLOPT_NOSIGNAL (see above) is set.
.PP
.SH SSL and SECURITY OPTIONS
.TP 0.4i

View File

@@ -19,78 +19,104 @@ 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 faster.
After the \fIlastitem\fP pointer follow the real arguments. (If the following
description confuses you, jump directly to the examples):
\fBCURLFORM_COPYNAME\fP or \fBCURLFORM_PTRNAME\fP followed by a string is used
for the name of the section. Optionally one may use \fBCURLFORM_NAMELENGTH\fP
to specify the length of the name (allowing null characters within the
name). All options that use the word COPY in their names copy the given
contents, while the ones with PTR in their names simply points to the (static)
data you must make sure remain until curl no longer needs it.
The options for providing values are: \fBCURLFORM_COPYCONTENTS\fP,
\fBCURLFORM_PTRCONTENTS\fP, \fBCURLFORM_FILE\fP, \fBCURLFORM_BUFFER\fP,
or \fBCURLFORM_FILECONTENT\fP followed by a char or void pointer
(allowed for PTRCONTENTS).
\fBCURLFORM_FILECONTENT\fP does a normal post like \fBCURLFORM_COPYCONTENTS\fP
but the actual value is read from the filename given as a string.
Other arguments may be \fBCURLFORM_CONTENTTYPE\fP 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 \fBCURLFORM_PTRCONTENTS\fP or \fBCURLFORM_COPYNAME\fP the user may also
add \fBCURLFORM_CONTENTSLENGTH\fP followed by the length as a long (if not
given the library will use strlen to determine the length).
For \fBCURLFORM_FILE\fP the user may send multiple files in one section by
providing multiple \fBCURLFORM_FILE\fP arguments each followed by the filename
(and each FILE is allowed to have a CONTENTTYPE).
\fBCURLFORM_BUFFER\fP
tells libcurl that a buffer is to be used to upload data instead of using a
file. The value of the next parameter is used as the value of the "filename"
parameter in the content header.
\fBCURLFORM_BUFFERPTR\fP
tells libcurl that the address of the next parameter is a pointer to the buffer
containing data to upload. The buffer containing this data must not be freed
until after curl_easy_cleanup is called.
\fBCURLFORM_BUFFERLENGTH\fP
tells libcurl that the length of the buffer to upload is the value of the
next parameter.
Another possibility to send options to curl_formadd() is the
\fBCURLFORM_ARRAY\fP option, that passes a struct curl_forms array pointer as
its value. Each curl_forms structure element has a CURLformoption and a char
pointer. The final element in the array must be a CURLFORM_END. All available
options can be used in an array, except the CURLFORM_ARRAY option itself!
Should you need to specify extra headers for the form POST section, use
\fBCURLFORM_CONTENTHEADER\fP. This takes a curl_slist prepared in the usual way
using \fBcurl_slist_append\fP and appends the list of headers to those Curl
automatically generates for \fBCURLFORM_CONTENTTYPE\fP and the content
disposition. The list must exist while the POST occurs, if you free it before
the post completes you may experience problems.
The last argument in such an array must always be \fBCURLFORM_END\fP.
After the \fIlastitem\fP pointer follow the real arguments.
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 \fBCURLFORM_PTRNAME\fP and \fBCURLFORM_PTRCONTENTS\fP 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 \fBCURLFORM_PTRNAME\fP or
\fBCURLFORM_PTRCONTENTS\fP you must ensure that the pointer stays valid until
you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP.
First, there are some basics you need to understand about multipart/formdata
posts. Each part consists of at least a NAME and a CONTENTS part. If the part
is made for file upload, there are also a stored CONTENT-TYPE and a
FILENAME. Below here, we'll discuss on what options you use to set these
properties in the parts you want to add to your post.
.SH OPTIONS
.B CURLFORM_COPYNAME
followed by string is used to set the name of this part. libcurl copies the
given data, so your application doesn't need to keep it around after this
function call. If the name isn't zero terminated properly, or if you'd like it
to contain zero bytes, you need to set the length of the name with
\fBCURLFORM_NAMELENGTH\fP.
.B CURLFORM_PTRNAME
followed by a string is used for the name of this part. libcurl will use the
pointer and refer to the data in your application, you must make sure it
remains until curl no longer needs it. If the name isn't zero terminated
properly, or if you'd like it to contain zero bytes, you need to set the
length of the name with \fBCURLFORM_NAMELENGTH\fP.
.B CURLFORM_COPYCONTENTS
followed by a string is used for the contents of this part, the actual data to
send away. libcurl copies the given data, so your application doesn't need to
keep it around after this function call. If the data isn't zero terminated
properly, or if you'd like it to contain zero bytes, you need to set the
length of the name with \fBCURLFORM_CONTENTSLENGTH\fP.
.B CURLFORM_PTRCONTENTS
followed by a string is used for the contents of this part, the actual data to
send away. libcurl will use the pointer and refer to the data in your
application, you must make sure it remains until curl no longer needs it. If
the data isn't zero terminated properly, or if you'd like it to contain zero
bytes, you need to set the length of the name with
\fBCURLFORM_CONTENTSLENGTH\fP.
.B CURLFORM_FILECONTENT
followed by a file name, makes that file read and the contents will be used in
as data in this part.
.B CURLFORM_FILE
followed by a file name, makes this part a file upload part. It sets the file
name field to the actual file name used here, it gets the contents of the file
and passes as data and sets the content-type if the given file match one of
the new internally known file extension. For \fBCURLFORM_FILE\fP the user may
send one or more files in one part by providing multiple \fBCURLFORM_FILE\fP
arguments each followed by the filename (and each CURLFORM_FILE is allowed to
have a CURLFORM_CONTENTTYPE).
.B CURLFORM_CONTENTTYPE
followed by a pointer to a string with a content-type will make curl use this
given content-type for this file upload part, possibly instead of an
internally chosen one.
.B CURLFORM_FILENAME
followed by a pointer to a string to a name, will make libcurl use the given
name in the file upload part, intead of the actual file name given to
\fICURLFORM_FILE\fP.
.B BCURLFORM_BUFFER
followed by a string, tells libcurl that a buffer is to be used to upload data
instead of using a file. The given string is used as the value of the file
name field in the content header.
.B CURLFORM_BUFFERPTR
followed by a pointer to a data area, tells libcurl the address of the buffer
containing data to upload (as indicated with \fICURLFORM_BUFFER\fP). The
buffer containing this data must not be freed until after curl_easy_cleanup is
called.
.B CURLFORM_BUFFERLENGTH
followed by a long with the size of the \fICURLFORM_BUFFERPTR\fP data area,
tells libcurl the length of the buffer to upload.
.B CURLFORM_ARRAY
Another possibility to send options to curl_formadd() is the
\fBCURLFORM_ARRAY\fP option, that passes a struct curl_forms array pointer as
its value. Each curl_forms structure element has a CURLformoption and a char
pointer. The final element in the array must be a CURLFORM_END. All available
options can be used in an array, except the CURLFORM_ARRAY option itself! The
last argument in such an array must always be \fBCURLFORM_END\fP.
.B CURLFORM_CONTENTHEADER
specifies extra headers for the form POST section. This takes a curl_slist
prepared in the usual way using \fBcurl_slist_append\fP and appends the list
of headers to those libcurl automatically generates. The list must exist while
the POST occurs, if you free it before the post completes you may experience
problems.
When you've passed the HttpPost pointer to \fIcurl_easy_setopt\fP (using the
\fICURLOPT_HTTPPOST\fP option), you must not free the list until after you've
called \fIcurl_easy_cleanup\fP for the curl handle.
See example below.
.SH RETURN VALUE

View File

@@ -2,7 +2,7 @@
.\"
.TH curl_multi_fdset 3 "3 May 2002" "libcurl 7.9.5" "libcurl Manual"
.SH NAME
curl_multi_fdset - add an easy handle to a multi session
curl_multi_fdset - extracts file descriptor information from a multi handle
.SH SYNOPSIS
#include <curl/curl.h>

View File

@@ -2,7 +2,7 @@
.\"
.TH curl_multi_perform 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
.SH NAME
curl_multi_perform - add an easy handle to a multi session
curl_multi_perform - reads/writes available data from each easy handle
.SH SYNOPSIS
#include <curl/curl.h>

View File

@@ -2,7 +2,7 @@
.\"
.TH curl_multi_remove_handle 3 "6 March 2002" "libcurl 7.9.5" "libcurl Manual"
.SH NAME
curl_multi_remove_handle - add an easy handle to a multi session
curl_multi_remove_handle - remove an easy handle from a multi session
.SH SYNOPSIS
#include <curl/curl.h>

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" $Id$
.\"
.TH libcurl-multi 5 "20 March 2001" "libcurl 7.9.5" "libcurl multi interface"
.TH libcurl-multi 5 "13 Oct 2001" "libcurl 7.10.1" "libcurl multi interface"
.SH NAME
libcurl-multi \- how to use the multi interface
.SH DESCRIPTION
@@ -37,7 +37,7 @@ curl_multi_* functions.
Each single transfer is built up with an easy handle. You must create them,
and setup the appropriate options for each easy handle, as outlined in the
\fIlibcurl(3)\fP man page.
\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
When the easy handle is setup for a transfer, then instead of using
\fIcurl_easy_perform\fP (as when using the easy interface for transfers), you
@@ -49,11 +49,11 @@ handles.
Should you change your mind, the easy handle is again removed from the multi
stack using \fIcurl_multi_remove_handle\fP. Once removed from the multi
handle, you can again use other easy interface functions like
curl_easy_perform or whatever you think is necessary.
\fIcurl_easy_perform\fP on the handle or whatever you think is necessary.
Adding the easy handles to the multi handle does not start any
transfer. Remember that one of the main ideas with this interface is to let
your application drive. You drive the transfers by invoking
Adding the easy handle to the multi handle does not start the transfer.
Remember that one of the main ideas with this interface is to let your
application drive. You drive the transfers by invoking
\fIcurl_multi_perform\fP. libcurl will then transfer data if there is anything
available to transfer. It'll use the callbacks and everything else you have
setup in the individual easy handles. It'll transfer data on all current
@@ -62,24 +62,39 @@ all, it may be none.
Your application can acquire knowledge from libcurl when it would like to get
invoked to transfer data, so that you don't have to busy-loop and call that
\fIcurl_multi_perform\fP like a mad man! \fIcurl_multi_fdset\fP offers an
\fIcurl_multi_perform\fP like crazy. \fIcurl_multi_fdset\fP offers an
interface using which you can extract fd_sets from libcurl to use in select()
or poll() calls in order to get to know when the transfers in the multi stack
might need attention. This also makes it very easy for your program to wait
for input on your own private file descriptors at the same time or perhaps
timeout every now and then, should you want that.
A little note here about the return codes from the multi functions, and
especially the \fIcurl_multi_perform\fP: if you receive
\fICURLM_CALL_MULTI_PERFORM\fP, this basicly means that you should call
\fIcurlm_call_multi_perform\fP again, before you select() on more actions. You
don't have to do it immediately, but the return code means that libcurl may
have more data available to return or that there may be more data to send off
before it is "satisfied".
\fIcurl_multi_perform\fP stores the number of still running transfers in one
of its input arguments, and by reading that you can figure out when all the
transfers in the multi handles are done. 'done' does not mean successful. One
or more of the transfers may have failed.
or more of the transfers may have failed. Tracking when this number changes,
you know when one or more transfers are done.
To get information about completed transfers, to figure out success or not and
similar, \fIcurl_multi_info_read\fP should be called. It can return a message
about a current or previous transfer. Repeated invokes of the function get
more messages until the message queue is empty.
more messages until the message queue is empty. The information you receive
there includes an easy handle pointer which you may use to identify which easy
handle the information regards.
When all transfers in the multi stack are done, cleanup the multi handle with
\fIcurl_multi_cleanup\fP. Be careful and please note that you \fBMUST\fP
invoke separate \fIcurl_easy_cleanup\fP calls on every single easy handle to
clean them up properly.
If you want to re-use an easy handle that was added to the multi handle for
transfer, you must first remove it from the multi stack and then re-add it
again (possbily after having altered some options at your own choice).

View File

@@ -205,6 +205,9 @@ typedef enum {
CURL_LAST /* never use! */
} CURLcode;
/* Make a spelling correction for the operation timed-out define */
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
typedef enum {
CURLPROXY_HTTP = 0,
CURLPROXY_SOCKS4 = 4,
@@ -242,7 +245,15 @@ typedef enum {
* platforms.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC)
defined(__HP_aCC) || defined(__BORLANDC__)
/* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP
#else
/* This compiler is believed NOT to have an ISO compatible preprocessor */
#undef CURL_ISOCPP
#endif
#ifdef CURL_ISOCPP
#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
#else
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
@@ -689,8 +700,7 @@ int curl_formparse(char *, struct curl_httppost **,
#undef CFINIT
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC)
#ifdef CURL_ISOCPP
#define CFINIT(name) CURLFORM_ ## name
#else
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
@@ -793,8 +803,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void);
/* This is the version number */
#define LIBCURL_VERSION "7.10.1"
#define LIBCURL_VERSION_NUM 0x070a01
#define LIBCURL_VERSION "7.10.2"
#define LIBCURL_VERSION_NUM 0x070a02
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {

View File

@@ -5,9 +5,9 @@
AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
Makefile.vc6 Makefile.riscos libcurl.def dllinit.c curllib.dsp \
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
config.h.in ca-bundle.crt README.encoding
config.h.in ca-bundle.crt README.encoding README.memoryleak
lib_LTLIBRARIES = libcurl.la
@@ -16,11 +16,7 @@ lib_LTLIBRARIES = libcurl.la
# we use srcdir/lib for the lib-private header files
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib
# The -no-undefined flag is CRUCIAL for this to build fine on Cygwin. If we
# find a case in which we need to remove this flag, we should most likely
# write a configure check that detects when this flag is needed and when its
# not.
libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0
VERSION=-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
@@ -50,6 +46,16 @@ libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0
# set age to 0.
#
if NO_UNDEFINED
# The -no-undefined flag is CRUCIAL for this to build fine on Cygwin. If we
# find a case in which we need to remove this flag, we should most likely
# write a configure check that detects when this flag is needed and when its
# not.
libcurl_la_LDFLAGS = -no-undefined $(VERSION)
else
libcurl_la_LDFLAGS = $(VERSION)
endif
libcurl_la_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c \
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c \
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \

View File

@@ -1,6 +1,6 @@
#############################################################
#
## Makefile for building libcurl.a with MingW32 (GCC-2.95) and
## Makefile for building libcurl.a with MingW32 (GCC-3.2) and
## optionally OpenSSL (0.9.6)
## Use: make -f Makefile.m32
##
@@ -9,9 +9,10 @@
CC = gcc
AR = ar
RM = rm -f
RANLIB = ranlib
STRIP = strip -g
OPENSSL_PATH = ../../openssl-0.9.6d
OPENSSL_PATH = ../../openssl-0.9.6g
ZLIB_PATH = ../../zlib-1.1.3
########################################################
@@ -60,16 +61,18 @@ OBJECTS = $(libcurl_a_OBJECTS)
all: libcurl.a libcurl.dll libcurldll.a
libcurl.a: $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
-@erase libcurl.a
$(RM) libcurl.a
$(AR) cru libcurl.a $(libcurl_a_OBJECTS)
$(RANLIB) libcurl.a
$(STRIP) $@
DLLINITOBJ =
# remove the last line above to keep debug info
libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o
-@erase $@
dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) dllinit.o $(DLL_LIBS) -lwsock32 -lws2_32 -lwinmm
libcurl.dll libcurldll.a: libcurl.a libcurl.def $(DLLINITOBJ)
$(RM) $@
dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) $(DLLINITOBJ) $(DLL_LIBS) -lwsock32 -lws2_32 -lwinmm
$(STRIP) $@
# remove the last line above to keep debug info
@@ -84,9 +87,9 @@ libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o
$(COMPILE) -c $<
clean:
-@erase $(libcurl_a_OBJECTS)
$(RM) $(libcurl_a_OBJECTS)
distrib: clean
-@erase $(libcurl_a_LIBRARIES)
$(RM) $(libcurl_a_LIBRARIES)

56
lib/README.memoryleak Normal file
View File

@@ -0,0 +1,56 @@
$Id$
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
How To Track Down Suspected Memory Leaks in libcurl
===================================================
Single-threaded
Please note that this memory leak system is not adjusted to work in more
than one thread. If you want/need to use it in a multi-threaded app. Please
adjust accordingly.
Build
Rebuild libcurl with -DMALLOCDEBUG (usually, rerunning configure with
--enable-debug fixes this). 'make clean' first, then 'make' so that all
files actually are rebuilt properly. It will also make sense to build
libcurl with the debug option (usually -g to the compiler) so that debugging
it will be easier if you actually do find a leak in the library.
This will create a library that has memory debugging enabled.
Modify Your Application
Add a line in your application code:
curl_memdebug("filename");
This will make the malloc debug system output a full trace of all resource
using functions to the given file name. Make sure you rebuild your program
and that you link with the same libcurl you built for this purpose as
described above.
Run Your Application
Run your program as usual. Watch the specified memory trace file grow.
Make your program exit and use the proper libcurl cleanup functions etc. So
that all non-leaks are returned/freed properly.
Analyze the Flow
Use the tests/memanalyze.pl perl script to analyze the memdump file:
tests/memanalyze.pl < memdump
This now outputs a report on what resources that were allocated but never
freed etc. This report is very fine for posting to the list!
If this doesn't produce any output, no leak was detected in libcurl. Then
the leak is mostly likely to be in your code.

View File

@@ -206,7 +206,7 @@ static CURLcode bindlocal(struct connectdata *conn,
*************************************************************/
if (strlen(data->set.device)<255) {
struct sockaddr_in sa;
Curl_addrinfo *h=NULL;
struct Curl_dns_entry *h=NULL;
size_t size;
char myhost[256] = "";
in_addr_t in;
@@ -247,12 +247,17 @@ static CURLcode bindlocal(struct connectdata *conn,
if (INADDR_NONE != in) {
if ( h ) {
Curl_addrinfo *addr = h->addr;
Curl_resolv_unlock(h);
/* we don't need it anymore after this function has returned */
memset((char *)&sa, 0, sizeof(sa));
#ifdef ENABLE_IPV6
memcpy((char *)&sa.sin_addr, h->ai_addr, h->ai_addrlen);
sa.sin_family = h->ai_family;
memcpy((char *)&sa.sin_addr, addr->ai_addr, addr->ai_addrlen);
sa.sin_family = addr->ai_family;
#else
memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length);
memcpy((char *)&sa.sin_addr, addr->h_addr, addr->h_length);
sa.sin_family = AF_INET;
#endif
sa.sin_addr.s_addr = in;
@@ -387,6 +392,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OK;
}
/* nope, not connected for real */
if(err)
return CURLE_COULDNT_CONNECT;
}
/*
@@ -408,7 +415,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
*/
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
Curl_addrinfo *remotehost, /* use one in here */
struct Curl_dns_entry *remotehost, /* use this one */
int port, /* connect to this */
int *sockconn, /* the connected socket */
Curl_ipconnect **addr, /* the one we used */
@@ -477,7 +484,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
struct addrinfo *ai;
port =0; /* prevent compiler warning */
for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) {
for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd < 0)
continue;
@@ -569,7 +576,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/*
* Connecting with IPv4-only support
*/
if(!remotehost->h_addr_list[0]) {
if(!remotehost->addr->h_addr_list[0]) {
/* If there is no addresses in the address list, then we return
error right away */
failf(data, "no address available");
@@ -596,16 +603,16 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* This is the loop that attempts to connect to all IP-addresses we
know for the given host. One by one. */
for(rc=-1, aliasindex=0;
rc && (struct in_addr *)remotehost->h_addr_list[aliasindex];
rc && (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
aliasindex++) {
struct sockaddr_in serv_addr;
/* do this nasty work to do the connect */
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr),
(struct in_addr *)remotehost->h_addr_list[aliasindex],
(struct in_addr *)remotehost->addr->h_addr_list[aliasindex],
sizeof(struct in_addr));
serv_addr.sin_family = remotehost->h_addrtype;
serv_addr.sin_family = remotehost->addr->h_addrtype;
serv_addr.sin_port = htons((unsigned short)port);
rc = connect(sockfd, (struct sockaddr *)&serv_addr,
@@ -681,7 +688,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(addr)
/* this is the address we've connected to */
*addr = (struct in_addr *)remotehost->h_addr_list[aliasindex];
*addr = (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
#endif
/* allow NULL-pointers to get passed in */

View File

@@ -31,7 +31,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
bool *connected);
CURLcode Curl_connecthost(struct connectdata *conn,
Curl_addrinfo *host, /* connect to this */
struct Curl_dns_entry *host, /* connect to this */
int port, /* connect to this port number */
int *sockconn, /* not set if error is returned */
Curl_ipconnect **addr, /* the one we used */

View File

@@ -519,7 +519,7 @@ struct CookieInfo *Curl_cookie_init(char *file,
char *lineptr;
bool headerline;
while(fgets(line, MAX_COOKIE_LINE, fp)) {
if(strnequal("Set-Cookie:", line, 11)) {
if(checkprefix("Set-Cookie:", line)) {
/* This is a cookie line, get it! */
lineptr=&line[11];
headerline=TRUE;
@@ -587,8 +587,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/* now check the left part of the path with the cookies path
requirement */
if(!co->path ||
strnequal(path, co->path, strlen(co->path))) {
if(!co->path ||
checkprefix(co->path, path) ) {
/* and now, we know this is a match and we should create an
entry for the return-linked-list */

View File

@@ -111,10 +111,6 @@ SOURCE=.\dict.c
# End Source File
# Begin Source File
SOURCE=.\dllinit.c
# End Source File
# Begin Source File
SOURCE=.\easy.c
# End Source File
# Begin Source File

View File

@@ -1,99 +0,0 @@
#ifdef WIN32
/* dllinit.c -- Portable DLL initialization.
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Mumit Khan (khan@xraylith.wisc.edu).
I've used DllMain as the DLL "main" since that's the most common
usage. MSVC and Mingw32 both default to DllMain as the standard
callback from the linker entry point. Cygwin, as of b20.1, also
uses DllMain as the default callback from the entry point.
The real entry point is typically always defined by the runtime
library, and usually never overridden by (casual) user. What you can
override however is the callback routine that the entry point calls,
and this file provides such a callback function, DllMain.
Mingw32: The default entry point for mingw32 is DllMainCRTStartup
which is defined in libmingw32.a This in turn calls DllMain which is
defined here. If not defined, there is a stub in libmingw32.a which
does nothing.
Cygwin: The default entry point for Cygwin b20.1 or newer is
__cygwin_dll_entry which is defined in libcygwin.a. This in turn
calls the routine DllMain. If not defined, there is a stub in
libcygwin.a which does nothing.
MSVC: MSVC runtime calls DllMain, just like Mingw32.
Summary: If you need to do anything special in DllMain, just add it
here. Otherwise, the default setup should be just fine for 99%+ of
the time. I strongly suggest that you *not* change the entry point,
but rather change DllMain as appropriate.
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <stdio.h>
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason,
LPVOID reserved /* Not used. */ );
/*
*----------------------------------------------------------------------
*
* DllMain --
*
* This routine is called by the Mingw32, Cygwin32 or VC++ C run
* time library init code, or the Borland DllEntryPoint routine. It
* is responsible for initializing various dynamically loaded
* libraries.
*
* Results:
* TRUE on sucess, FALSE on failure.
*
* Side effects:
*
*----------------------------------------------------------------------
*/
BOOL APIENTRY
DllMain (
HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
/* prevent compiler warnings */
(void) hInst;
(void) reserved;
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
#else
#ifdef VMS
int VOID_VAR_DLLINIT;
#endif
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
* end:
* vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78
*/

View File

@@ -637,7 +637,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost *post = NULL;
CURLformoption option;
struct curl_forms *forms = NULL;
char *array_value; /* value read from an array */
char *array_value=NULL; /* value read from an array */
/* This is a state variable, that if TRUE means that we're parsing an
array that we got passed to us. If FALSE we're parsing the input
@@ -1218,7 +1218,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/
if(file->contenttype &&
!strnequal("text/", file->contenttype, 5)) {
!checkprefix("text/", file->contenttype)) {
/* this is not a text content, mention our binary encoding */
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
}

View File

@@ -999,7 +999,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
#endif
unsigned char *ap;
unsigned char *pp;
int alen, plen;
char portmsgbuf[4096], tmp[4096];
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
@@ -1062,6 +1061,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
for (modep = (char **)mode; modep && *modep; modep++) {
int lprtaf, eprtaf;
int alen=0, plen=0;
switch (sa->sa_family) {
case AF_INET:
@@ -1183,8 +1183,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
*
*/
struct sockaddr_in sa;
struct hostent *h=NULL;
char *hostdataptr=NULL;
struct Curl_dns_entry *h=NULL;
unsigned short porttouse;
char myhost[256] = "";
bool sa_filled_in = FALSE;
@@ -1215,6 +1214,10 @@ CURLcode ftp_use_port(struct connectdata *conn)
sa_filled_in = TRUE; /* the sa struct is filled in */
}
if(h)
/* when we return from here, we can forget about this */
Curl_resolv_unlock(h);
if ( h || sa_filled_in) {
if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {
int size;
@@ -1227,8 +1230,8 @@ CURLcode ftp_use_port(struct connectdata *conn)
if(!sa_filled_in) {
memset((char *)&sa, 0, sizeof(sa));
memcpy((char *)&sa.sin_addr,
h->h_addr,
h->h_length);
h->addr->h_addr,
h->addr->h_length);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
}
@@ -1250,19 +1253,16 @@ CURLcode ftp_use_port(struct connectdata *conn)
if ( listen(portsock, 1) < 0 ) {
failf(data, "listen(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
else {
failf(data, "bind(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
else {
failf(data, "socket(2) failed (%s)");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
@@ -1277,7 +1277,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
struct in_addr in;
unsigned short ip[5];
(void) memcpy(&in.s_addr,
h?*h->h_addr_list:(char *)&sa.sin_addr.s_addr,
h?*h->addr->h_addr_list:(char *)&sa.sin_addr.s_addr,
sizeof (in.s_addr));
#ifdef HAVE_INET_NTOA_R
@@ -1332,7 +1332,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
char *buf = data->state.buffer; /* this is our buffer */
int ftpcode; /* receive FTP response codes in this */
CURLcode result;
Curl_addrinfo *addr=NULL;
struct Curl_dns_entry *addr=NULL;
Curl_ipconnect *conninfo;
/*
@@ -1363,7 +1363,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
#endif
int modeoff;
unsigned short connectport; /* the local port connect() should use! */
unsigned short newport; /* remote port, not necessary the local one */
unsigned short newport=0; /* remote port, not necessary the local one */
/* newhost must be able to hold a full IP-style address in ASCII, which
in the IPv6 case means 5*8-1 = 39 letters */
@@ -1480,6 +1480,8 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
&conninfo,
connected);
Curl_resolv_unlock(addr); /* we're done using this address */
/*
* When this is used from the multi interface, this might've returned with
* the 'connected' set to FALSE and thus we are now awaiting a non-blocking
@@ -2087,7 +2089,7 @@ CURLcode Curl_ftp(struct connectdata *conn)
retcode = Curl_ftp_nextconnect(conn);
else
/* since we didn't connect now, we want do_more to get called */
conn->do_more = TRUE;
conn->bits.do_more = TRUE;
}
return retcode;

View File

@@ -72,9 +72,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
{
va_list arg;
long *param_longp;
double *param_doublep;
char **param_charp;
long *param_longp=NULL;
double *param_doublep=NULL;
char **param_charp=NULL;
va_start(arg, info);
switch(info&CURLINFO_TYPEMASK) {

View File

@@ -25,6 +25,7 @@
#include <string.h>
#include <stdlib.h>
#include "hash.h"
#include "llist.h"
@@ -128,7 +129,6 @@ _mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void *
(*e)->key = strdup(key);
(*e)->key_len = key_len;
(*e)->ptr = (void *) p;
return 0;
}
/* }}} */
@@ -195,10 +195,10 @@ Curl_hash_delete(curl_hash *h, char *key, size_t key_len)
}
/* }}} */
/* {{{ int curl_hash_find (curl_hash *, char *, size_t, void **)
/* {{{ int curl_hash_pick (curl_hash *, char *, size_t, void **)
*/
int
Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p)
void *
Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
{
curl_llist_element *le;
curl_hash_element *he;
@@ -209,12 +209,11 @@ Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p)
le = CURL_LLIST_NEXT(le)) {
he = CURL_LLIST_VALP(le);
if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
*p = he->ptr;
return 1;
return he->ptr;
}
}
return 0;
return NULL;
}
/* }}} */
@@ -222,7 +221,7 @@ Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p)
*/
void
Curl_hash_apply(curl_hash *h, void *user,
void (*cb)(void *, curl_hash_element *))
void (*cb)(void *user, void *ptr))
{
curl_llist_element *le;
int i;
@@ -231,7 +230,8 @@ Curl_hash_apply(curl_hash *h, void *user,
for (le = CURL_LLIST_HEAD(h->table[i]);
le != NULL;
le = CURL_LLIST_NEXT(le)) {
cb(user, (curl_hash_element *) CURL_LLIST_VALP(le));
curl_hash_element *el = CURL_LLIST_VALP(le);
cb(user, el->ptr);
}
}
}

View File

@@ -41,7 +41,7 @@ typedef struct _curl_hash {
typedef struct _curl_hash_element {
void *ptr;
char *key;
size_t key_len;
size_t key_len;
} curl_hash_element;
@@ -49,15 +49,14 @@ void Curl_hash_init(curl_hash *, int, curl_hash_dtor);
curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
int Curl_hash_add(curl_hash *, char *, size_t, const void *);
int Curl_hash_delete(curl_hash *h, char *key, size_t key_len);
int Curl_hash_find(curl_hash *, char *, size_t, void **p);
void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
void *Curl_hash_pick(curl_hash *, char *, size_t);
void Curl_hash_apply(curl_hash *h, void *user,
void (*cb)(void *user, void *ptr));
int Curl_hash_count(curl_hash *h);
void Curl_hash_clean(curl_hash *h);
void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
void Curl_hash_destroy(curl_hash *h);
#define Curl_hash_update Curl_hash_add
#endif
/*

View File

@@ -80,6 +80,11 @@
static curl_hash hostname_cache;
static int host_cache_initialized;
static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp);
void Curl_global_host_cache_init(void)
{
if (!host_cache_initialized) {
@@ -101,11 +106,6 @@ void Curl_global_host_cache_dtor(void)
}
}
struct curl_dns_cache_entry {
Curl_addrinfo *addr;
time_t timestamp;
};
/* count the number of characters that an integer takes up */
static int _num_chars(int i)
{
@@ -129,7 +129,7 @@ static int _num_chars(int i)
/* Create a hostcache id */
static char *
_create_hostcache_id(char *server, int port, ssize_t *entry_len)
create_hostcache_id(char *server, int port, ssize_t *entry_len)
{
char *id = NULL;
@@ -162,16 +162,19 @@ struct hostcache_prune_data {
};
static int
_curl_hostcache_timestamp_remove(void *datap, void *hc)
hostcache_timestamp_remove(void *datap, void *hc)
{
struct hostcache_prune_data *data =
(struct hostcache_prune_data *) datap;
struct curl_dns_cache_entry *c = (struct curl_dns_cache_entry *) hc;
struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
if (data->now - c->timestamp < data->cache_timeout) {
if ((data->now - c->timestamp < data->cache_timeout) ||
c->inuse) {
/* please don't remove */
return 0;
}
/* fine, remove */
return 1;
}
@@ -185,14 +188,30 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
Curl_hash_clean_with_criterium(hostcache,
(void *) &user,
_curl_hostcache_timestamp_remove);
hostcache_timestamp_remove);
}
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
/* Called from Curl_done() to check that there's no DNS cache entry with
a non-zero counter left. */
void Curl_scan_cache_used(void *user, void *ptr)
{
struct Curl_dns_entry *e = ptr;
(void)user; /* prevent compiler warning */
if(e->inuse) {
fprintf(stderr, "*** WARNING: locked DNS cache entry detected: %s\n",
e->entry_id);
/* perform a segmentation fault to draw attention */
*(void **)0 = 0;
}
}
#endif
/* Macro to save redundant free'ing of entry_id */
#define _hostcache_return(__v) \
#define HOSTCACHE_RETURN(dns) \
{ \
free(entry_id); \
return (__v); \
return dns; \
}
#ifdef HAVE_SIGSETJMP
@@ -200,70 +219,69 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
sigjmp_buf curl_jmpenv;
#endif
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname,
int port)
struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
char *hostname,
int port)
{
char *entry_id = NULL;
struct curl_dns_cache_entry *p = NULL;
struct Curl_dns_entry *dns = NULL;
ssize_t entry_len;
time_t now;
char *bufp;
#ifdef HAVE_SIGSETJMP
if(sigsetjmp(curl_jmpenv, 1) != 0) {
/* this allows us to time-out from the name resolver, as the timeout
will generate a signal and we will siglongjmp() from that here */
if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
/* this is coming from a siglongjmp() */
failf(data, "name lookup time-outed");
return NULL;
}
#endif
/* If the host cache timeout is 0, we don't do DNS cach'ing
so fall through */
if (data->set.dns_cache_timeout == 0) {
return Curl_getaddrinfo(data, hostname, port, &bufp);
}
/* Create an entry id, based upon the hostname and port */
entry_len = strlen(hostname);
entry_id = create_hostcache_id(hostname, port, &entry_len);
/* If we can't create the entry id, fail */
if (!entry_id)
return NULL;
/* See if its already in our dns cache */
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
if (!dns) {
Curl_addrinfo *addr = my_getaddrinfo(data, hostname, port, &bufp);
if (!addr) {
HOSTCACHE_RETURN(NULL);
}
/* Create a new cache entry */
dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry));
if (!dns) {
Curl_freeaddrinfo(addr);
HOSTCACHE_RETURN(NULL);
}
dns->inuse = 0;
dns->addr = addr;
/* Save it in our host cache */
Curl_hash_add(data->hostcache, entry_id, entry_len+1, (const void *) dns);
}
time(&now);
/* Remove outdated entries from the hostcache */
dns->timestamp = now;
dns->inuse++; /* mark entry as in-use */
#ifdef MALLOCDEBUG
dns->entry_id = entry_id;
#endif
/* Remove outdated and unused entries from the hostcache */
hostcache_prune(data->hostcache,
data->set.dns_cache_timeout,
now);
/* Create an entry id, based upon the hostname and port */
entry_len = strlen(hostname);
entry_id = _create_hostcache_id(hostname, port, &entry_len);
/* If we can't create the entry id, don't cache, just fall-through
to the plain Curl_getaddrinfo() */
if (!entry_id) {
return Curl_getaddrinfo(data, hostname, port, &bufp);
}
/* See if its already in our dns cache */
if (entry_id &&
Curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) {
_hostcache_return(p->addr);
}
/* Create a new cache entry */
p = (struct curl_dns_cache_entry *)
malloc(sizeof(struct curl_dns_cache_entry));
if (!p) {
_hostcache_return(NULL);
}
p->addr = Curl_getaddrinfo(data, hostname, port, &bufp);
if (!p->addr) {
free(p);
_hostcache_return(NULL);
}
p->timestamp = now;
/* Save it in our host cache */
Curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p);
_hostcache_return(p->addr);
HOSTCACHE_RETURN(dns);
}
/*
@@ -273,7 +291,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
*/
void Curl_freeaddrinfo(void *freethis)
{
struct curl_dns_cache_entry *p = (struct curl_dns_cache_entry *) freethis;
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
#ifdef ENABLE_IPV6
freeaddrinfo(p->addr);
@@ -331,10 +349,10 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
* memory we need to free after use. That meory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp)
static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp)
{
struct addrinfo hints, *res;
int error;
@@ -507,10 +525,10 @@ static void hostcache_fixoffset(struct hostent *h, int offset)
/* The original code to this function was once stolen from the Dancer source
code, written by Bjorn Reese, it has since been patched and modified
considerably. */
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp)
static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp)
{
struct hostent *h = NULL;
in_addr_t in;
@@ -597,14 +615,25 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
#endif
#ifdef HAVE_GETHOSTBYNAME_R_6
/* Linux */
while((res=gethostbyname_r(hostname,
(struct hostent *)buf,
(char *)buf + sizeof(struct hostent),
step_size - sizeof(struct hostent),
&h, /* DIFFERENCE */
&h_errnop))==ERANGE) {
step_size+=200;
}
do {
res=gethostbyname_r(hostname,
(struct hostent *)buf,
(char *)buf + sizeof(struct hostent),
step_size - sizeof(struct hostent),
&h, /* DIFFERENCE */
&h_errnop);
/* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
sudden this function seems to be setting EAGAIN if the given buffer
size is too small. Previous versions are known to return ERANGE for
the same. */
if((ERANGE == res) || (EAGAIN == res)) {
step_size+=200;
continue;
}
break;
} while(1);
if(!h) /* failure */
res=1;

View File

@@ -23,6 +23,7 @@
* $Id$
***************************************************************************/
#include "setup.h"
#include "hash.h"
struct addrinfo;
@@ -35,15 +36,34 @@ curl_hash *Curl_global_host_cache_get(void);
#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname,
int port);
struct Curl_dns_entry {
Curl_addrinfo *addr;
time_t timestamp;
long inuse; /* use-counter, make very sure you decrease this
when you're done using the address you received */
#ifdef MALLOCDEBUG
char *entry_id;
#endif
};
/*
* Curl_resolv() returns an entry with the info for the specified host
* and port.
*
* The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
* use, or we'll leak memory!
*/
struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
char *hostname,
int port);
/* unlock a previously resolved dns entry */
#define Curl_resolv_unlock(dns) dns->inuse--
/* for debugging purposes only: */
void Curl_scan_cache_used(void *user, void *ptr);
/* Get name info */
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port,
char **bufp);
/* free name info */
void Curl_freeaddrinfo(void *freethis);

View File

@@ -485,6 +485,7 @@ CURLcode Curl_http(struct connectdata *conn)
struct Cookie *co=NULL; /* no cookies from start */
char *ppath = conn->ppath; /* three previous function arguments */
char *host = conn->name;
const char *te = ""; /* tranfer-encoding */
if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */
@@ -546,6 +547,14 @@ CURLcode Curl_http(struct connectdata *conn)
conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie);
}
if(conn->bits.upload_chunky) {
if(!checkheaders(data, "Transfer-Encoding:")) {
te = "Transfer-Encoding: chunked\r\n";
}
/* else
our header was already added, what to do now? */
}
if(data->cookies) {
co = Curl_cookie_getlist(data->cookies,
host, ppath,
@@ -717,7 +726,8 @@ CURLcode Curl_http(struct connectdata *conn)
"%s" /* pragma */
"%s" /* accept */
"%s" /* accept-encoding */
"%s", /* referer */
"%s" /* referer */
"%s",/* transfer-encoding */
data->set.customrequest?data->set.customrequest:
(data->set.no_body?"HEAD":
@@ -739,7 +749,8 @@ CURLcode Curl_http(struct connectdata *conn)
http->p_accept?http->p_accept:"",
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
conn->allocptr.accept_encoding:"", /* 08/28/02 jhrg */
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */,
te
);
if(co) {

View File

@@ -40,4 +40,5 @@ EXPORTS
curl_multi_perform @ 31;
curl_multi_cleanup @ 32;
curl_multi_info_read @ 33;
curl_free @ 34;
curl_free @ 34;
curl_version_info @ 35;

View File

@@ -57,6 +57,7 @@ FILE *curl_fopen(const char *file, const char *mode, int line,
int curl_fclose(FILE *file, int line, const char *source);
/* Set this symbol on the command-line, recompile all lib-sources */
#undef strdup
#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)

View File

@@ -360,7 +360,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(CURLE_OK == easy->result) {
/* after do, go PERFORM... or DO_MORE */
if(easy->easy_conn->do_more) {
if(easy->easy_conn->bits.do_more) {
/* we're supposed to do more, but we need to sit down, relax
and wait a little while first */
easy->state = CURLM_STATE_DO_MORE;
@@ -430,8 +430,10 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(easy->easy_conn->newurl) {
easy->result = Curl_follow(easy->easy_handle,
strdup(easy->easy_conn->newurl));
if(CURLE_OK == easy->result)
if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_CONNECT;
result = CURLM_CALL_MULTI_PERFORM;
}
}
else {
easy->state = CURLM_STATE_DONE;

View File

@@ -154,8 +154,9 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
data->state.errorbuf = TRUE; /* wrote error string */
Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer,
strlen(data->set.errorbuffer));
if(data->set.verbose)
Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer,
strlen(data->set.errorbuffer));
}
va_end(ap);
}

View File

@@ -32,6 +32,10 @@ int curl_strnequal(const char *first, const char *second, size_t max);
#define strequal(a,b) curl_strequal(a,b)
#define strnequal(a,b,c) curl_strnequal(a,b,c)
/* checkprefix() is a shorter version of the above, used when the first
argument is zero-byte terminated */
#define checkprefix(a,b) strnequal(a,b,strlen(a))
#ifndef HAVE_STRLCAT
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
size_t Curl_strlcat(char *dst, const char *src, size_t siz);

View File

@@ -291,10 +291,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->hbuflen += nread;
if (!k->headerline && (k->hbuflen>5)) {
/* make a first check that this looks like a HTTP header */
if(!strnequal(data->state.headerbuff, "HTTP/", 5)) {
if(!checkprefix("HTTP/", data->state.headerbuff)) {
/* this is not the beginning of a HTTP first header line */
k->header = FALSE;
k->badheader = TRUE;
k->badheader = HEADER_ALLBAD;
break;
}
}
@@ -342,6 +342,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
* We now have a FULL header line that p points to
*****/
if(!k->headerline) {
/* the first read header */
if((k->hbuflen>5) &&
!checkprefix("HTTP/", data->state.headerbuff)) {
/* this is not the beginning of a HTTP first header line */
k->header = FALSE;
k->badheader = HEADER_PARTHEADER;
break;
}
}
if (('\n' == *k->p) || ('\r' == *k->p)) {
int headerlen;
/* Zero-length header line means end of headers! */
@@ -505,19 +516,18 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
else {
k->header = FALSE; /* this is not a header line */
k->badheader = TRUE; /* this was a bad header */
break;
}
}
/* check for Content-Length: header lines to get size */
if (strnequal("Content-Length:", k->p, 15) &&
if (checkprefix("Content-Length:", k->p) &&
sscanf (k->p+15, " %ld", &k->contentlength)) {
conn->size = k->contentlength;
Curl_pgrsSetDownloadSize(data, k->contentlength);
}
/* check for Content-Type: header lines to get the mime-type */
else if (strnequal("Content-Type:", k->p, 13)) {
else if (checkprefix("Content-Type:", k->p)) {
char *start;
char *end;
int len;
@@ -587,7 +597,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* init our chunky engine */
Curl_httpchunk_init(conn);
}
else if (strnequal("Content-Encoding:", k->p, 17) &&
else if (checkprefix("Content-Encoding:", k->p) &&
data->set.encoding) {
/*
* Process Content-Encoding. Look for the values: identity, gzip,
@@ -599,23 +609,23 @@ CURLcode Curl_readwrite(struct connectdata *conn,
char *start;
/* Find the first non-space letter */
for(start=k->p+18;
for(start=k->p+17;
*start && isspace((int)*start);
start++);
/* Record the content-encoding for later use. 08/27/02 jhrg */
if (strnequal("identity", start, 8))
if (checkprefix("identity", start))
k->content_encoding = IDENTITY;
else if (strnequal("deflate", start, 7))
else if (checkprefix("deflate", start))
k->content_encoding = DEFLATE;
else if (strnequal("gzip", start, 4)
|| strnequal("x-gzip", start, 6))
else if (checkprefix("gzip", start)
|| checkprefix("x-gzip", start))
k->content_encoding = GZIP;
else if (strnequal("compress", start, 8)
|| strnequal("x-compress", start, 10))
else if (checkprefix("compress", start)
|| checkprefix("x-compress", start))
k->content_encoding = COMPRESS;
}
else if (strnequal("Content-Range:", k->p, 14)) {
else if (checkprefix("Content-Range:", k->p)) {
if (sscanf (k->p+14, " bytes %d-", &k->offset) ||
sscanf (k->p+14, " bytes: %d-", &k->offset)) {
/* This second format was added August 1st 2000 by Igor
@@ -628,11 +638,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
}
else if(data->cookies &&
strnequal("Set-Cookie:", k->p, 11)) {
checkprefix("Set-Cookie:", k->p)) {
Curl_cookie_add(data->cookies, TRUE, k->p+11, conn->name);
}
else if(strnequal("Last-Modified:", k->p,
strlen("Last-Modified:")) &&
else if(checkprefix("Last-Modified:", k->p) &&
(data->set.timecondition || data->set.get_filetime) ) {
time_t secs=time(NULL);
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
@@ -642,7 +651,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
}
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
(data->set.http_follow_location) &&
strnequal("Location:", k->p, 9)) {
checkprefix("Location:", k->p)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
char *start=k->p;
@@ -660,9 +669,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
while(*ptr && !isspace((int)*ptr))
ptr++;
backup = *ptr; /* store the ending letter */
*ptr = '\0'; /* zero terminate */
conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
if(ptr != start) {
*ptr = '\0'; /* zero terminate */
conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
}
}
/*
@@ -716,6 +727,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
infof (data, "Follow to new URL: %s\n", conn->newurl);
k->keepon &= ~KEEP_READ;
FD_ZERO(&k->rkeepfd);
*done = TRUE;
return CURLE_OK;
}
else if (conn->resume_from &&
@@ -740,6 +752,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(k->timeofdoc < data->set.timevalue) {
infof(data,
"The requested document is not new enough\n");
*done = TRUE;
return CURLE_OK;
}
break;
@@ -747,6 +760,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(k->timeofdoc > data->set.timevalue) {
infof(data,
"The requested document is not old enough\n");
*done = TRUE;
return CURLE_OK;
}
break;
@@ -759,8 +773,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->bodywrites++;
/* pass data to the debug function before it gets "dechunked" */
if(data->set.verbose)
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
if(data->set.verbose) {
if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
k->hbuflen);
if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
}
else
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
}
if(conn->bits.chunk) {
/*
@@ -815,14 +837,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
result = Curl_client_write(data, CLIENTWRITE_BODY,
data->state.headerbuff,
k->hbuflen);
k->badheader = FALSE; /* taken care of now */
}
/* This switch handles various content encodings. If there's an
error here, be sure to check over the almost identical code in
http_chunk.c. 08/29/02 jhrg */
if(k->badheader < HEADER_ALLBAD) {
/* This switch handles various content encodings. If there's an
error here, be sure to check over the almost identical code in
http_chunk.c. 08/29/02 jhrg */
#ifdef HAVE_LIBZ
switch (k->content_encoding) {
switch (k->content_encoding) {
case IDENTITY:
#endif
/* This is the default when the server sends no
@@ -847,8 +868,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
"content encodings.");
result = CURLE_BAD_CONTENT_ENCODING;
break;
}
}
#endif
}
k->badheader = HEADER_NORMAL; /* taken care of now */
if(result)
return result;
@@ -876,11 +899,46 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* only read more data if there's no upload data already
present in the upload buffer */
if(0 == conn->upload_present) {
size_t buffersize = BUFSIZE;
/* init the "upload from here" pointer */
conn->upload_fromhere = k->uploadbuf;
nread = data->set.fread(conn->upload_fromhere, 1,
BUFSIZE, data->set.in);
if(!k->upload_done) {
if(conn->bits.upload_chunky) {
/* if chunked Transfer-Encoding */
buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
conn->upload_fromhere += 10; /* 32bit hex + CRLF */
}
nread = data->set.fread(conn->upload_fromhere, 1,
buffersize, data->set.in);
if(conn->bits.upload_chunky) {
/* if chunked Transfer-Encoding */
char hexbuffer[9];
int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
"%x\r\n", nread);
/* move buffer pointer */
conn->upload_fromhere -= hexlen;
nread += hexlen;
/* copy the prefix to the buffer */
memcpy(conn->upload_fromhere, hexbuffer, hexlen);
if(nread>0) {
/* append CRLF to the data */
memcpy(conn->upload_fromhere +
nread, "\r\n", 2);
nread+=2;
}
else {
/* mark this as done once this chunk is transfered */
k->upload_done = TRUE;
}
}
}
else
nread = 0; /* we're done uploading/reading */
/* the signed int typecase of nread of for systems that has
unsigned size_t */
@@ -944,6 +1002,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* we've uploaded that buffer now */
conn->upload_fromhere = k->uploadbuf;
conn->upload_present = 0; /* no more bytes left */
if(k->upload_done) {
/* switch off writing, we're done! */
k->keepon &= ~KEEP_WRITE; /* we're done writing */
FD_ZERO(&k->wkeepfd);
}
}
if(data->set.verbose)
@@ -1048,13 +1112,13 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0);
if (!conn->getheader) {
if (!conn->bits.getheader) {
k->header = FALSE;
if(conn->size > 0)
Curl_pgrsSetDownloadSize(data, conn->size);
}
/* we want header and/or body, if neither then don't do this! */
if(conn->getheader || !data->set.no_body) {
if(conn->bits.getheader || !data->set.no_body) {
FD_ZERO (&k->readfd); /* clear it */
if(conn->sockfd != -1) {
@@ -1136,7 +1200,7 @@ Transfer(struct connectdata *conn)
return CURLE_OK;
/* we want header and/or body, if neither then don't do this! */
if(!conn->getheader && data->set.no_body)
if(!conn->bits.getheader && data->set.no_body)
return CURLE_OK;
k->writefdp = &k->writefd; /* store the address of the set */
@@ -1194,6 +1258,22 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
data->state.this_is_a_follow = FALSE; /* reset this */
data->state.errorbuf = FALSE; /* no error has occurred */
/* If there was a list of cookie files to read and we haven't done it before,
do it now! */
if(data->change.cookielist) {
struct curl_slist *list = data->change.cookielist;
while(list) {
data->cookies = Curl_cookie_init(list->data,
data->cookies,
data->set.cookiesession);
list = list->next;
}
curl_slist_free_all(data->change.cookielist); /* clean up list */
data->change.cookielist = NULL; /* don't do this again! */
}
/* Allow data->set.use_port to set which port to use. This needs to be
* disabled for example when we follow Location: headers to URLs using
* different ports! */
@@ -1351,7 +1431,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
return CURLE_OUT_OF_MEMORY; /* go out from this */
sprintf(newest, "%s%s%s", url_clone,
(('/' == useurl[0]) || !*protsep)?"":"/",
(('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
useurl);
free(newurl); /* newurl is the allocated pointer */
free(url_clone);
@@ -1569,7 +1649,7 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */
/* now copy all input parameters */
conn->sockfd = sockfd;
conn->size = size;
conn->getheader = getheader;
conn->bits.getheader = getheader;
conn->bytecountp = bytecountp;
conn->writesockfd = writesockfd;
conn->writebytecountp = writebytecountp;

View File

@@ -183,6 +183,9 @@ CURLcode Curl_close(struct SessionHandle *data)
if (data->share)
data->share->dirty--;
if(data->change.cookielist) /* clean up list if any */
curl_slist_free_all(data->change.cookielist);
if(data->state.auth_host)
free(data->state.auth_host);
@@ -552,8 +555,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
cookiefile = (char *)va_arg(param, void *);
if(cookiefile)
data->cookies = Curl_cookie_init(cookiefile, data->cookies,
data->set.cookiesession);
/* append the cookie file name to the list of file names, and deal with
them later */
data->change.cookielist =
curl_slist_append(data->change.cookielist, cookiefile);
break;
case CURLOPT_COOKIEJAR:
@@ -1479,18 +1484,23 @@ static int handleSock5Proxy(
socksreq[3] = 1; /* IPv4 = 1 */
{
Curl_addrinfo *hp;
hp = Curl_resolv(conn->data, conn->hostname, conn->remote_port);
#ifndef ENABLE_IPV6
struct Curl_dns_entry *dns;
Curl_addrinfo *hp=NULL;
dns = Curl_resolv(conn->data, conn->hostname, conn->remote_port);
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
* returns a Curl_addrinfo pointer that may not always look the same.
*/
#ifndef ENABLE_IPV6
if(dns)
hp=dns->addr;
if (hp && hp->h_addr_list[0]) {
socksreq[4] = ((char*)hp->h_addr_list[0])[0];
socksreq[5] = ((char*)hp->h_addr_list[0])[1];
socksreq[6] = ((char*)hp->h_addr_list[0])[2];
socksreq[7] = ((char*)hp->h_addr_list[0])[3];
Curl_resolv_unlock(dns); /* not used anymore from now on */
}
else {
failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
@@ -1543,7 +1553,7 @@ static int handleSock5Proxy(
}
static CURLcode ConnectPlease(struct connectdata *conn,
Curl_addrinfo *hostaddr,
struct Curl_dns_entry *hostaddr,
bool *connected)
{
CURLcode result;
@@ -1562,13 +1572,15 @@ static CURLcode ConnectPlease(struct connectdata *conn,
/* All is cool, then we store the current information from the hostaddr
struct to the serv_addr, as it might be needed later. The address
returned from the function above is crucial here. */
conn->connect_addr = hostaddr;
#ifdef ENABLE_IPV6
conn->serv_addr = addr;
#else
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
memcpy((char *)&(conn->serv_addr.sin_addr),
(struct in_addr *)addr, sizeof(struct in_addr));
conn->serv_addr.sin_family = hostaddr->h_addrtype;
conn->serv_addr.sin_family = hostaddr->addr->h_addrtype;
conn->serv_addr.sin_port = htons((unsigned short)conn->port);
#endif
@@ -1592,7 +1604,7 @@ static CURLcode ConnectPlease(struct connectdata *conn,
}
static void verboseconnect(struct connectdata *conn,
Curl_addrinfo *hostaddr)
struct Curl_dns_entry *dns)
{
#ifdef HAVE_INET_NTOA_R
char ntoa_buf[64];
@@ -1601,7 +1613,7 @@ static void verboseconnect(struct connectdata *conn,
/* Figure out the ip-number and display the first host name it shows: */
#ifdef ENABLE_IPV6
(void)hostaddr; /* not used in the IPv6 enabled version */
(void)dns; /* not used in the IPv6 enabled version */
{
char hbuf[NI_MAXHOST];
#ifdef NI_WITHSCOPEID
@@ -1624,6 +1636,7 @@ static void verboseconnect(struct connectdata *conn,
}
#else
{
Curl_addrinfo *hostaddr=dns->addr;
struct in_addr in;
(void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
infof(data, "Connected to %s (%s) port %d\n",
@@ -1649,7 +1662,7 @@ static void verboseconnect(struct connectdata *conn,
* 'serv_addr' field in the connectdata struct for most of it.
*/
CURLcode Curl_protocol_connect(struct connectdata *conn,
Curl_addrinfo *hostaddr)
struct Curl_dns_entry *hostaddr)
{
struct SessionHandle *data = conn->data;
CURLcode result=CURLE_OK;
@@ -1684,15 +1697,15 @@ static CURLcode CreateConnection(struct SessionHandle *data,
struct connectdata *conn;
struct connectdata *conn_temp;
int urllen;
Curl_addrinfo *hostaddr;
struct Curl_dns_entry *hostaddr;
#ifdef HAVE_ALARM
unsigned int prev_alarm;
unsigned int prev_alarm=0;
#endif
char endbracket;
#ifdef HAVE_SIGACTION
struct sigaction keep_sigact; /* store the old struct here */
bool keep_copysig; /* did copy it? */
bool keep_copysig=FALSE; /* did copy it? */
#else
#ifdef HAVE_SIGNAL
void *keep_sigact; /* store the old handler here */
@@ -1751,6 +1764,20 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* Store creation time to help future close decision making */
conn->created = Curl_tvnow();
/* Set the start time temporary to this creation time to allow easier
timeout checks before the transfer has started for real. The start time
is later set "for real" using Curl_pgrsStartNow(). */
conn->data->progress.start = conn->created;
conn->bits.upload_chunky =
((conn->protocol&PROT_HTTP) &&
data->set.upload &&
(data->set.infilesize == -1) &&
(data->set.httpversion != CURL_HTTP_VERSION_1_0))?
/* HTTP, upload, unknown file size and not HTTP 1.0 */
TRUE:
/* else, no chunky upload */
FALSE;
/***********************************************************
* We need to allocate memory to store the path in. We get the size of the
@@ -1843,22 +1870,22 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* Note: if you add a new protocol, please update the list in
* lib/version.c too! */
if(strnequal(conn->gname, "FTP", 3)) {
if(checkprefix("FTP", conn->gname)) {
strcpy(conn->protostr, "ftp");
}
else if(strnequal(conn->gname, "GOPHER", 6))
else if(checkprefix("GOPHER", conn->gname))
strcpy(conn->protostr, "gopher");
#ifdef USE_SSLEAY
else if(strnequal(conn->gname, "HTTPS", 5))
else if(checkprefix("HTTPS", conn->gname))
strcpy(conn->protostr, "https");
else if(strnequal(conn->gname, "FTPS", 4))
else if(checkprefix("FTPS", conn->gname))
strcpy(conn->protostr, "ftps");
#endif /* USE_SSLEAY */
else if(strnequal(conn->gname, "TELNET", 6))
else if(checkprefix("TELNET", conn->gname))
strcpy(conn->protostr, "telnet");
else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1))
else if (checkprefix("DICT", conn->gname))
strcpy(conn->protostr, "DICT");
else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1))
else if (checkprefix("LDAP", conn->gname))
strcpy(conn->protostr, "LDAP");
else {
strcpy(conn->protostr, "http");
@@ -1961,7 +1988,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(strlen(nope) <= namelen) {
char *checkn=
conn->name + namelen - strlen(nope);
if(strnequal(nope, checkn, strlen(nope))) {
if(checkprefix(nope, checkn)) {
/* no proxy for this host! */
break;
}
@@ -2806,7 +2833,6 @@ CURLcode Curl_connect(struct SessionHandle *data,
return code;
}
CURLcode Curl_done(struct connectdata *conn)
{
struct SessionHandle *data=conn->data;
@@ -2825,6 +2851,15 @@ CURLcode Curl_done(struct connectdata *conn)
conn->newurl = NULL;
}
if(conn->connect_addr)
Curl_resolv_unlock(conn->connect_addr); /* done with this */
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
/* scan for DNS cache entries still marked as in use */
Curl_hash_apply(data->hostcache,
NULL, Curl_scan_cache_used);
#endif
/* this calls the protocol-specific function pointer previously set */
if(conn->curl_done)
result = conn->curl_done(conn);
@@ -2854,7 +2889,7 @@ CURLcode Curl_do(struct connectdata **connp)
struct connectdata *conn = *connp;
struct SessionHandle *data=conn->data;
conn->do_more = FALSE; /* by default there's no curl_do_more() to use */
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
if(conn->curl_do) {
/* generic protocol-specific function pointer set in curl_connect() */

View File

@@ -36,5 +36,5 @@ CURLcode Curl_do_more(struct connectdata *);
CURLcode Curl_done(struct connectdata *);
CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn,
Curl_addrinfo *hostaddr);
struct Curl_dns_entry *dns);
#endif

View File

@@ -26,8 +26,6 @@
/* This file is for lib internal stuff */
#include "setup.h"
#include "hostip.h"
#include "hash.h"
#define PORT_FTP 21
#define PORT_TELNET 23
@@ -81,6 +79,8 @@
#include <curl/curl.h>
#include "http_chunks.h" /* for the structs and enum stuff */
#include "hostip.h"
#include "hash.h"
#ifdef HAVE_ZLIB_H
#include <zlib.h> /* for content-encoding 08/28/02 jhrg */
@@ -214,6 +214,14 @@ struct ConnectBits {
IP address */
bool use_range;
bool rangestringalloc; /* the range string is malloc()'ed */
bool do_more; /* this is set TRUE if the ->curl_do_more() function is
supposed to be called, after ->curl_do() */
bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
on upload */
bool getheader; /* TRUE if header parsing is wanted */
};
/*
@@ -229,7 +237,12 @@ struct Curl_transfer_keeper {
struct timeval start; /* transfer started at this time */
struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */
bool badheader; /* the header was deemed bad and will be
enum {
HEADER_NORMAL, /* no bad header at all */
HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest is
normal data */
HEADER_ALLBAD /* all was believed to be header */
} badheader; /* the header was deemed bad and will be
written as body */
int headerline; /* counts header lines to better track the
first one */
@@ -280,6 +293,8 @@ struct Curl_transfer_keeper {
fd_set wkeepfd;
int keepon;
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
and we're uploading the last chunk */
};
@@ -306,8 +321,11 @@ struct connectdata {
#define PROT_FTPS (1<<9)
#define PROT_SSL (1<<10) /* protocol requires SSL */
/* the particular host we use, in two different ways */
struct Curl_dns_entry *connect_addr;
#ifdef ENABLE_IPV6
struct addrinfo *serv_addr; /* the particular host we use */
struct addrinfo *serv_addr;
#else
struct sockaddr_in serv_addr;
#endif
@@ -371,7 +389,6 @@ struct connectdata {
/* READ stuff */
int sockfd; /* socket to read from or -1 */
int size; /* -1 if unknown at this point */
bool getheader; /* TRUE if header parsing is wanted */
long *bytecountp; /* return number of bytes read or NULL */
/* WRITE stuff */
@@ -439,9 +456,6 @@ struct connectdata {
and the 'upload_present' contains the number of bytes available at this
position */
char *upload_fromhere;
bool do_more; /* this is set TRUE if the ->curl_do_more() function is
supposed to be called, after ->curl_do() */
};
/* The end of connectdata. 08/27/02 jhrg */
@@ -582,6 +596,8 @@ struct DynamicStatic {
bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by
curl_easy_setopt(COOKIEFILE) calls */
};
/*

View File

@@ -35,6 +35,10 @@ mv $HEADER.new $HEADER
# Replace version number in header file:
sed 's/#define CURL_VERSION.*/#define CURL_VERSION "'$curlversion'"/g' $CHEADER >$CHEADER.new
echo "curl version $curlversion"
echo "libcurl version $libversion"
echo "libcurl numerical $numeric"
# Save old header file
cp -p $CHEADER $CHEADER.old
@@ -83,6 +87,9 @@ fi
#
make html
# And the PDF versions
make pdf
############################################################################
#
# Now run make dist to generate a tar.gz archive

View File

@@ -21,22 +21,22 @@ cygwinbin:
rm -rf $(cygwintmp)
rm -rf $(cygwintmp)-dev
$(MAKE) -C $(top_builddir) DESTDIR=$(cygwintmp) install-strip
# $(STRIP) $(cygwintmp)/usr/bin/cygcurl-?.dll
# $(STRIP) $(cygwintmp)/usr/bin/cygcurl-?.dll
$(mkinstalldirs) \
$(cygwintmp)/usr/doc/Cygwin \
$(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION) \
$(cygwintmp)-dev/usr/doc/$(PACKAGE)-$(VERSION)/libcurl \
$(cygwintmp)-dev/usr/doc/$(PACKAGE)-$(VERSION)/examples \
$(cygwintmp)-dev/usr/man
#
# copy some files into the binary install dir
#
# copy some files into the binary install dir
cp $(srcdir)/README \
$(cygwintmp)/usr/doc/Cygwin/$(PACKAGE)-$(VERSION)-$(CYGBUILD).README
cd $(top_srcdir) ; cp CHANGES COPYING README UPGRADE docs/* \
$(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION) ; pwd
cd $(cygwintmp)/usr/doc/$(PACKAGE)-$(VERSION) ; rm *.1 Makefile*
#
# copy some files into the -dev install dir, remove some from binary
#
# copy some files into the -dev install dir, remove some from binary
cp $(top_srcdir)/docs/libcurl/*.html \
$(cygwintmp)-dev/usr/doc/$(PACKAGE)-$(VERSION)/libcurl
cp $(top_srcdir)/docs/examples/* \
@@ -51,12 +51,12 @@ cygwinbin:
mv $(cygwintmp)/usr/include $(cygwintmp)-dev/usr
mv $(cygwintmp)/usr/lib $(cygwintmp)-dev/usr
mv $(cygwintmp)/usr/man/man3 $(cygwintmp)-dev/usr/man
#
# create both tar files, and delete tmp folders
#
# create both tar files, and delete tmp folders
cd $(cygwintmp) ; tar cjf \
$(PACKAGE)-$(VERSION)-$(CYGBUILD).tar.bz2 usr
mv $(cygwintmp)/*.tar.bz2 . && rm -rf $(cygwintmp)
#
#
cd $(cygwintmp)-dev ; tar cjf \
$(PACKAGE)-devel-$(VERSION)-$(CYGBUILD).tar.bz2 usr
mv $(cygwintmp)-dev/*.tar.bz2 . && rm -rf $(cygwintmp)-dev

View File

@@ -1,7 +1,7 @@
#############################################################
# $Id$
#
## Makefile for building curl.exe with MingW32 (GCC-2.95) and
## Makefile for building curl.exe with MingW32 (GCC-3.2) and
## optionally OpenSSL (0.9.6)
##
## Use: make -f Makefile.m32 [SSL=1] [DYN=1]
@@ -10,8 +10,9 @@
## Joern Hartroth <hartroth@acm.org>
CC = gcc
RM = rm -f
STRIP = strip -s
OPENSSL_PATH = ../../openssl-0.9.6d
OPENSSL_PATH = ../../openssl-0.9.6g
ZLIB_PATH = ../../zlib-1.1.3
# We may need these someday
@@ -23,6 +24,9 @@ ZLIB_PATH = ../../zlib-1.1.3
INCLUDES = -I. -I.. -I../include
CFLAGS = -g -O2 -DMINGW32
ifdef SSL
CFLAGS += -DUSE_SSLEAY
endif
LDFLAGS =
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
@@ -52,13 +56,13 @@ OBJECTS = $(curl_OBJECTS)
all: curl.exe
curl.exe: $(curl_OBJECTS) $(curl_DEPENDENCIES)
-@erase $@
$(RM) $@
$(LINK) $(curl_OBJECTS) $(curl_LDADD)
$(STRIP) $@
# We don't have nroff normally under win32
# hugehelp.c: ../README.curl ../curl.1 mkhelp.pl
# -@erase hugehelp.c
# $(RM) hugehelp.c
# $(NROFF) -man ../curl.1 | $(PERL) mkhelp.pl ../README.curl > hugehelp.c
.c.o:
@@ -71,7 +75,7 @@ curl.exe: $(curl_OBJECTS) $(curl_DEPENDENCIES)
$(COMPILE) -c $<
clean:
-@erase $(curl_OBJECTS)
$(RM) $(curl_OBJECTS)
distrib: clean
-@erase $(curl_PROGRAMS)
$(RM) $(curl_PROGRAMS)

View File

@@ -1774,7 +1774,7 @@ static int parseconfig(const char *filename,
case '\n':
case '*':
case '\0':
free(line);
free(aline);
continue;
}
@@ -2149,6 +2149,7 @@ void dump(const char *text,
}
fputc('\n', stream); /* newline */
}
fflush(stream);
}
static
@@ -2245,6 +2246,41 @@ void free_config_fields(struct Configurable *config)
curl_slist_free_all(config->headers); /* */
}
#if defined(WIN32) && !defined(__CYGWIN32__)
/* Function to find CACert bundle on a Win32 platform using SearchPath.
* (SearchPath is defined in windows.h, which is #included into libcurl)
* (Use the ASCII version instead of the unicode one!)
* The order of the directories it searches is:
* 1. application's directory
* 2. current working directory
* 3. Windows System directory (e.g. C:\windows\system32)
* 4. Windows Directory (e.g. C:\windows)
* 5. all directories along %PATH%
*/
static void FindWin32CACert(struct Configurable *config,
const char *bundle_file)
{
curl_version_info_data *info;
info = curl_version_info(CURLVERSION_NOW);
/* only check for cert file if "we" support SSL */
if(info->features & CURL_VERSION_SSL) {
DWORD buflen;
char *ptr = NULL;
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
if (!retval)
return;
retval[0] = '\0';
buflen = SearchPathA(NULL, bundle_file, NULL, MAX_PATH+2, retval, &ptr);
if (buflen > 0) {
GetStr(&config->cacert, retval);
}
free(retval);
}
}
#endif
static int
operate(struct Configurable *config, int argc, char *argv[])
@@ -2280,9 +2316,9 @@ operate(struct Configurable *config, int argc, char *argv[])
int res = 0;
int i;
char *env;
#ifdef MALLOCDEBUG
/* this sends all memory debug messages to a logfile named memdump */
char *env;
env = curl_getenv("CURL_MEMDEBUG");
if(env) {
free(env);
@@ -2384,6 +2420,27 @@ operate(struct Configurable *config, int argc, char *argv[])
else
allocuseragent = TRUE;
/* On WIN32 (non-cygwin), we can't set the path to curl-ca-bundle.crt
* at compile time. So we look here for the file in two ways:
* 1: look at the environment variable CURL_CA_BUNDLE for a path
* 2: if #1 isn't found, use the windows API function SearchPath()
* to find it along the app's path (includes app's dir and CWD)
*
* We support the environment variable thing for non-Windows platforms
* too. Just for the sake of it.
*/
if (! config->cacert) {
env = curl_getenv("CURL_CA_BUNDLE");
if(env) {
GetStr(&config->cacert, env);
free(env);
}
}
#if defined(WIN32) && !defined(__CYGWIN32__)
if (! config->cacert)
FindWin32CACert(config, "curl-ca-bundle.crt");
#endif
if (config->postfields) {
if (config->use_httpget) {
/* Use the postfields data for a http get */

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl"
#define CURL_VERSION "7.10.1"
#define CURL_VERSION "7.10.2"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "

View File

@@ -17,4 +17,4 @@ test106 test115 test124 test190 test25 test303 test44 test38 \
test107 test116 test125 test2 test26 test33 test45 test126 \
test304 test39 test32 test128 test48 test306 \
test130 test131 test132 test133 test134 test135 test403 test305 \
test49 test50 test51 test52
test49 test50 test51 test52 test53 test54 test55

42
tests/data/test53 Normal file
View File

@@ -0,0 +1,42 @@
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Tue, 25 Sep 2001 19:37:44 GMT
Content-Type: text/html
Connection: close
This server says moo
</data>
</reply>
# Client-side
<client>
<name>
HTTP, junk session cookies
</name>
<command>
%HOSTIP:%HOSTPORT/want/53 -b log/injar53 -j
</command>
<file name="log/injar53">
127.0.0.1 FALSE / FALSE 2139150993 mooo indeed
127.0.0.1 FALSE / FALSE 0 moo1 indeed
127.0.0.1 FALSE / FALSE 1 moo2 indeed
</file>
</client>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /want/53 HTTP/1.1
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Cookie: mooo=indeed
</protocol>
</verify>

34
tests/data/test54 Normal file
View File

@@ -0,0 +1,34 @@
# Server-side
<reply>
<data>
HTTP/1.1 302 This is a weirdo text message
Connection: close
Location:
This server reply is for testing
</data>
</reply>
# Client-side
<client>
<name>
HTTP with blank Location:
</name>
<command>
http://%HOSTIP:%HOSTPORT/want/54 -L
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /want/54 HTTP/1.1
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
</protocol>
</verify>

56
tests/data/test55 Normal file
View File

@@ -0,0 +1,56 @@
<reply>
<data>
HTTP/1.1 302 OK
Location: 550002
Date: Thu, 09 Nov 2010 14:50:00 GMT
Connection: close
</data>
<data2>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:50:00 GMT
Connection: close
body
</data2>
<datacheck>
HTTP/1.1 302 OK
Location: 550002
Date: Thu, 09 Nov 2010 14:50:00 GMT
Connection: close
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:50:00 GMT
Connection: close
body
</datacheck>
</reply>
<client>
<name>
HTTP follow redirect with single slash in path
</name>
<command>
http://%HOSTIP:%HOSTPORT/55 -L
</command>
</client>
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /55 HTTP/1.1
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
GET /550002 HTTP/1.1
User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
</protocol>
</verify>

View File

@@ -1,7 +1,7 @@
#!/usr/bin/perl
#
# $Id$
# This is the HTTPS server designed for the curl test suite.
# This is the FTPS server designed for the curl test suite.
#
# It is actually just a layer that runs stunnel properly.
@@ -23,14 +23,14 @@ if(!$stunnel) {
my $verbose=0; # set to 1 for debugging
my $port = 8821; # just our default, weird enough
my $ftp = 8921; # test ftp-server port
my $port = 8821; # just our default, weird enough
my $remote_port = 8921; # test ftp-server port
do {
if($ARGV[0] eq "-v") {
$verbose=1;
}
elsif($ARGV[0] eq "-r") {
$ftp=$ARGV[1];
$remote_port=$ARGV[1];
shift @ARGV;
}
elsif($ARGV[0] =~ /^(\d+)$/) {
@@ -40,9 +40,40 @@ do {
my $path = `pwd`;
chomp $path;
my $cmd = "$stunnel -p $path/stunnel.pem -P $path/.ftps.pid -d $port -r $ftp";
my $conffile="$path/stunnel.conf"; # stunnel configuration data
my $certfile="$path/stunnel.pem"; # stunnel server certificate
my $pidfile="$path/.ftps.pid"; # stunnel process pid file
open(CONF, ">$conffile") || return 1;
print CONF "
CApath=$path
cert = $certfile
pid = $pidfile
debug = 0
output = /dev/null
foreground = yes
[curltest]
accept = $port
connect = $remote_port
";
close CONF;
system("chmod go-rwx $conffile $path/stunnel.pem"); # secure permissions
# works only with stunnel versions < 4.00
my $cmd="$stunnel -p $certfile -P $pidfile -d $port -r $remote_port 2>/dev/null";
# use some heuristics to determine stunnel version
my $version_ge_4=system("$stunnel -V 2>&1|grep '^stunnel.* on '>/dev/null 2>&1");
# works only with stunnel versions >= 4.00
if ($version_ge_4) { $cmd="$stunnel $conffile"; }
if($verbose) {
print "FTPS server: $cmd\n";
}
system($cmd);
unlink $conffile;

View File

@@ -23,8 +23,8 @@ if(!$stunnel) {
my $verbose=0; # set to 1 for debugging
my $port = 8433; # just a default
my $http = 8999; # http-port
my $port = 8433; # just our default, weird enough
my $target_port = 8999; # test http-server port
do {
if($ARGV[0] eq "-v") {
$verbose=1;
@@ -33,7 +33,7 @@ do {
return 0; # return success, means we have stunnel working!
}
elsif($ARGV[0] eq "-r") {
$http=$ARGV[1];
$target_port=$ARGV[1];
shift @ARGV;
}
elsif($ARGV[0] =~ /^(\d+)$/) {
@@ -43,9 +43,39 @@ do {
my $path = `pwd`;
chomp $path;
my $cmd = "$stunnel -p $path/stunnel.pem -P $path/.https.pid -d $port -r $http";
my $conffile="$path/stunnel.conf"; # stunnel configuration data
my $certfile="$path/stunnel.pem"; # stunnel server certificate
my $pidfile="$path/.https.pid"; # stunnel process pid file
open(CONF, ">$conffile") || return 1;
print CONF "
CApath=$path
cert = $certfile
pid = $pidfile
debug = 0
output = /dev/null
foreground = yes
[curltest]
accept = $port
connect = $target_port
";
close CONF;
system("chmod go-rwx $conffile $path/stunnel.pem"); # secure permissions
# works only with stunnel versions < 4.00
my $cmd="$stunnel -p $certfile -P $pidfile -d $port -r $target_port 2>/dev/null";
# use some heuristics to determine stunnel version
my $version_ge_4=system("$stunnel -V 2>&1|grep '^stunnel.* on '>/dev/null 2>&1");
# works only with stunnel versions >= 4.00
if ($version_ge_4) { $cmd="$stunnel $conffile"; }
if($verbose) {
print "$cmd\n";
print "HTTPS server: $cmd\n";
}
system($cmd);
unlink $conffile;

View File

@@ -506,7 +506,7 @@ sub singletest {
# name of the test
my @testname= getpart("client", "name");
print "test $testnum...";
printf("test %03d...", $testnum);
if(!$short) {
my $name = $testname[0];
$name =~ s/\n//g;