Compare commits
326 Commits
curl-7_10_
...
curl-7_10_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bdb5e5a250 | ||
![]() |
48a580e609 | ||
![]() |
1361fc69b9 | ||
![]() |
93352e56d8 | ||
![]() |
d9246ff24d | ||
![]() |
9301bc3444 | ||
![]() |
76352c4e2d | ||
![]() |
428f41bd12 | ||
![]() |
99c32e460f | ||
![]() |
83f249cf65 | ||
![]() |
2c2baa93ea | ||
![]() |
f0278ca114 | ||
![]() |
297b1b5013 | ||
![]() |
e9f63bf4e8 | ||
![]() |
556ce1c6a1 | ||
![]() |
cc4ff62681 | ||
![]() |
0423fd9b55 | ||
![]() |
789ab20bf7 | ||
![]() |
b47462bd68 | ||
![]() |
1a94fee42d | ||
![]() |
a91ce6a5d6 | ||
![]() |
981ffd9fce | ||
![]() |
e76c960624 | ||
![]() |
416c92cc6f | ||
![]() |
fb731eb3e7 | ||
![]() |
6f2a4d290f | ||
![]() |
cefc8ba938 | ||
![]() |
d0bd644eef | ||
![]() |
071c95128e | ||
![]() |
1a192c489b | ||
![]() |
56014e74a0 | ||
![]() |
172271498d | ||
![]() |
f2882cb88c | ||
![]() |
152f1fee40 | ||
![]() |
968234e6ae | ||
![]() |
5e133e2dff | ||
![]() |
0049c09fc3 | ||
![]() |
a2a63c27f4 | ||
![]() |
c50a601f1a | ||
![]() |
bc0fd6db71 | ||
![]() |
52b631fade | ||
![]() |
2f0bc9d1f7 | ||
![]() |
5ef6520d4e | ||
![]() |
2c1925161e | ||
![]() |
0529b349d5 | ||
![]() |
b4620364a2 | ||
![]() |
634aef3895 | ||
![]() |
06c86d1a8c | ||
![]() |
79749f8eb4 | ||
![]() |
b036986b3e | ||
![]() |
938f1d1da7 | ||
![]() |
58b6b3df06 | ||
![]() |
f9c3347f7c | ||
![]() |
5b72eb0b03 | ||
![]() |
6dd4c13bc0 | ||
![]() |
e4e7db551f | ||
![]() |
ebfde8da56 | ||
![]() |
756bc0f4b7 | ||
![]() |
269d491b6a | ||
![]() |
449e5bc2ad | ||
![]() |
8736c11d84 | ||
![]() |
45fc760985 | ||
![]() |
7968e3c2de | ||
![]() |
964a41c75c | ||
![]() |
5931d53637 | ||
![]() |
3ed3ae5bcf | ||
![]() |
6519cc70c5 | ||
![]() |
505a4f27fa | ||
![]() |
79144eba99 | ||
![]() |
26e17d89c9 | ||
![]() |
4322c1106f | ||
![]() |
73071dfd4f | ||
![]() |
b7c14b3c27 | ||
![]() |
3130b44535 | ||
![]() |
a2bd73334f | ||
![]() |
1a393f5625 | ||
![]() |
d4951e837e | ||
![]() |
26f6365e93 | ||
![]() |
3a552b1e63 | ||
![]() |
69eb1790da | ||
![]() |
a1af6f3614 | ||
![]() |
3aced61465 | ||
![]() |
6f02ddfce8 | ||
![]() |
c2faa39b62 | ||
![]() |
2d3734b8b5 | ||
![]() |
ed908b7f89 | ||
![]() |
f7d795a364 | ||
![]() |
8919b39d54 | ||
![]() |
84cedc094e | ||
![]() |
3b2b2496d7 | ||
![]() |
445684c409 | ||
![]() |
898e067ccc | ||
![]() |
12859e345f | ||
![]() |
89f4af695e | ||
![]() |
308bc9d919 | ||
![]() |
db566c54ae | ||
![]() |
81d403e207 | ||
![]() |
2bd71d70ff | ||
![]() |
1eef6f44ba | ||
![]() |
204f03912f | ||
![]() |
f8c3b3aa18 | ||
![]() |
d4df981463 | ||
![]() |
497c6d516d | ||
![]() |
8288862b7e | ||
![]() |
9aae16c236 | ||
![]() |
80c194a70a | ||
![]() |
c832b2db5b | ||
![]() |
27018882ec | ||
![]() |
caf6e9c540 | ||
![]() |
e727fb82f2 | ||
![]() |
c78df56801 | ||
![]() |
d13202f43b | ||
![]() |
9d139a6b35 | ||
![]() |
d2abe44e6f | ||
![]() |
bc67228576 | ||
![]() |
ecf32c964a | ||
![]() |
e58f30b82a | ||
![]() |
654e3f1101 | ||
![]() |
86689dc524 | ||
![]() |
5f62a0c1ca | ||
![]() |
ad1bf0f389 | ||
![]() |
9c7703ace1 | ||
![]() |
4a8155b53c | ||
![]() |
80d6d5c5c4 | ||
![]() |
c624be8388 | ||
![]() |
09df1cd41e | ||
![]() |
52c5b57200 | ||
![]() |
5ea04a852e | ||
![]() |
a2eef05198 | ||
![]() |
55f75af353 | ||
![]() |
fb6a51b8fd | ||
![]() |
252cc2213e | ||
![]() |
73c5f24fa4 | ||
![]() |
4c80e103a0 | ||
![]() |
39ea557360 | ||
![]() |
d0cc92a01a | ||
![]() |
d7980c1a45 | ||
![]() |
e56ae1426c | ||
![]() |
696843c020 | ||
![]() |
6ff5621dd7 | ||
![]() |
e7fb72a732 | ||
![]() |
8d30d34e0c | ||
![]() |
bc7fe85f8a | ||
![]() |
89352d92c5 | ||
![]() |
c32390d84c | ||
![]() |
45ca866a2d | ||
![]() |
ceef206c21 | ||
![]() |
7c6424f0a9 | ||
![]() |
bc942de6f1 | ||
![]() |
06984df5cb | ||
![]() |
4f136a3a76 | ||
![]() |
363bf3ba30 | ||
![]() |
acb895956a | ||
![]() |
21e87b9bb3 | ||
![]() |
c896ebcf12 | ||
![]() |
d288222e80 | ||
![]() |
4eb2a6c9a3 | ||
![]() |
2563731c4d | ||
![]() |
4e410111db | ||
![]() |
5670563a26 | ||
![]() |
6caa656d01 | ||
![]() |
c12af7aed1 | ||
![]() |
dcb6d1c01d | ||
![]() |
18234cbdac | ||
![]() |
06bf988dc1 | ||
![]() |
55ff4c3f08 | ||
![]() |
4915002168 | ||
![]() |
5bd8d60e41 | ||
![]() |
fc872808c5 | ||
![]() |
0f4feda382 | ||
![]() |
90b0f38316 | ||
![]() |
18f630ab21 | ||
![]() |
e97fd44151 | ||
![]() |
b75679778f | ||
![]() |
35a84ad576 | ||
![]() |
4ed28be75a | ||
![]() |
e2f4656a86 | ||
![]() |
1e14da5c60 | ||
![]() |
b2ef79ef3d | ||
![]() |
f488874ff5 | ||
![]() |
23258648da | ||
![]() |
6b84ebe501 | ||
![]() |
07dd067f73 | ||
![]() |
420744d048 | ||
![]() |
01108e3a63 | ||
![]() |
8026b1e194 | ||
![]() |
a39d77227f | ||
![]() |
9f69deec7d | ||
![]() |
e912f772e0 | ||
![]() |
0102726aeb | ||
![]() |
1e7aa04040 | ||
![]() |
00a7c6fe6b | ||
![]() |
87f8c0d471 | ||
![]() |
334d78cd18 | ||
![]() |
2356325592 | ||
![]() |
d78ec593fa | ||
![]() |
d5043133e6 | ||
![]() |
509f69a457 | ||
![]() |
662c659220 | ||
![]() |
9a6566e774 | ||
![]() |
4da0428d9e | ||
![]() |
8ee1177206 | ||
![]() |
e9154b2549 | ||
![]() |
d398a0dd58 | ||
![]() |
7723a24297 | ||
![]() |
95a4b8db68 | ||
![]() |
663c1898a3 | ||
![]() |
465de793e8 | ||
![]() |
de9b76cef0 | ||
![]() |
1747a8d3d9 | ||
![]() |
1094e79749 | ||
![]() |
22569681bc | ||
![]() |
e615d117a0 | ||
![]() |
a51258b6bb | ||
![]() |
8894bd07b6 | ||
![]() |
ec45a9e825 | ||
![]() |
871358a6e5 | ||
![]() |
2e2e0fba60 | ||
![]() |
4a5139e3f4 | ||
![]() |
8f85933d7c | ||
![]() |
246f3a63f6 | ||
![]() |
e99eff4eb0 | ||
![]() |
c0197f19cf | ||
![]() |
3994d67eea | ||
![]() |
9ead79c9d4 | ||
![]() |
9371aed46c | ||
![]() |
940707ad66 | ||
![]() |
e6c267fb4c | ||
![]() |
93538fccd6 | ||
![]() |
83a7fad308 | ||
![]() |
3c7e33388e | ||
![]() |
7b0f35edb6 | ||
![]() |
94a157d0b0 | ||
![]() |
ca04620253 | ||
![]() |
073ef0b36a | ||
![]() |
c41c05d4f4 | ||
![]() |
f1ea54e07a | ||
![]() |
a139ce901a | ||
![]() |
7431957113 | ||
![]() |
1752d80915 | ||
![]() |
aa7420e109 | ||
![]() |
a290d4b9db | ||
![]() |
19a4314e7f | ||
![]() |
d166e85e0a | ||
![]() |
f213e857ab | ||
![]() |
eb6130baa7 | ||
![]() |
f69ea2c68a | ||
![]() |
078441d477 | ||
![]() |
95f6b15a67 | ||
![]() |
ee29dbdb8f | ||
![]() |
15f3f4c93f | ||
![]() |
6932e94e0e | ||
![]() |
3ef06d7efe | ||
![]() |
fb012b48e9 | ||
![]() |
bc77bf217f | ||
![]() |
37d1e9351e | ||
![]() |
4494c0dee0 | ||
![]() |
26afc604ac | ||
![]() |
9aefcada19 | ||
![]() |
69fc363760 | ||
![]() |
bea02ddebe | ||
![]() |
3fb257c39c | ||
![]() |
7c96c5a39b | ||
![]() |
efd836d971 | ||
![]() |
836aaa1647 | ||
![]() |
bf2b3dbf3e | ||
![]() |
b4fa2ff995 | ||
![]() |
2f9cabc30b | ||
![]() |
63593f5597 | ||
![]() |
c0acaa5d2c | ||
![]() |
2e46f8d0a6 | ||
![]() |
51da6aaa07 | ||
![]() |
c8b79e36db | ||
![]() |
208374bcc9 | ||
![]() |
7f0a6e7203 | ||
![]() |
54ebb9cfd4 | ||
![]() |
49e9c1495b | ||
![]() |
a84b0fbd52 | ||
![]() |
c95814c04d | ||
![]() |
9f8123f1b8 | ||
![]() |
8b23db4f4d | ||
![]() |
d77cc13374 | ||
![]() |
9a12db1aa2 | ||
![]() |
eb54d34bec | ||
![]() |
4b1203d4c9 | ||
![]() |
183a9c6244 | ||
![]() |
1f2294d585 | ||
![]() |
0b839c4f77 | ||
![]() |
1d4fd1fcae | ||
![]() |
b1d8d72c16 | ||
![]() |
bafb68b844 | ||
![]() |
21873b52e9 | ||
![]() |
0aa8b82871 | ||
![]() |
f9781afafd | ||
![]() |
fece361a55 | ||
![]() |
7b51b2f128 | ||
![]() |
22d88fb28e | ||
![]() |
f7c5b28e76 | ||
![]() |
5760f2a307 | ||
![]() |
ee46efb5a5 | ||
![]() |
eb6ffebfc7 | ||
![]() |
c06c44f286 | ||
![]() |
019c4088cf | ||
![]() |
0b0a88b78d | ||
![]() |
028e9cc56f | ||
![]() |
e0d8615ece | ||
![]() |
c8ecbda40b | ||
![]() |
2324c10d43 | ||
![]() |
89cfa76291 | ||
![]() |
072070a22c | ||
![]() |
3c3ad134ea | ||
![]() |
a4ffcfd4d5 | ||
![]() |
136670c58a | ||
![]() |
28169725fa | ||
![]() |
5b13106f54 | ||
![]() |
1a2db0dfb1 | ||
![]() |
696f95bb0a | ||
![]() |
acec588fe3 | ||
![]() |
6ed0da8e98 | ||
![]() |
7fd91d70bd | ||
![]() |
61788a0389 | ||
![]() |
0821447b5b | ||
![]() |
3cba274ba6 | ||
![]() |
df7bbcfd21 | ||
![]() |
021d406f0c | ||
![]() |
294569c502 |
@@ -9,3 +9,6 @@ config.status
|
|||||||
curl-config
|
curl-config
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
depcomp
|
depcomp
|
||||||
|
config.guess
|
||||||
|
config.sub
|
||||||
|
ltmain.sh
|
||||||
|
1504
CHANGES.2002
Normal file
1504
CHANGES.2002
Normal file
File diff suppressed because it is too large
Load Diff
10
CVS-INFO
10
CVS-INFO
@@ -16,8 +16,8 @@ Compile and build instructions follow below.
|
|||||||
CHANGES.$year contains changes for the particular year.
|
CHANGES.$year contains changes for the particular year.
|
||||||
|
|
||||||
tests/memanalyze.pl
|
tests/memanalyze.pl
|
||||||
is for analyzing the output generated by curl if -DMALLOCDEBUG
|
is for analyzing the output generated by curl if -DCURLDEBUG
|
||||||
is used when compiling
|
is used when compiling (run configure with --enable-debug)
|
||||||
|
|
||||||
buildconf builds the makefiles and configure stuff
|
buildconf builds the makefiles and configure stuff
|
||||||
|
|
||||||
@@ -40,9 +40,9 @@ REQUIREMENTS
|
|||||||
|
|
||||||
You need the following software installed:
|
You need the following software installed:
|
||||||
|
|
||||||
o autoconf 2.50 (or later)
|
o autoconf 2.57 (or later)
|
||||||
o automake 1.5 (or later)
|
o automake 1.7 (or later)
|
||||||
o libtool 1.4 (or later)
|
o libtool 1.4.2 (or later)
|
||||||
o GNU m4 (required by autoconf)
|
o GNU m4 (required by autoconf)
|
||||||
|
|
||||||
o nroff + perl
|
o nroff + perl
|
||||||
|
14
Makefile.am
14
Makefile.am
@@ -4,12 +4,13 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
EXTRA_DIST = CHANGES COPYING maketgz SSLCERTS reconf Makefile.dist \
|
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
|
||||||
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh
|
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh
|
||||||
|
|
||||||
bin_SCRIPTS = curl-config
|
bin_SCRIPTS = curl-config
|
||||||
|
|
||||||
SUBDIRS = docs lib src include tests packages
|
SUBDIRS = lib src
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS) tests include packages docs
|
||||||
|
|
||||||
# create a root makefile in the distribution:
|
# create a root makefile in the distribution:
|
||||||
dist-hook:
|
dist-hook:
|
||||||
@@ -25,10 +26,10 @@ pdf:
|
|||||||
check: test
|
check: test
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@(cd tests; $(MAKE) quiet-test)
|
@(cd tests; $(MAKE) all quiet-test)
|
||||||
|
|
||||||
test-full:
|
test-full:
|
||||||
@(cd tests; $(MAKE) full-test)
|
@(cd tests; $(MAKE) all full-test)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
|
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
|
||||||
@@ -77,3 +78,8 @@ pkgadd:
|
|||||||
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
|
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
|
||||||
cygwinbin:
|
cygwinbin:
|
||||||
$(MAKE) -C packages/Win32/cygwin cygwinbin
|
$(MAKE) -C packages/Win32/cygwin cygwinbin
|
||||||
|
|
||||||
|
# We extend the standard install with a custom hook:
|
||||||
|
install-data-hook:
|
||||||
|
cd include && $(MAKE) install
|
||||||
|
cd docs && $(MAKE) install
|
||||||
|
@@ -59,6 +59,10 @@ vc-ssl-dll:
|
|||||||
cd ..\src
|
cd ..\src
|
||||||
nmake -f Makefile.vc6
|
nmake -f Makefile.vc6
|
||||||
|
|
||||||
|
djgpp:
|
||||||
|
make -C lib -f Makefile.dj
|
||||||
|
make -C src -f Makefile.dj
|
||||||
|
|
||||||
cygwin:
|
cygwin:
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
|
8
README
8
README
@@ -49,15 +49,15 @@ CVS
|
|||||||
|
|
||||||
To download the very latest source off the CVS server do this:
|
To download the very latest source off the CVS server do this:
|
||||||
|
|
||||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl login
|
cvs -d :pserver:cvsread@cvs.php.net:/repository login
|
||||||
|
|
||||||
(just press enter when asked for password)
|
(enter "phpfi" when asked for password)
|
||||||
|
|
||||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl co curl
|
cvs -d :pserver:cvsread@cvs.php.net:/repository co curl
|
||||||
|
|
||||||
(you'll get a directory named curl created, filled with the source code)
|
(you'll get a directory named curl created, filled with the source code)
|
||||||
|
|
||||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl logout
|
cvs -d :pserver:cvsread@cvs.php.net:/repository logout
|
||||||
|
|
||||||
(you're off the hook!)
|
(you're off the hook!)
|
||||||
|
|
||||||
|
@@ -152,10 +152,8 @@ AC_DEFUN([TYPE_IN_ADDR_T],
|
|||||||
AC_MSG_CHECKING([for in_addr_t equivalent])
|
AC_MSG_CHECKING([for in_addr_t equivalent])
|
||||||
AC_CACHE_VAL([curl_cv_in_addr_t_equiv],
|
AC_CACHE_VAL([curl_cv_in_addr_t_equiv],
|
||||||
[
|
[
|
||||||
# Systems have either "struct sockaddr *" or
|
|
||||||
# "void *" as the second argument to getpeername
|
|
||||||
curl_cv_in_addr_t_equiv=
|
curl_cv_in_addr_t_equiv=
|
||||||
for t in int size_t unsigned long "unsigned long"; do
|
for t in "unsigned long" int size_t unsigned long; do
|
||||||
AC_TRY_COMPILE([
|
AC_TRY_COMPILE([
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
51
buildconf
51
buildconf
@@ -6,18 +6,19 @@ die(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# autoconf 2.50 or newer
|
# autoconf 2.57 or newer
|
||||||
#
|
#
|
||||||
|
need_autoconf="2.57"
|
||||||
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||||
if test -z "$ac_version"; then
|
if test -z "$ac_version"; then
|
||||||
echo "buildconf: autoconf not found."
|
echo "buildconf: autoconf not found."
|
||||||
echo " You need autoconf version 2.50 or newer installed."
|
echo " You need autoconf version $need_autoconf or newer installed."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
IFS=.; set $ac_version; IFS=' '
|
IFS=.; set $ac_version; IFS=' '
|
||||||
if test "$1" = "2" -a "$2" -lt "50" || test "$1" -lt "2"; then
|
if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then
|
||||||
echo "buildconf: autoconf version $ac_version found."
|
echo "buildconf: autoconf version $ac_version found."
|
||||||
echo " You need autoconf version 2.50 or newer installed."
|
echo " You need autoconf version $need_autoconf or newer installed."
|
||||||
echo " If you have a sufficient autoconf installed, but it"
|
echo " If you have a sufficient autoconf installed, but it"
|
||||||
echo " is not named 'autoconf', then try setting the"
|
echo " is not named 'autoconf', then try setting the"
|
||||||
echo " AUTOCONF environment variable."
|
echo " AUTOCONF environment variable."
|
||||||
@@ -48,18 +49,19 @@ fi
|
|||||||
echo "buildconf: autoheader version $ah_version (ok)"
|
echo "buildconf: autoheader version $ah_version (ok)"
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# automake 1.5 or newer
|
# automake 1.7 or newer
|
||||||
#
|
#
|
||||||
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
need_automake="1.7"
|
||||||
|
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
||||||
if test -z "$am_version"; then
|
if test -z "$am_version"; then
|
||||||
echo "buildconf: automake not found."
|
echo "buildconf: automake not found."
|
||||||
echo " You need automake version 1.5 or newer installed."
|
echo " You need automake version $need_automake or newer installed."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
IFS=.; set $am_version; IFS=' '
|
IFS=.; set $am_version; IFS=' '
|
||||||
if test "$1" = "1" -a "$2" -lt "5" || test "$1" -lt "1"; then
|
if test "$1" = "1" -a "$2" -lt "7" || test "$1" -lt "1"; then
|
||||||
echo "buildconf: automake version $am_version found."
|
echo "buildconf: automake version $am_version found."
|
||||||
echo " You need automake version 1.5 or newer installed."
|
echo " You need automake version $need_automake or newer installed."
|
||||||
echo " If you have a sufficient automake installed, but it"
|
echo " If you have a sufficient automake installed, but it"
|
||||||
echo " is not named 'autommake', then try setting the"
|
echo " is not named 'autommake', then try setting the"
|
||||||
echo " AUTOMAKE environment variable."
|
echo " AUTOMAKE environment variable."
|
||||||
@@ -68,35 +70,39 @@ fi
|
|||||||
|
|
||||||
echo "buildconf: automake version $am_version (ok)"
|
echo "buildconf: automake version $am_version (ok)"
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# libtool 1.4 or newer
|
# libtool check
|
||||||
#
|
#
|
||||||
LIBTOOL_WANTED_MAJOR=1
|
LIBTOOL_WANTED_MAJOR=1
|
||||||
LIBTOOL_WANTED_MINOR=4
|
LIBTOOL_WANTED_MINOR=4
|
||||||
LIBTOOL_WANTED_PATCH=
|
LIBTOOL_WANTED_PATCH=2
|
||||||
LIBTOOL_WANTED_VERSION=1.4
|
LIBTOOL_WANTED_VERSION=1.4.2
|
||||||
|
|
||||||
libtool=`which glibtool 2>/dev/null`
|
libtool=`which glibtool 2>/dev/null`
|
||||||
if test ! -x "$libtool"; then
|
if test ! -x "$libtool"; then
|
||||||
libtool=`which libtool`
|
libtool=`which libtool`
|
||||||
fi
|
fi
|
||||||
lt_pversion=`$libtool --version 2>/dev/null|sed -e 's/^[^0-9]*//' -e 's/[- ].*//'`
|
#lt_pversion=`${LIBTOOL:-$libtool} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
||||||
|
lt_pversion=`$libtool --version 2>/dev/null|head -1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
|
||||||
if test -z "$lt_pversion"; then
|
if test -z "$lt_pversion"; then
|
||||||
echo "buildconf: libtool not found."
|
echo "buildconf: libtool not found."
|
||||||
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"
|
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
lt_version=`echo $lt_pversion|sed -e 's/\([a-z]*\)$/.\1/'`
|
lt_version=`echo $lt_pversion` #|sed -e 's/\([a-z]*\)$/.\1/'`
|
||||||
IFS=.; set $lt_version; IFS=' '
|
IFS=.; set $lt_version; IFS=' '
|
||||||
lt_status="good"
|
lt_status="good"
|
||||||
if test "$1" = "$LIBTOOL_WANTED_MAJOR"; then
|
if test "$1" = "$LIBTOOL_WANTED_MAJOR"; then
|
||||||
if test "$2" -lt "$LIBTOOL_WANTED_MINOR"; then
|
if test "$2" -lt "$LIBTOOL_WANTED_MINOR"; then
|
||||||
lt_status="bad"
|
lt_status="bad"
|
||||||
elif test ! -z "$LIBTOOL_WANTED_PATCH"; then
|
elif test ! -z "$LIBTOOL_WANTED_PATCH"; then
|
||||||
|
if test -n "$3"; then
|
||||||
if test "$3" -lt "$LIBTOOL_WANTED_PATCH"; then
|
if test "$3" -lt "$LIBTOOL_WANTED_PATCH"; then
|
||||||
lt_status="bad"
|
lt_status="bad"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if test $lt_status != "good"; then
|
if test $lt_status != "good"; then
|
||||||
echo "buildconf: libtool version $lt_pversion found."
|
echo "buildconf: libtool version $lt_pversion found."
|
||||||
@@ -104,15 +110,20 @@ if test $lt_status != "good"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "buildconf: libtool version $lt_pversion (ok)"
|
echo "buildconf: libtool version $lt_version (ok)"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
# run the correct scripts now
|
||||||
|
|
||||||
|
echo "buildconf: running libtoolize"
|
||||||
|
${LIBTOOLIZE:-libtoolize} --copy --automake || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake' failed"
|
||||||
echo "buildconf: running aclocal"
|
echo "buildconf: running aclocal"
|
||||||
aclocal || die "The command 'aclocal' failed"
|
${ACLOCAL:-aclocal} || die "The command '${AUTOHEADER:-aclocal}' failed"
|
||||||
echo "buildconf: running autoheader"
|
echo "buildconf: running autoheader"
|
||||||
autoheader || die "The command 'autoheader' failed"
|
${AUTOHEADER:-autoheader} || die "The command '${AUTOHEADER:-autoheader}' failed"
|
||||||
echo "buildconf: running autoconf"
|
echo "buildconf: running autoconf"
|
||||||
autoconf || die "The command 'autoconf' failed"
|
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||||
echo "buildconf: running automake"
|
echo "buildconf: running automake"
|
||||||
automake -a || die "The command 'automake -a' failed"
|
${AUTOMAKE:-automake} -a || die "The command '${AUTOMAKE:-automake} -a' failed"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
1363
config.guess
vendored
1363
config.guess
vendored
File diff suppressed because it is too large
Load Diff
1470
config.sub
vendored
1470
config.sub
vendored
File diff suppressed because it is too large
Load Diff
132
configure.ac
132
configure.ac
@@ -14,7 +14,7 @@ This configure script may be copied, distributed and modified under the
|
|||||||
terms of the curl license; see COPYING for more details])
|
terms of the curl license; see COPYING for more details])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([lib/urldata.h])
|
AC_CONFIG_SRCDIR([lib/urldata.h])
|
||||||
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h lib/ca-bundle.h)
|
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h )
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
||||||
@@ -349,15 +349,17 @@ dnl Check if the operating system allows programs to write to their own argv[]
|
|||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
AC_MSG_CHECKING([if argv can be written to])
|
AC_MSG_CHECKING([if argv can be written to])
|
||||||
AC_TRY_RUN([
|
AC_RUN_IFELSE([[
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
argv[0][0] = ' ';
|
argv[0][0] = ' ';
|
||||||
return (argv[0][0] == ' ')?0:1;
|
return (argv[0][0] == ' ')?0:1;
|
||||||
}
|
}
|
||||||
],
|
]],
|
||||||
AC_DEFINE(HAVE_WRITABLE_ARGV, 1, [Define this symbol if your OS supports changing the contents of argv])
|
AC_DEFINE(HAVE_WRITABLE_ARGV, 1, [Define this symbol if your OS supports changing the contents of argv])
|
||||||
AC_MSG_RESULT(yes),
|
AC_MSG_RESULT(yes),
|
||||||
|
AC_MSG_RESULT(no),
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
AC_MSG_WARN([the previous check could not be made default was used])
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -452,6 +454,63 @@ else
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl Check for GSS-API libraries
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
AC_ARG_WITH(gssapi-includes,
|
||||||
|
AC_HELP_STRING([--with-gssapi-includes=DIR],
|
||||||
|
[Specify location of GSSAPI header]),
|
||||||
|
[ GSSAPI_INCS="-I$withval"
|
||||||
|
want_gss="yes" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_ARG_WITH(gssapi-libs,
|
||||||
|
AC_HELP_STRING([--with-gssapi-libs=DIR],
|
||||||
|
[Specify location of GSSAPI libs]),
|
||||||
|
[ GSSAPI_LIBS="-L$withval -lgssapi"
|
||||||
|
want_gss="yes" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_ARG_WITH(gssapi,
|
||||||
|
AC_HELP_STRING([--with-gssapi=DIR],
|
||||||
|
[Where to look for GSSAPI]),
|
||||||
|
[ GSSAPI_ROOT="$withval"
|
||||||
|
want_gss="yes" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if GSSAPI support is requested])
|
||||||
|
if test x"$want_gss" = xyes; then
|
||||||
|
if test -z "$GSSAPI_INCS"; then
|
||||||
|
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||||
|
gss_cppflags=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
|
||||||
|
CPPFLAGS="$CPPFLAGS $gss_cppflags"
|
||||||
|
else
|
||||||
|
CPPFLAGS="$GSSAPI_ROOT/include"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$GSSAPI_LIB_DIR"; then
|
||||||
|
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||||
|
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||||
|
LDFLAGS="$LDFLAGS $gss_ldflags"
|
||||||
|
else
|
||||||
|
LDFLAGS="$LDFLAGS $GSSAPI_ROOT/lib -lgssapi"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(GSSAPI, 1, [if you have the gssapi libraries])
|
||||||
|
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl Detect the pkg-config tool, as it may have extra info about the
|
dnl Detect the pkg-config tool, as it may have extra info about the
|
||||||
dnl openssl installation we can use. I *believe* this is what we are
|
dnl openssl installation we can use. I *believe* this is what we are
|
||||||
dnl expected to do on really recent Redhat Linux hosts.
|
dnl expected to do on really recent Redhat Linux hosts.
|
||||||
@@ -484,6 +543,8 @@ dnl **********************************************************************
|
|||||||
|
|
||||||
dnl Default to compiler & linker defaults for SSL files & libraries.
|
dnl Default to compiler & linker defaults for SSL files & libraries.
|
||||||
OPT_SSL=off
|
OPT_SSL=off
|
||||||
|
dnl Default to no CA bundle
|
||||||
|
ca="no"
|
||||||
AC_ARG_WITH(ssl,dnl
|
AC_ARG_WITH(ssl,dnl
|
||||||
AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)])
|
AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)])
|
||||||
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||||
@@ -567,13 +628,29 @@ else
|
|||||||
|
|
||||||
AC_SUBST(OPENSSL_ENABLED)
|
AC_SUBST(OPENSSL_ENABLED)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([CA cert bundle install path])
|
||||||
|
|
||||||
|
AC_ARG_WITH(ca-bundle,
|
||||||
|
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||||
|
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||||
|
[ ca="$withval" ],
|
||||||
|
[
|
||||||
|
if test "x$prefix" != xNONE; then
|
||||||
|
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
||||||
|
else
|
||||||
|
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||||
|
fi
|
||||||
|
] )
|
||||||
|
|
||||||
|
if test X"$OPT_SSL" = Xno; then
|
||||||
|
ca="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test X"$OPT_SSL" != Xoff &&
|
if test "x$ca" != "xno"; then
|
||||||
test "$OPENSSL_ENABLED" != "1"; then
|
CURL_CA_BUNDLE='"'$ca'"'
|
||||||
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
|
AC_SUBST(CURL_CA_BUNDLE)
|
||||||
fi
|
fi
|
||||||
|
AC_MSG_RESULT([$ca])
|
||||||
|
|
||||||
dnl these can only exist if openssl exists
|
dnl these can only exist if openssl exists
|
||||||
|
|
||||||
@@ -581,8 +658,17 @@ else
|
|||||||
RAND_screen \
|
RAND_screen \
|
||||||
RAND_egd )
|
RAND_egd )
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test X"$OPT_SSL" != Xoff &&
|
||||||
|
test "$OPENSSL_ENABLED" != "1"; then
|
||||||
|
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
|
||||||
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Check for the presence of ZLIB libraries and headers
|
dnl Check for the presence of ZLIB libraries and headers
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -625,6 +711,9 @@ case "$OPT_ZLIB" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
dnl set variable for use in automakefile(s)
|
||||||
|
AM_CONDITIONAL(HAVE_LIBZ, test x"$HAVE_LIBZ" = x1)
|
||||||
|
|
||||||
dnl Default is to try the thread-safe versions of a few functions
|
dnl Default is to try the thread-safe versions of a few functions
|
||||||
OPT_THREAD=on
|
OPT_THREAD=on
|
||||||
|
|
||||||
@@ -772,7 +861,6 @@ AC_CHECK_FUNCS( socket \
|
|||||||
tcgetattr \
|
tcgetattr \
|
||||||
perror \
|
perror \
|
||||||
closesocket \
|
closesocket \
|
||||||
setvbuf \
|
|
||||||
sigaction \
|
sigaction \
|
||||||
signal \
|
signal \
|
||||||
getpass_r \
|
getpass_r \
|
||||||
@@ -820,31 +908,6 @@ AC_PATH_PROGS( NROFF, gnroff nroff, ,
|
|||||||
$PATH:/usr/bin/:/usr/local/bin )
|
$PATH:/usr/bin/:/usr/local/bin )
|
||||||
AC_SUBST(NROFF)
|
AC_SUBST(NROFF)
|
||||||
|
|
||||||
AC_MSG_CHECKING([CA cert bundle install path])
|
|
||||||
|
|
||||||
AC_ARG_WITH(ca-bundle,
|
|
||||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
|
||||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
|
||||||
[ ca="$withval" ],
|
|
||||||
[
|
|
||||||
if test "x$prefix" != xNONE; then
|
|
||||||
ca="$prefix/share/curl/curl-ca-bundle.crt"
|
|
||||||
else
|
|
||||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
|
||||||
fi
|
|
||||||
] )
|
|
||||||
|
|
||||||
if test "x$ca" = "xno"; then
|
|
||||||
dnl let's not keep "no" as path name, blank it instead
|
|
||||||
ca=""
|
|
||||||
else
|
|
||||||
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [CA bundle full path name])
|
|
||||||
fi
|
|
||||||
|
|
||||||
CURL_CA_BUNDLE="$ca"
|
|
||||||
AC_SUBST(CURL_CA_BUNDLE)
|
|
||||||
AC_MSG_RESULT([$ca])
|
|
||||||
|
|
||||||
AC_PROG_YACC
|
AC_PROG_YACC
|
||||||
|
|
||||||
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
||||||
@@ -864,7 +927,7 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
|
||||||
CFLAGS="$CFLAGS -g"
|
CFLAGS="$CFLAGS -g"
|
||||||
if test "$GCC" = "yes"; then
|
if test "$GCC" = "yes"; then
|
||||||
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs"
|
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs"
|
||||||
@@ -907,6 +970,7 @@ AC_CONFIG_FILES([Makefile \
|
|||||||
packages/Linux/RPM/curl.spec \
|
packages/Linux/RPM/curl.spec \
|
||||||
packages/Linux/RPM/curl-ssl.spec \
|
packages/Linux/RPM/curl-ssl.spec \
|
||||||
packages/Solaris/Makefile \
|
packages/Solaris/Makefile \
|
||||||
|
packages/DOS/Makefile \
|
||||||
packages/EPM/curl.list \
|
packages/EPM/curl.list \
|
||||||
packages/EPM/Makefile \
|
packages/EPM/Makefile \
|
||||||
curl-config
|
curl-config
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
(setq tab-width 8
|
(setq tab-width 8
|
||||||
indent-tabs-mode nil ; Use spaces. Not tabs.
|
indent-tabs-mode nil ; Use spaces. Not tabs.
|
||||||
comment-column 40
|
comment-column 40
|
||||||
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set"))
|
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t"))
|
||||||
)
|
)
|
||||||
;; keybindings for C, C++, and Objective-C. We can put these in
|
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||||
;; c-mode-base-map because of inheritance ...
|
;; c-mode-base-map because of inheritance ...
|
||||||
|
29
docs/FAQ
29
docs/FAQ
@@ -1,4 +1,4 @@
|
|||||||
Updated: February 25, 2003 (http://curl.haxx.se/docs/faq.html)
|
Updated: June 17, 2003 (http://curl.haxx.se/docs/faq.html)
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -97,6 +97,12 @@ FAQ
|
|||||||
We spell it cURL or just curl. We pronounce it with an initial k sound:
|
We spell it cURL or just curl. We pronounce it with an initial k sound:
|
||||||
[kurl].
|
[kurl].
|
||||||
|
|
||||||
|
NOTE: there are numerous sub-projects and related projects that also use the
|
||||||
|
word curl in the project names in various combinations, but you should take
|
||||||
|
notice that this FAQ is directed at the command-line tool named curl (and
|
||||||
|
libcurl the library), and may therefore not be valid for other curl
|
||||||
|
projects.
|
||||||
|
|
||||||
1.2 What is libcurl?
|
1.2 What is libcurl?
|
||||||
|
|
||||||
libcurl is a reliable and portable library which provides you with an easy
|
libcurl is a reliable and portable library which provides you with an easy
|
||||||
@@ -132,11 +138,9 @@ FAQ
|
|||||||
better. We do however believe in a few rules when it comes to the future of
|
better. We do however believe in a few rules when it comes to the future of
|
||||||
curl:
|
curl:
|
||||||
|
|
||||||
* Curl is to remain a command line tool. If you want GUIs or fancy scripting
|
* Curl -- the command line tool -- is to remain a non-graphical command line
|
||||||
capabilities, you're free to write another tool that uses libcurl and that
|
tool. If you want GUIs or fancy scripting capabilities, you should look
|
||||||
offers this. There's no point in having a single tool that does every
|
for another tool that uses libcurl.
|
||||||
imaginable thing. That's also one of the great advantages of having the
|
|
||||||
core of curl as a library.
|
|
||||||
|
|
||||||
* We do not add things to curl that other small and available tools already
|
* We do not add things to curl that other small and available tools already
|
||||||
do very fine at the side. Curl's output is fine to pipe into another
|
do very fine at the side. Curl's output is fine to pipe into another
|
||||||
@@ -589,9 +593,11 @@ FAQ
|
|||||||
|
|
||||||
4.9. Curl can't authenticate to the server that requires NTLM?
|
4.9. Curl can't authenticate to the server that requires NTLM?
|
||||||
|
|
||||||
NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not
|
This is supported in curl 7.10.6 or later. No earlier curl version knows
|
||||||
currently support that. Proprietary formats are evil. You should not use
|
of this magic.
|
||||||
such ones.
|
|
||||||
|
NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
|
||||||
|
should not use such ones.
|
||||||
|
|
||||||
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
||||||
|
|
||||||
@@ -772,6 +778,5 @@ FAQ
|
|||||||
discussions and a large amount of people have contributed with source code
|
discussions and a large amount of people have contributed with source code
|
||||||
knowing that this is the license we use. This license puts the restrictions
|
knowing that this is the license we use. This license puts the restrictions
|
||||||
we want on curl/libcurl and it does not spread to other programs or
|
we want on curl/libcurl and it does not spread to other programs or
|
||||||
libraries that use it. The recent dual license modification should make it
|
libraries that use it. It should be possible for everyone to use libcurl or
|
||||||
possible for everyone to use libcurl or curl in their projects, no matter
|
curl in their projects, no matter what license they already have in use.
|
||||||
what license they already have in use.
|
|
||||||
|
@@ -17,27 +17,30 @@ Misc
|
|||||||
- progress bar/time specs while downloading
|
- progress bar/time specs while downloading
|
||||||
- "standard" proxy environment variables support
|
- "standard" proxy environment variables support
|
||||||
- config file support
|
- config file support
|
||||||
- compiles on win32 (reported built on 29 operating systems)
|
- compiles on win32 (reported builds on 40+ operating systems)
|
||||||
- redirectable stderr
|
- redirectable stderr
|
||||||
- use selected network interface for outgoing traffic
|
- selectable network interface for outgoing traffic
|
||||||
- IPv6 support
|
- IPv6 support
|
||||||
- persistant connections
|
- persistant connections
|
||||||
|
- socks5 support
|
||||||
|
- supports user name + password in proxy environment variables
|
||||||
|
- operations through proxy "tunnel" (using CONNECT)
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
- HTTP/1.1 compliant
|
- HTTP/1.1 compliant (optionally uses 1.0)
|
||||||
- GET
|
- GET
|
||||||
- PUT
|
- PUT
|
||||||
- HEAD
|
- HEAD
|
||||||
- POST
|
- POST
|
||||||
- multipart POST
|
- multipart formpost (RFC1867-style)
|
||||||
- authentication
|
- authentication (Basic, Digest, NTLM(*1), GSS-Negotiate(*3))
|
||||||
- resume (both GET and PUT)
|
- resume (both GET and PUT)
|
||||||
- follow redirects
|
- follow redirects
|
||||||
- maximum amount of redirects to follow
|
- maximum amount of redirects to follow
|
||||||
- custom HTTP request
|
- custom HTTP request
|
||||||
- cookie get/send fully parsed
|
- cookie get/send fully parsed
|
||||||
- understands the netscape cookie file format
|
- reads/writes the netscape cookie file format
|
||||||
- custom headers (that can replace/remove internally generated headers)
|
- custom headers (replace/remove internally generated headers)
|
||||||
- custom user-agent string
|
- custom user-agent string
|
||||||
- custom referer string
|
- custom referer string
|
||||||
- range
|
- range
|
||||||
@@ -45,12 +48,16 @@ HTTP
|
|||||||
- time conditions
|
- time conditions
|
||||||
- via http-proxy
|
- via http-proxy
|
||||||
- retrieve file modification date
|
- retrieve file modification date
|
||||||
|
- Content-Encoding support for deflate and gzip
|
||||||
|
- "Transfer-Encoding: chunked" support for "uploads"
|
||||||
|
|
||||||
HTTPS (*1)
|
HTTPS (*1)
|
||||||
- (all the HTTP features)
|
- (all the HTTP features)
|
||||||
- using certificates
|
- using certificates
|
||||||
- verify server certificate
|
- verify server certificate
|
||||||
- via http-proxy
|
- via http-proxy
|
||||||
|
- select desired encryption
|
||||||
|
- force usage of a specific SSL version (SSLv2, SSLv3 or TLSv1)
|
||||||
|
|
||||||
FTP
|
FTP
|
||||||
- download
|
- download
|
||||||
@@ -92,3 +99,4 @@ FILE
|
|||||||
|
|
||||||
*1 = requires OpenSSL
|
*1 = requires OpenSSL
|
||||||
*2 = requires OpenLDAP
|
*2 = requires OpenLDAP
|
||||||
|
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||||
|
@@ -31,6 +31,10 @@ UNIX
|
|||||||
If you have checked out the sources from the CVS repository, read the
|
If you have checked out the sources from the CVS repository, read the
|
||||||
CVS-INFO on how to proceed.
|
CVS-INFO on how to proceed.
|
||||||
|
|
||||||
|
Get a full listing of all available configure options by invoking it like:
|
||||||
|
|
||||||
|
./configure --help
|
||||||
|
|
||||||
If you want to install curl in a different file hierarchy than /usr/local,
|
If you want to install curl in a different file hierarchy than /usr/local,
|
||||||
you need to specify that already when running configure:
|
you need to specify that already when running configure:
|
||||||
|
|
||||||
@@ -444,6 +448,7 @@ PORTS
|
|||||||
- StrongARM NetBSD 1.4.1
|
- StrongARM NetBSD 1.4.1
|
||||||
- Ultrix 4.3a
|
- Ultrix 4.3a
|
||||||
- i386 BeOS
|
- i386 BeOS
|
||||||
|
- i386 DOS
|
||||||
- i386 FreeBSD
|
- i386 FreeBSD
|
||||||
- i386 HURD
|
- i386 HURD
|
||||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
||||||
@@ -454,10 +459,12 @@ PORTS
|
|||||||
- i386 Solaris 2.7
|
- i386 Solaris 2.7
|
||||||
- i386 Windows 95, 98, ME, NT, 2000
|
- i386 Windows 95, 98, ME, NT, 2000
|
||||||
- i386 QNX 6
|
- i386 QNX 6
|
||||||
|
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
|
||||||
- ia64 Linux 2.3.99
|
- ia64 Linux 2.3.99
|
||||||
- m68k AmigaOS 3
|
- m68k AmigaOS 3
|
||||||
- m68k Linux
|
- m68k Linux
|
||||||
- m68k OpenBSD
|
- m68k OpenBSD
|
||||||
|
- m88k dg-dgux5.4R3.00
|
||||||
- s390 Linux
|
- s390 Linux
|
||||||
- XScale/PXA250 Linux 2.4
|
- XScale/PXA250 Linux 2.4
|
||||||
|
|
||||||
|
@@ -3,6 +3,15 @@ join in and help us correct one or more of these! Also be sure to check the
|
|||||||
changelog of the current development status, as one or more of these problems
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
|
* LDAP output is garbled. Hardly anyone seems to care about LDAP functionality
|
||||||
|
in curl/libcurl why this report has been closed and set to be solved later.
|
||||||
|
If you feel this is something you want fixed, get in touch and we'll start
|
||||||
|
working.
|
||||||
|
http://sourceforge.net/tracker/index.php?func=detail&aid=735752&group_id=976&atid=100976
|
||||||
|
|
||||||
|
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
|
||||||
|
struct. It has been reported to work on AIX 5.1 though.
|
||||||
|
|
||||||
* Running 'make test' on Mac OS X gives 4 errors. This seems to be related
|
* Running 'make test' on Mac OS X gives 4 errors. This seems to be related
|
||||||
to some kind of libtool problem:
|
to some kind of libtool problem:
|
||||||
http://curl.haxx.se/mail/archive-2002-03/0029.html and
|
http://curl.haxx.se/mail/archive-2002-03/0029.html and
|
||||||
|
@@ -11,7 +11,7 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
curl http://www.netscape.com/
|
curl http://www.netscape.com/
|
||||||
|
|
||||||
Get the root README file from funet's ftp-server:
|
Get the README file the user's home directory at funet's ftp-server:
|
||||||
|
|
||||||
curl ftp://ftp.funet.fi/README
|
curl ftp://ftp.funet.fi/README
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
curl http://www.weirdserver.com:8000/
|
curl http://www.weirdserver.com:8000/
|
||||||
|
|
||||||
Get a list of the root directory of an FTP site:
|
Get a list of a directory of an FTP site:
|
||||||
|
|
||||||
curl ftp://cool.haxx.se/
|
curl ftp://cool.haxx.se/
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ PDFPAGES = \
|
|||||||
|
|
||||||
SUBDIRS = examples libcurl
|
SUBDIRS = examples libcurl
|
||||||
|
|
||||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \
|
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
||||||
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
||||||
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
||||||
|
@@ -13,8 +13,8 @@ README.win32
|
|||||||
are win32-based.
|
are win32-based.
|
||||||
|
|
||||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||||
those pages also converted to HTML and those are also included in the
|
those pages converted to HTML as well as pdf, and included in the release
|
||||||
release archives.
|
archives.
|
||||||
|
|
||||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||||
command line similar to this in order to extract a separate text file:
|
command line similar to this in order to extract a separate text file:
|
||||||
|
@@ -87,3 +87,7 @@ that have contributed with non-trivial parts:
|
|||||||
- Miklos Nemeth <mnemeth@kfkisystems.com>
|
- Miklos Nemeth <mnemeth@kfkisystems.com>
|
||||||
- Kevin Roth <kproth@users.sourceforge.net>
|
- Kevin Roth <kproth@users.sourceforge.net>
|
||||||
- Ralph Mitchell <rmitchell@eds.com>
|
- Ralph Mitchell <rmitchell@eds.com>
|
||||||
|
- Dan Fandrich <dan@coneharvesters.com>
|
||||||
|
- Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
||||||
|
- Richard Bramante <RBramante@on.com>
|
||||||
|
- Daniel Kouril <kouril@ics.muni.cz>
|
||||||
|
54
docs/TODO
54
docs/TODO
@@ -16,7 +16,7 @@ TODO
|
|||||||
know what cookies that are received. Pushing interface that calls a
|
know what cookies that are received. Pushing interface that calls a
|
||||||
callback on each received cookie? Querying interface that asks about
|
callback on each received cookie? Querying interface that asks about
|
||||||
existing cookies? We probably need both. Enable applications to modify
|
existing cookies? We probably need both. Enable applications to modify
|
||||||
existing cookies as well.
|
existing cookies as well. http://curl.haxx.se/dev/COOKIES
|
||||||
|
|
||||||
* Make content encoding/decoding internally be made using a filter system.
|
* Make content encoding/decoding internally be made using a filter system.
|
||||||
|
|
||||||
@@ -50,10 +50,6 @@ TODO
|
|||||||
requested. That is, the download should not even begin but be aborted
|
requested. That is, the download should not even begin but be aborted
|
||||||
immediately.
|
immediately.
|
||||||
|
|
||||||
* Allow the http_proxy (and other) environment variables to contain user and
|
|
||||||
password as well in the style: http://proxyuser:proxypasswd@proxy:port
|
|
||||||
Berend Reitsma suggested.
|
|
||||||
|
|
||||||
LIBCURL - multi interface
|
LIBCURL - multi interface
|
||||||
|
|
||||||
* Make sure we don't ever loop because of non-blocking sockets return
|
* Make sure we don't ever loop because of non-blocking sockets return
|
||||||
@@ -73,52 +69,24 @@ TODO
|
|||||||
|
|
||||||
FTP
|
FTP
|
||||||
|
|
||||||
* FTP ASCII upload does not follow RFC959 section 3.1.1.1: "The sender
|
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
||||||
converts the data from an internal character representation to the standard
|
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
||||||
8-bit NVT-ASCII representation (see the Telnet specification). The
|
|
||||||
receiver will convert the data from the standard form to his own internal
|
* FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||||
form."
|
accordingly.
|
||||||
|
|
||||||
* Since USERPWD always override the user and password specified in URLs, we
|
* Since USERPWD always override the user and password specified in URLs, we
|
||||||
might need another way to specify user+password for anonymous ftp logins.
|
might need another way to specify user+password for anonymous ftp logins.
|
||||||
|
|
||||||
* An option to only download remote FTP files if they're newer than the local
|
|
||||||
one is a good idea, and it would fit right into the same syntax as the
|
|
||||||
already working http dito works. It of course requires that 'MDTM' works,
|
|
||||||
and it isn't a standard FTP command.
|
|
||||||
|
|
||||||
* Add FTPS support with SSL for the data connection too. This should be made
|
* Add FTPS support with SSL for the data connection too. This should be made
|
||||||
according to the specs written in draft-murray-auth-ftp-ssl-08.txt,
|
according to the specs written in draft-murray-auth-ftp-ssl-11.txt,
|
||||||
"Securing FTP with TLS"
|
"Securing FTP with TLS", valid until September 27th 2003.
|
||||||
|
http://curl.haxx.se/rfc/draft-murray-auth-ftp-ssl-11.txt
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
|
|
||||||
* If the "body" of the POST is < MSS it really aught to be sent along with
|
* Digest, NTLM and GSS-Negotiate support for HTTP proxies. They all work
|
||||||
the headers. More generally, if the last chunk of the POST body is < MSS,
|
on direct-connections to the server.
|
||||||
it should be sent with the previous chunk (which may be the POST headers).
|
|
||||||
So long as any one send is larger than MSS (or there is only one send when
|
|
||||||
< MSS :), the Nagle Algorithm will not be a problem on any stack where
|
|
||||||
Nagle is implemented correctly. (pointed out by Rick Jones)
|
|
||||||
|
|
||||||
* Authentication: NTLM. Support for that MS crap called NTLM
|
|
||||||
authentication. MS proxies and servers sometime require that. Since that
|
|
||||||
protocol is a proprietary one, it involves reverse engineering and network
|
|
||||||
sniffing. This should however be a library-based functionality. There are a
|
|
||||||
few different efforts "out there" to make open source HTTP clients support
|
|
||||||
this and it should be possible to take advantage of other people's hard
|
|
||||||
work. http://modntlm.sourceforge.net/ is one. There's a web page at
|
|
||||||
http://www.innovation.ch/java/ntlm.html that contains detailed reverse-
|
|
||||||
engineered info.
|
|
||||||
|
|
||||||
* RFC2617 compliance, "Digest Access Authentication" A valid test page seem
|
|
||||||
to exist at: http://hopf.math.nwu.edu/testpage/digest/ And some friendly
|
|
||||||
person's server source code is available at
|
|
||||||
http://hopf.math.nwu.edu/digestauth/index.html Then there's the Apache
|
|
||||||
mod_digest source code too of course. It seems as if Netscape doesn't
|
|
||||||
support this, and not many servers do. Although this is a lot better
|
|
||||||
authentication method than the more common "Basic". Basic sends the
|
|
||||||
password in cleartext over the network, this "Digest" method uses a
|
|
||||||
challange-response protocol which increases security quite a lot.
|
|
||||||
|
|
||||||
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||||
This could possibly be implemented using the multi interface to queue
|
This could possibly be implemented using the multi interface to queue
|
||||||
|
149
docs/curl.1
149
docs/curl.1
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man curl.1
|
.\" nroff -man curl.1
|
||||||
.\" Written by Daniel Stenberg
|
.\" Written by Daniel Stenberg
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "14 Feb 2003" "Curl 7.10.3" "Curl Manual"
|
.TH curl 1 "18 June 2003" "Curl 7.10.6" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -10,14 +10,18 @@ curl \- transfer a URL
|
|||||||
.I [URL...]
|
.I [URL...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B curl
|
.B curl
|
||||||
is a client to get documents/files from or send documents to a server, using
|
is a tool to transfer data from or to a server, using one of the supported
|
||||||
any of the supported protocols (HTTP, HTTPS, FTP, GOPHER, DICT, TELNET, LDAP
|
protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The
|
||||||
or FILE). The command is designed to work without user interaction or any kind
|
command is designed to work without user interaction.
|
||||||
of interactivity.
|
|
||||||
|
|
||||||
curl offers a busload of useful tricks like proxy support, user
|
curl offers a busload of useful tricks like proxy support, user
|
||||||
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
||||||
transfer resume and more.
|
transfer resume and more. As you will see below, the amount of features will
|
||||||
|
make your head spin!
|
||||||
|
|
||||||
|
curl is powered by libcurl for all transfer-related features. See
|
||||||
|
.BR libcurl (3)
|
||||||
|
for details.
|
||||||
.SH URL
|
.SH URL
|
||||||
The URL syntax is protocol dependent. You'll find a detailed description in
|
The URL syntax is protocol dependent. You'll find a detailed description in
|
||||||
RFC 2396.
|
RFC 2396.
|
||||||
@@ -48,10 +52,8 @@ specified on a single command line and cannot be used between separate curl
|
|||||||
invokes.
|
invokes.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IP "-a/--append"
|
.IP "-a/--append"
|
||||||
(FTP)
|
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
||||||
When used in a ftp upload, this will tell curl to append to the target
|
file instead of overwriting it. If the file doesn't exist, it will be created.
|
||||||
file instead of overwriting it. If the file doesn't exist, it will
|
|
||||||
be created.
|
|
||||||
|
|
||||||
If this option is used twice, the second one will disable append mode again.
|
If this option is used twice, the second one will disable append mode again.
|
||||||
.IP "-A/--user-agent <agent string>"
|
.IP "-A/--user-agent <agent string>"
|
||||||
@@ -63,6 +65,16 @@ surround the string with single quote marks. This can also be set with the
|
|||||||
|
|
||||||
If this option is set more than once, the last one will be the one that's
|
If this option is set more than once, the last one will be the one that's
|
||||||
used.
|
used.
|
||||||
|
.IP "--anyauth"
|
||||||
|
(HTTP) Tells curl to figure out authentication method by itself, and use the
|
||||||
|
most secure one the remote site claims it supports. This is done by first
|
||||||
|
doing a request and checking the response-headers, thus inducing an extra
|
||||||
|
network round-trip. This is used instead of setting a specific authentication
|
||||||
|
method, which you can do with \fI--digest\fP, \fI--ntlm\fP, and
|
||||||
|
\fI--negotiate\fP. (Added in 7.10.6)
|
||||||
|
|
||||||
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
.IP "-b/--cookie <name=data>"
|
.IP "-b/--cookie <name=data>"
|
||||||
(HTTP)
|
(HTTP)
|
||||||
Pass the data to the HTTP server as a cookie. It is supposedly the
|
Pass the data to the HTTP server as a cookie. It is supposedly the
|
||||||
@@ -90,12 +102,26 @@ also be enforced by using an URL that ends with ";type=A". This option causes
|
|||||||
data sent to stdout to be in text mode for win32 systems.
|
data sent to stdout to be in text mode for win32 systems.
|
||||||
|
|
||||||
If this option is used twice, the second one will disable ASCII usage.
|
If this option is used twice, the second one will disable ASCII usage.
|
||||||
|
.IP "--basic"
|
||||||
|
(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
|
||||||
|
this option is usually pointless, unless you use it to override a previously
|
||||||
|
set option that sets a different authentication method (such as \fI--ntlm\fP,
|
||||||
|
\fI--digest\fP and \fI--negotiate\fP). (Added in 7.10.6)
|
||||||
|
|
||||||
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
.IP "--ciphers <list of ciphers>"
|
.IP "--ciphers <list of ciphers>"
|
||||||
(SSL) Specifies which ciphers to use in the connection. The list of ciphers
|
(SSL) Specifies which ciphers to use in the connection. The list of ciphers
|
||||||
must be using valid ciphers. Read up on SSL cipher list details on this URL:
|
must be using valid ciphers. Read up on SSL cipher list details on this URL:
|
||||||
.I http://www.openssl.org/docs/apps/ciphers.html (Option added in curl 7.9)
|
.I http://www.openssl.org/docs/apps/ciphers.html (Option added in curl 7.9)
|
||||||
|
|
||||||
If this option is used several times, the last one will override the others.
|
If this option is used several times, the last one will override the others.
|
||||||
|
.IP "--compressed"
|
||||||
|
(HTTP) Request a compressed response using one of the algorithms libcurl
|
||||||
|
supports, and return the uncompressed document. If this option is used and
|
||||||
|
the server sends an unsupported encoding, Curl will report an error.
|
||||||
|
|
||||||
|
If this option is used several times, each occurrence will toggle it on/off.
|
||||||
.IP "--connect-timeout <seconds>"
|
.IP "--connect-timeout <seconds>"
|
||||||
Maximum time in seconds that you allow the connection to the server to take.
|
Maximum time in seconds that you allow the connection to the server to take.
|
||||||
This only limits the connection phase, once curl has connected this option is
|
This only limits the connection phase, once curl has connected this option is
|
||||||
@@ -110,6 +136,12 @@ no file will be written. The file will be written using the Netscape cookie
|
|||||||
file format. If you set the file name to a single dash, "-", the cookies will
|
file format. If you set the file name to a single dash, "-", the cookies will
|
||||||
be written to stdout. (Option added in curl 7.9)
|
be written to stdout. (Option added in curl 7.9)
|
||||||
|
|
||||||
|
.B NOTE
|
||||||
|
If the cookie jar can't be created or written to, the whole curl operation
|
||||||
|
won't fail or even report an error clearly. Using -v will get a warning
|
||||||
|
displayed, but that is the only visible feedback you get about this possibly
|
||||||
|
lethal situation.
|
||||||
|
|
||||||
If this option is used several times, the last specfied file name will be
|
If this option is used several times, the last specfied file name will be
|
||||||
used.
|
used.
|
||||||
.IP "-C/--continue-at <offset>"
|
.IP "-C/--continue-at <offset>"
|
||||||
@@ -122,7 +154,7 @@ Use "-C -" to tell curl to automatically find out where/how to resume the
|
|||||||
transfer. It then uses the given output/input files to figure that out.
|
transfer. It then uses the given output/input files to figure that out.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "---create-dirs"
|
.IP "--create-dirs"
|
||||||
When used in conjunction with the -o option, curl will create the necessary
|
When used in conjunction with the -o option, curl will create the necessary
|
||||||
local directory hierarchy as needed.
|
local directory hierarchy as needed.
|
||||||
.IP "--crlf"
|
.IP "--crlf"
|
||||||
@@ -166,9 +198,27 @@ want to post a binary file without the strip-newlines feature of the
|
|||||||
|
|
||||||
If this option is used several times, the ones following the first will
|
If this option is used several times, the ones following the first will
|
||||||
append data.
|
append data.
|
||||||
|
.IP "--digest"
|
||||||
|
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
||||||
|
prevents the password from being sent over the wire in clear text. Use this in
|
||||||
|
combination with the normal -u/--user option to set user name and
|
||||||
|
password. See also \fI--ntlm\fP, \fP--negotiate\fI and \fI--anyauth\fP for
|
||||||
|
related options. (Added in curl 7.10.6)
|
||||||
|
|
||||||
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
|
.IP "--disable-eprt"
|
||||||
|
(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
|
||||||
|
active FTP transfers. Curl will normally always first attempt to use EPRT,
|
||||||
|
then LPRT before using PORT, but with this option, it will use PORT right
|
||||||
|
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
|
||||||
|
on all servers but enable more functionality in a better way than the
|
||||||
|
traditional PORT command. (Aded in 7.10.5)
|
||||||
|
|
||||||
|
If this option is used several times, each occurrence will toggle this on/off.
|
||||||
.IP "--disable-epsv"
|
.IP "--disable-epsv"
|
||||||
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
|
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
|
||||||
downloads. Curl will normally always first attempt to use EPSV before PASV,
|
transfers. Curl will normally always first attempt to use EPSV before PASV,
|
||||||
but with this option, it will not try using EPSV.
|
but with this option, it will not try using EPSV.
|
||||||
|
|
||||||
If this option is used several times, each occurrence will toggle this on/off.
|
If this option is used several times, each occurrence will toggle this on/off.
|
||||||
@@ -256,12 +306,18 @@ Example, to send your password file to the server, where
|
|||||||
\&'password' is the name of the form-field to which /etc/passwd will be the
|
\&'password' is the name of the form-field to which /etc/passwd will be the
|
||||||
input:
|
input:
|
||||||
|
|
||||||
.B curl
|
\fBcurl\fP -F password=@/etc/passwd www.mypasswords.com
|
||||||
-F password=@/etc/passwd www.mypasswords.com
|
|
||||||
|
|
||||||
To read the file's content from stdin insted of a file, use - where the file
|
To read the file's content from stdin insted of a file, use - where the file
|
||||||
name should've been. This goes for both @ and < constructs.
|
name should've been. This goes for both @ and < constructs.
|
||||||
|
|
||||||
|
You can also tell curl what Content-Type to use for the file upload part, by
|
||||||
|
using 'type=', in a manner similar to:
|
||||||
|
|
||||||
|
\fBcurl\fP -F "web=@index.html;type=text/html" url.com
|
||||||
|
|
||||||
|
See further examples and details in the MANUAL.
|
||||||
|
|
||||||
This option can be used multiple times.
|
This option can be used multiple times.
|
||||||
.IP "-g/--globoff"
|
.IP "-g/--globoff"
|
||||||
This option switches off the "URL globbing parser". When you set this option,
|
This option switches off the "URL globbing parser". When you set this option,
|
||||||
@@ -381,9 +437,18 @@ If this option is used twice, the second will again disable list only.
|
|||||||
(HTTP/HTTPS) If the server reports that the requested page has a different
|
(HTTP/HTTPS) If the server reports that the requested page has a different
|
||||||
location (indicated with the header line Location:) this flag will let curl
|
location (indicated with the header line Location:) this flag will let curl
|
||||||
attempt to reattempt the get on the new place. If used together with -i or -I,
|
attempt to reattempt the get on the new place. If used together with -i or -I,
|
||||||
headers from all requested pages will be shown. If this flag is used when
|
headers from all requested pages will be shown. If authentication is used,
|
||||||
making a HTTP POST, curl will automatically switch to GET after the initial
|
curl will only send its credentials to the initial host, so if a redirect
|
||||||
POST has been done.
|
takes curl to a different host, it won't intercept the user+password. See also
|
||||||
|
\fI--location-trusted\fP on how to change this.
|
||||||
|
|
||||||
|
If this option is used twice, the second will again disable location following.
|
||||||
|
.IP "--location-trusted"
|
||||||
|
(HTTP/HTTPS) Like \fI--location\fP, but will allow sending the name + password
|
||||||
|
to all hosts that the site may redirect to. This may or may not introduce a
|
||||||
|
security breach if the site redirects you do a site to which you'll send your
|
||||||
|
authentication info (which is plaintext in the case of HTTP Basic
|
||||||
|
authentication).
|
||||||
|
|
||||||
If this option is used twice, the second will again disable location following.
|
If this option is used twice, the second will again disable location following.
|
||||||
.IP "-m/--max-time <seconds>"
|
.IP "-m/--max-time <seconds>"
|
||||||
@@ -417,6 +482,19 @@ to allow curl to ftp to the machine host.domain.com with user name
|
|||||||
.B "machine host.domain.com login myself password secret"
|
.B "machine host.domain.com login myself password secret"
|
||||||
|
|
||||||
If this option is used twice, the second will again disable netrc usage.
|
If this option is used twice, the second will again disable netrc usage.
|
||||||
|
.IP "--negotiate"
|
||||||
|
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
|
||||||
|
designed by Microsoft and is used in their web aplications. It is primarily
|
||||||
|
meant as a support for Kerberos5 authentication but may be also used along
|
||||||
|
with another authentication methods. For more information see IETF draft
|
||||||
|
draft-brezak-spnego-http-04.txt. (Added in 7.10.6)
|
||||||
|
|
||||||
|
\fBNOTE\fP that this option requiures that the library was built with GSSAPI
|
||||||
|
support. This is not very common. Use \fIcurl --version\fP to see if your
|
||||||
|
version supports GSS-Negotiate.
|
||||||
|
|
||||||
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
.IP "-N/--no-buffer"
|
.IP "-N/--no-buffer"
|
||||||
Disables the buffering of the output stream. In normal work situations, curl
|
Disables the buffering of the output stream. In normal work situations, curl
|
||||||
will use a standard buffered output stream that will have the effect that it
|
will use a standard buffered output stream that will have the effect that it
|
||||||
@@ -424,6 +502,19 @@ will output the data in chunks, not necessarily exactly when the data arrives.
|
|||||||
Using this option will disable that buffering.
|
Using this option will disable that buffering.
|
||||||
|
|
||||||
If this option is used twice, the second will again switch on buffering.
|
If this option is used twice, the second will again switch on buffering.
|
||||||
|
.IP "--ntlm"
|
||||||
|
(HTTP) Enables NTLM authentication. The NTLM authentication method was
|
||||||
|
designed by Microsoft and is used by IIS web servers. It is a proprietary
|
||||||
|
protocol, reversed engineered by clever people and implemented in curl based
|
||||||
|
on their efforts. This kind of behavior should not be endorsed, you should
|
||||||
|
encourage everyone who uses NTLM to switch to a public and documented
|
||||||
|
authentication method instead. Such as Digest. (Added in 7.10.6)
|
||||||
|
|
||||||
|
\fBNOTE\fP that this option requiures that the library was built with SSL
|
||||||
|
support. Use \fIcurl --version\fP to see if your version supports NTLM.
|
||||||
|
|
||||||
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
.IP "-o/--output <file>"
|
.IP "-o/--output <file>"
|
||||||
Write output to <file> instead of stdout. If you are using {} or [] to fetch
|
Write output to <file> instead of stdout. If you are using {} or [] to fetch
|
||||||
multiple documents, you can use '#' followed by a number in the <file>
|
multiple documents, you can use '#' followed by a number in the <file>
|
||||||
@@ -440,8 +531,8 @@ You may use this option as many times as you have number of URLs.
|
|||||||
|
|
||||||
See also the --create-dirs option to create the local directories dynamically.
|
See also the --create-dirs option to create the local directories dynamically.
|
||||||
.IP "-O/--remote-name"
|
.IP "-O/--remote-name"
|
||||||
Write output to a local file named like the remote file we get. (Only
|
Write output to a local file named like the remote file we get. (Only the file
|
||||||
the file part of the remote file is used, the path is cut off.)
|
part of the remote file is used, the path is cut off.)
|
||||||
|
|
||||||
You may use this option as many times as you have number of URLs.
|
You may use this option as many times as you have number of URLs.
|
||||||
.IP "-p/--proxytunnel"
|
.IP "-p/--proxytunnel"
|
||||||
@@ -580,7 +671,7 @@ descriptive information, to the given output file. Use "-" as filename to have
|
|||||||
the output sent to stdout.
|
the output sent to stdout.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
If this option is used several times, the last one will be used. (Added in
|
||||||
curl 7.9.7)
|
7.9.7)
|
||||||
.IP "--trace-ascii <file>"
|
.IP "--trace-ascii <file>"
|
||||||
Enables a full trace dump of all incoming and outgoing data, including
|
Enables a full trace dump of all incoming and outgoing data, including
|
||||||
descriptive information, to the given output file. Use "-" as filename to have
|
descriptive information, to the given output file. Use "-" as filename to have
|
||||||
@@ -591,12 +682,15 @@ the ASCII part of the dump. It makes smaller output that might be easier to
|
|||||||
read for untrained humans.
|
read for untrained humans.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
If this option is used several times, the last one will be used. (Added in
|
||||||
curl 7.9.7)
|
7.9.7)
|
||||||
.IP "-u/--user <user:password>"
|
.IP "-u/--user <user:password>"
|
||||||
Specify user and password to use when fetching. Read the MANUAL for detailed
|
Specify user and password to use when fetching. Read the MANUAL for detailed
|
||||||
examples of how to use this. If no password is specified, curl will ask for it
|
examples of how to use this. If no password is specified, curl will ask for it
|
||||||
interactively.
|
interactively.
|
||||||
|
|
||||||
|
You can also use the --digest option to enable Digest authentication when
|
||||||
|
communicating with HTTP 1.1 servers.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-U/--proxy-user <user:password>"
|
.IP "-U/--proxy-user <user:password>"
|
||||||
Specify user and password to use for Proxy authentication. If no
|
Specify user and password to use for Proxy authentication. If no
|
||||||
@@ -626,8 +720,17 @@ If you think this option still doesn't give you enough details, consider using
|
|||||||
|
|
||||||
If this option is used twice, the second will again disable verbose.
|
If this option is used twice, the second will again disable verbose.
|
||||||
.IP "-V/--version"
|
.IP "-V/--version"
|
||||||
Displays the full version of curl, libcurl and other 3rd party libraries
|
Displays information about curl and the libcurl version it uses.
|
||||||
linked with the executable.
|
|
||||||
|
The first line includes the full version of curl, libcurl and other 3rd party
|
||||||
|
libraries linked with the executable.
|
||||||
|
|
||||||
|
The second line (starts with "Protocols:") shows all protocols that libcurl
|
||||||
|
reports to support.
|
||||||
|
|
||||||
|
The third line (starts with "Features:") shows specific features libcurl
|
||||||
|
reports to offer.
|
||||||
|
|
||||||
.IP "-w/--write-out <format>"
|
.IP "-w/--write-out <format>"
|
||||||
Defines what to display after a completed and successful operation. The format
|
Defines what to display after a completed and successful operation. The format
|
||||||
is a string that may contain plain text mixed with any number of variables. The
|
is a string that may contain plain text mixed with any number of variables. The
|
||||||
|
@@ -9,7 +9,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
|||||||
multithread.c getinmemory.c ftpupload.c httpput.c \
|
multithread.c getinmemory.c ftpupload.c httpput.c \
|
||||||
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
||||||
multi-app.c multi-double.c multi-single.c multi-post.c \
|
multi-app.c multi-double.c multi-single.c multi-post.c \
|
||||||
fopen.c simplepost.c
|
fopen.c simplepost.c makefile.dj
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "done"
|
@echo "done"
|
||||||
|
31
docs/examples/makefile.dj
Normal file
31
docs/examples/makefile.dj
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Adapted for djgpp / Watt-32 / DOS by
|
||||||
|
# Gisle Vanem <giva@bgnett.no>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../../packages/DOS/common.dj
|
||||||
|
|
||||||
|
CFLAGS += -I../../include
|
||||||
|
|
||||||
|
LIBS = ../../lib/libcurl.a
|
||||||
|
|
||||||
|
ifeq ($(USE_SSL),1)
|
||||||
|
LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||||
|
|
||||||
|
PROGRAMS = fopen.exe ftpget.exe ftpgetre.exe ftpuploa.exe getinmem.exe \
|
||||||
|
http-pos.exe httpput.exe multi-ap.exe multi-do.exe \
|
||||||
|
multi-po.exe multi-si.exe persista.exe post-cal.exe \
|
||||||
|
postit2.exe sepheade.exe simple.exe simpless.exe
|
||||||
|
|
||||||
|
all: $(PROGRAMS)
|
||||||
|
|
||||||
|
.c.exe:
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGRAMS)
|
||||||
|
|
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
|
|||||||
FILE *headerfile;
|
FILE *headerfile;
|
||||||
|
|
||||||
const char *pCertFile = "testcert.pem";
|
const char *pCertFile = "testcert.pem";
|
||||||
const char *pCACertFile="cacert.pem"
|
const char *pCACertFile="cacert.pem";
|
||||||
|
|
||||||
const char *pKeyName;
|
const char *pKeyName;
|
||||||
const char *pKeyType;
|
const char *pKeyType;
|
||||||
|
@@ -78,7 +78,8 @@ uploaded.
|
|||||||
.TP
|
.TP
|
||||||
.B CURLINFO_SIZE_DOWNLOAD
|
.B CURLINFO_SIZE_DOWNLOAD
|
||||||
Pass a pointer to a double to receive the total amount of bytes that were
|
Pass a pointer to a double to receive the total amount of bytes that were
|
||||||
downloaded.
|
downloaded. The amount is only for the latest transfer and will be reset again
|
||||||
|
for each new transfer.
|
||||||
.TP
|
.TP
|
||||||
.B CURLINFO_SPEED_DOWNLOAD
|
.B CURLINFO_SPEED_DOWNLOAD
|
||||||
Pass a pointer to a double to receive the average download speed that curl
|
Pass a pointer to a double to receive the average download speed that curl
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "3 Dec 2002" "libcurl 7.10.3" "libcurl Manual"
|
.TH curl_easy_setopt 3 "10 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_setopt - set options for a curl easy handle
|
curl_easy_setopt - set options for a curl easy handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -272,7 +272,7 @@ The main point of this would be that the write callback gets called more often
|
|||||||
and with smaller chunks. This is just treated as a request, not an order. You
|
and with smaller chunks. This is just treated as a request, not an order. You
|
||||||
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
||||||
.PP
|
.PP
|
||||||
.SH NAMES and PASSWORDS OPTIONS
|
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||||
.TP 0.4i
|
.TP 0.4i
|
||||||
.B CURLOPT_NETRC
|
.B CURLOPT_NETRC
|
||||||
This parameter controls the preference of libcurl between using user names and
|
This parameter controls the preference of libcurl between using user names and
|
||||||
@@ -322,23 +322,76 @@ prompt function.
|
|||||||
|
|
||||||
When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
|
When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
|
||||||
requests to possibly different hosts. libcurl will only send this user and
|
requests to possibly different hosts. libcurl will only send this user and
|
||||||
password information to hosts using the initial host name, so if libcurl
|
password information to hosts using the initial host name (unless
|
||||||
follows locations to other hosts it will not send the user and password to
|
CURLOPT_UNRESTRICTED_AUTH is set), so if libcurl follows locations to other
|
||||||
those. This is enforced to prevent accidental information leakage.
|
hosts it will not send the user and password to those. This is enforced to
|
||||||
|
prevent accidental information leakage.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_PROXYUSERPWD
|
.B CURLOPT_PROXYUSERPWD
|
||||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
Pass a char * as parameter, which should be [user name]:[password] to use for
|
||||||
the connection to the HTTP proxy. If the password is left out, you will be
|
the connection to the HTTP proxy. If the password is left out, you will be
|
||||||
prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
|
prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
|
||||||
prompt function.
|
prompt function.
|
||||||
|
.TP
|
||||||
|
.B CURLOPT_HTTPAUTH
|
||||||
|
Pass a long as parameter, which is set to a bitmask, to tell libcurl what
|
||||||
|
authentication method(s) you want it to use. The available bits are listed
|
||||||
|
below. If more than one bit is set, libcurl will first query the site to see
|
||||||
|
what authentication methods it supports and then pick the best one you allow
|
||||||
|
it to use. Note that for some methods, this will induce an extra network
|
||||||
|
round-trip. Set the actual name and password with the \fICURLOPT_USERPWD\fP
|
||||||
|
option. (Added in 7.10.6)
|
||||||
|
.RS
|
||||||
|
.TP 5
|
||||||
|
.B CURLAUTH_BASIC
|
||||||
|
HTTP Basic authentication. This is the default choice, and the only method
|
||||||
|
that is in wide-spread use and supported virtually everywhere. This is sending
|
||||||
|
the user name and password over the network in plain text, easily captured by
|
||||||
|
others.
|
||||||
|
.TP
|
||||||
|
.B CURLAUTH_DIGEST
|
||||||
|
HTTP Digest authentication. Digest authentication is defined in RFC2617 and
|
||||||
|
is a more secure way to do authentication over public networks than the
|
||||||
|
regular old-fashioned Basic method.
|
||||||
|
.TP
|
||||||
|
.B CURLAUTH_GSSNEGOTIATE
|
||||||
|
HTTP GSS-Negotiate authentication. The GSS-Negotiate method was designed by
|
||||||
|
Microsoft and is used in their web aplications. It is primarily meant as a
|
||||||
|
support for Kerberos5 authentication but may be also used along with another
|
||||||
|
authentication methods. For more information see IETF draft
|
||||||
|
draft-brezak-spnego-http-04.txt.
|
||||||
|
.TP
|
||||||
|
.B CURLAUTH_NTLM
|
||||||
|
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||||
|
Microsoft. It uses a challenge-response and hash concept similar to Digest to
|
||||||
|
prevent the password from being evesdropped.
|
||||||
|
.TP
|
||||||
|
.B CURLAUTH_ANY
|
||||||
|
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
||||||
|
it finds suitable. libcurl will automaticly select the one it finds most
|
||||||
|
secure.
|
||||||
|
.TP
|
||||||
|
.B CURLAUTH_ANYSAFE
|
||||||
|
This is a convenience macro that sets all bits except Basic and thus makes
|
||||||
|
libcurl pick any it finds suitable. libcurl will automaticly select the one it
|
||||||
|
finds most secure.
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
.SH HTTP OPTIONS
|
.SH HTTP OPTIONS
|
||||||
.TP 0.4i
|
.TP 0.4i
|
||||||
.B CURLOPT_ENCODING
|
.B CURLOPT_ENCODING
|
||||||
Two encodings are supported \fIdentity\fP, which does nothing, and
|
Sets the contents of the Accept-Encoding: header sent in an HTTP
|
||||||
\fIdeflate\fP to request the server to compress its reponse using the
|
request, and enables decoding of a response when a Content-Encoding:
|
||||||
zlib algorithm. This is not an order, the server may or may not do it.
|
header is received. Three encodings are supported: \fIidentity\fP,
|
||||||
See the special file lib/README.encoding for details.
|
which does nothing, \fIdeflate\fP which requests the server to
|
||||||
|
compress its response using the zlib algorithm, and \fIgzip\fP which
|
||||||
|
requests the gzip algorithm. If a zero-length string is set, then an
|
||||||
|
Accept-Encoding: header containing all supported encodings is sent.
|
||||||
|
|
||||||
|
This is a request, not an order; the server may or may not do it. This
|
||||||
|
option must be set (to any non-NULL value) or else any unsolicited
|
||||||
|
encoding done by the server is ignored. See the special file
|
||||||
|
lib/README.encoding for details.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_FOLLOWLOCATION
|
.B CURLOPT_FOLLOWLOCATION
|
||||||
A non-zero parameter tells the library to follow any Location: header that the
|
A non-zero parameter tells the library to follow any Location: header that the
|
||||||
@@ -429,6 +482,10 @@ curl adds CRLF after each header item. Failure to comply with this will
|
|||||||
result in strange bugs because the server will most likely ignore part
|
result in strange bugs because the server will most likely ignore part
|
||||||
of the headers you specified.
|
of the headers you specified.
|
||||||
|
|
||||||
|
The first line in a request (usually containing a GET or POST) is not a header
|
||||||
|
and cannot be replaced using this option. Only the lines following the
|
||||||
|
request-line are headers.
|
||||||
|
|
||||||
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
|
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
|
||||||
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
|
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
|
||||||
.TP
|
.TP
|
||||||
@@ -478,6 +535,13 @@ is called. If no cookies are known, no file will be created. Specify "-" to
|
|||||||
instead have the cookies written to stdout. Using this option also enables
|
instead have the cookies written to stdout. Using this option also enables
|
||||||
cookies for this session, so if you for example follow a location it will make
|
cookies for this session, so if you for example follow a location it will make
|
||||||
matching cookies get sent accordingly. (Added in 7.9)
|
matching cookies get sent accordingly. (Added in 7.9)
|
||||||
|
|
||||||
|
.B NOTE
|
||||||
|
If the cookie jar file can't be created or written to (when the
|
||||||
|
curl_easy_cleanup() is called), libcurl will not and cannot report an error
|
||||||
|
for this. Using CURLOPT_VERBOSE or CURLOPT_DEBUGFUNCTION will get a warning to
|
||||||
|
display, but that is the only visible feedback you get about this possibly
|
||||||
|
lethal situation.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_TIMECONDITION
|
.B CURLOPT_TIMECONDITION
|
||||||
Pass a long as parameter. This defines how the CURLOPT_TIMEVALUE time value is
|
Pass a long as parameter. This defines how the CURLOPT_TIMEVALUE time value is
|
||||||
@@ -560,6 +624,13 @@ and symbolic links.
|
|||||||
A non-zero parameter tells the library to append to the remote file instead of
|
A non-zero parameter tells the library to append to the remote file instead of
|
||||||
overwrite it. This is only useful when uploading to a ftp site.
|
overwrite it. This is only useful when uploading to a ftp site.
|
||||||
.TP
|
.TP
|
||||||
|
.B CURLOPT_FTP_USE_EPRT
|
||||||
|
Pass a long. If the value is non-zero, it tells curl to use the EPRT (and
|
||||||
|
LPRT) command when doing active FTP downloads (which is enabled by
|
||||||
|
CURLOPT_FTPPORT). Using EPRT means that it will first attempt to use EPRT and
|
||||||
|
then LPRT before using PORT, but if you pass FALSE (zero) to this option, it
|
||||||
|
will not try using EPRT or LPRT, only plain PORT. (Added in 7.10.5)
|
||||||
|
.TP
|
||||||
.B CURLOPT_FTP_USE_EPSV
|
.B CURLOPT_FTP_USE_EPSV
|
||||||
Pass a long. If the value is non-zero, it tells curl to use the EPSV command
|
Pass a long. If the value is non-zero, it tells curl to use the EPSV command
|
||||||
when doing passive FTP downloads (which it always does by default). Using EPSV
|
when doing passive FTP downloads (which it always does by default). Using EPSV
|
||||||
@@ -593,9 +664,18 @@ want the transfer to start from.
|
|||||||
.TP
|
.TP
|
||||||
.B CURLOPT_CUSTOMREQUEST
|
.B CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It will be user
|
Pass a pointer to a zero terminated string as parameter. It will be user
|
||||||
instead of GET or HEAD when doing the HTTP request. This is useful for doing
|
instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST
|
||||||
DELETE or other more or less obscure HTTP requests. Don't do this at will,
|
when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||||
make sure your server supports the command first.
|
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||||
|
server supports the command first.
|
||||||
|
|
||||||
|
NOTE: many people have wrongly used this option to replace the entire request
|
||||||
|
with their own, including multiple headers and POST contents. While that might
|
||||||
|
work in many cases, it will cause libcurl to send invalid requests and it
|
||||||
|
could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
||||||
|
\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||||
|
replace or extend the set of headers sent by libcurl. Use
|
||||||
|
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_FILETIME
|
.B CURLOPT_FILETIME
|
||||||
Pass a long. If it is a non-zero value, libcurl will attempt to get the
|
Pass a long. If it is a non-zero value, libcurl will attempt to get the
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_slist_append 3 "21 Feb 2003" "libcurl 7.10.4" "libcurl Manual"
|
.TH curl_slist_append 3 "19 Jun 2003" "libcurl 7.10.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_slist_append - add a string to an slist
|
curl_slist_append - add a string to an slist
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -15,7 +15,8 @@ curl_slist_append - add a string to an slist
|
|||||||
curl_slist_append() appends a specified string to a linked list of
|
curl_slist_append() appends a specified string to a linked list of
|
||||||
strings. The existing \fIlist\fP should be passed as the first argument while
|
strings. The existing \fIlist\fP should be passed as the first argument while
|
||||||
the new list is returned from this function. The specified \fIstring\fP has
|
the new list is returned from this function. The specified \fIstring\fP has
|
||||||
been appended when this function returns.
|
been appended when this function returns. curl_slist_append() copies the
|
||||||
|
string.
|
||||||
|
|
||||||
The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP.
|
The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_version_info 3 "30 Sep 2002" "libcurl 7.10" "libcurl Manual"
|
.TH curl_version_info 3 "17 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_version_info - returns run-time libcurl version info
|
curl_version_info - returns run-time libcurl version info
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -69,6 +69,16 @@ supports SSL (HTTPS/FTPS)
|
|||||||
.TP
|
.TP
|
||||||
.B CURL_VERSION_LIBZ
|
.B CURL_VERSION_LIBZ
|
||||||
supports HTTP deflate using libz
|
supports HTTP deflate using libz
|
||||||
|
.TP
|
||||||
|
.B CURL_VERSION_NTLM
|
||||||
|
supports HTTP NTLM (added in 7.10.6)
|
||||||
|
.TP
|
||||||
|
.B CURL_VERSION_GSSNEGOTIATE
|
||||||
|
supports HTTP GSS-Negotiate (added in 7.10.6)
|
||||||
|
.TP
|
||||||
|
.B CURL_VERSION_DEBUG
|
||||||
|
libcurl was built with extra debug capabilities built-in. This is mainly of
|
||||||
|
interest for libcurl hackers. (added in 7.10.6)
|
||||||
.PP
|
.PP
|
||||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||||
has no SSL support, this is NULL.
|
has no SSL support, this is NULL.
|
||||||
@@ -83,8 +93,6 @@ libcurl has no libz support, this is NULL.
|
|||||||
names protocols that libcurl supports (using lowercase letters). The protocol
|
names protocols that libcurl supports (using lowercase letters). The protocol
|
||||||
names are the same as would be used in URLs. The array is terminated by a NULL
|
names are the same as would be used in URLs. The array is terminated by a NULL
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a curl_version_info_data struct.
|
A pointer to a curl_version_info_data struct.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -13,3 +13,26 @@ of environment. You should include files from here using...
|
|||||||
|
|
||||||
... style and point the compiler's include path to the directory holding the
|
... style and point the compiler's include path to the directory holding the
|
||||||
curl subdirectory. It makes it more likely to survive future modifications.
|
curl subdirectory. It makes it more likely to survive future modifications.
|
||||||
|
|
||||||
|
NOTE FOR LIBCURL HACKERS
|
||||||
|
|
||||||
|
All the include files in this tree are written and intended to be installed on
|
||||||
|
a system that may serve multiple platforms and multiple applications, all
|
||||||
|
using libcurl (possibly even different libcurl installations using different
|
||||||
|
versions). Therefore, all header files in here must obey these rules:
|
||||||
|
|
||||||
|
* They cannot depend on or use configure-generated results from libcurl's or
|
||||||
|
curl's directories. Other applications may not run configure as (lib)curl
|
||||||
|
does, and using platform dependent info here may break other platforms.
|
||||||
|
|
||||||
|
* We cannot assume anything else but very basic compiler features being
|
||||||
|
present. While libcurl requires an ANSI C compiler to build, some of the
|
||||||
|
earlier ANSI compilers clearly can't deal with some preprocessor operators.
|
||||||
|
|
||||||
|
* Newlines must remain unix-style for older compilers' sake.
|
||||||
|
|
||||||
|
* Comments must be written in the old-style /* unnested C-fashion */
|
||||||
|
|
||||||
|
To figure out how to do good and portable checks for features, operating
|
||||||
|
systems or specific hardwarare, a very good resource is Bjorn Reese's
|
||||||
|
collection at http://predef.sf.net/
|
||||||
|
@@ -23,23 +23,39 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* If you have problems, all libcurl docs and details are found here:
|
||||||
|
http://curl.haxx.se/libcurl/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is the version number of the libcurl package from which this header
|
||||||
|
file origins: */
|
||||||
|
#define LIBCURL_VERSION "7.10.6"
|
||||||
|
|
||||||
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
|
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||||
|
always follow this syntax:
|
||||||
|
|
||||||
|
0xXXYYZZ
|
||||||
|
|
||||||
|
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||||
|
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||||
|
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||||
|
|
||||||
|
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||||
|
always a greater number in a more recent release. It makes comparisons with
|
||||||
|
greater than and less than work.
|
||||||
|
*/
|
||||||
|
#define LIBCURL_VERSION_NUM 0x070a06
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
/* The include stuff here is mainly for time_t! */
|
|
||||||
|
/* The include stuff here below is mainly for time_t! */
|
||||||
#ifdef vms
|
#ifdef vms
|
||||||
# include <types.h>
|
# include <types.h>
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# ifdef TIME_WITH_SYS_TIME
|
|
||||||
# include <sys/time.h>
|
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# else
|
|
||||||
# ifdef HAVE_SYS_TIME_H
|
|
||||||
# include <sys/time.h>
|
|
||||||
# else
|
|
||||||
# include <time.h>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif /* defined (vms) */
|
#endif /* defined (vms) */
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
@@ -55,8 +71,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* stupid #define trick to preserve functionality with older code, but
|
/* silly trick to preserve functionality with older code, but making it use
|
||||||
making it use our name space for the future */
|
our name space for the future */
|
||||||
#define HttpPost curl_httppost
|
#define HttpPost curl_httppost
|
||||||
|
|
||||||
struct curl_httppost {
|
struct curl_httppost {
|
||||||
@@ -65,15 +81,13 @@ struct curl_httppost {
|
|||||||
long namelength; /* length of name length */
|
long namelength; /* length of name length */
|
||||||
char *contents; /* pointer to allocated data contents */
|
char *contents; /* pointer to allocated data contents */
|
||||||
long contentslength; /* length of contents field */
|
long contentslength; /* length of contents field */
|
||||||
|
|
||||||
/* CMC: Added support for buffer uploads */
|
|
||||||
char *buffer; /* pointer to allocated buffer contents */
|
char *buffer; /* pointer to allocated buffer contents */
|
||||||
long bufferlength; /* length of buffer field */
|
long bufferlength; /* length of buffer field */
|
||||||
|
|
||||||
char *contenttype; /* Content-Type */
|
char *contenttype; /* Content-Type */
|
||||||
struct curl_slist* contentheader; /* list of extra headers for this form */
|
struct curl_slist* contentheader; /* list of extra headers for this form */
|
||||||
struct curl_httppost *more; /* if one field name has more than one file, this
|
struct curl_httppost *more; /* if one field name has more than one
|
||||||
link should link to following files */
|
file, this link should link to following
|
||||||
|
files */
|
||||||
long flags; /* as defined below */
|
long flags; /* as defined below */
|
||||||
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
|
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
|
||||||
#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
|
#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
|
||||||
@@ -81,13 +95,12 @@ struct curl_httppost {
|
|||||||
do not free in formfree */
|
do not free in formfree */
|
||||||
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
||||||
do not free in formfree */
|
do not free in formfree */
|
||||||
|
|
||||||
/* CMC: Added support for buffer uploads */
|
|
||||||
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
||||||
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
||||||
|
|
||||||
char *showfilename; /* The file name to show. If not set, the actual
|
char *showfilename; /* The file name to show. If not set, the
|
||||||
file name will be used (if this is a file part) */
|
actual file name will be used (if this
|
||||||
|
is a file part) */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*curl_progress_callback)(void *clientp,
|
typedef int (*curl_progress_callback)(void *clientp,
|
||||||
@@ -130,7 +143,7 @@ typedef int (*curl_debug_callback)
|
|||||||
curl_infotype type, /* what kind of data */
|
curl_infotype type, /* what kind of data */
|
||||||
char *data, /* points to the data */
|
char *data, /* points to the data */
|
||||||
size_t size, /* size of the data pointed to */
|
size_t size, /* size of the data pointed to */
|
||||||
void *userp); /* whatever the user please */
|
void *userptr); /* whatever the user please */
|
||||||
|
|
||||||
/* All possible error codes from all sorts of curl functions. Future versions
|
/* All possible error codes from all sorts of curl functions. Future versions
|
||||||
may return other values, stay prepared.
|
may return other values, stay prepared.
|
||||||
@@ -207,6 +220,11 @@ typedef enum {
|
|||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
|
|
||||||
|
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
||||||
|
void *ssl_ctx, /* actually an
|
||||||
|
OpenSSL SSL_CTX */
|
||||||
|
void *userptr);
|
||||||
|
|
||||||
/* Make a spelling correction for the operation timed-out define */
|
/* Make a spelling correction for the operation timed-out define */
|
||||||
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
||||||
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
||||||
@@ -217,6 +235,14 @@ typedef enum {
|
|||||||
CURLPROXY_SOCKS5 = 5
|
CURLPROXY_SOCKS5 = 5
|
||||||
} curl_proxytype;
|
} curl_proxytype;
|
||||||
|
|
||||||
|
#define CURLAUTH_NONE 0 /* nothing */
|
||||||
|
#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
|
||||||
|
#define CURLAUTH_DIGEST (1<<1) /* Digest */
|
||||||
|
#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
|
||||||
|
#define CURLAUTH_NTLM (1<<3) /* NTLM */
|
||||||
|
#define CURLAUTH_ANY ~0 /* all types set */
|
||||||
|
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
|
||||||
|
|
||||||
/* this was the error code 50 in 7.7.3 and a few earlier versions, this
|
/* this was the error code 50 in 7.7.3 and a few earlier versions, this
|
||||||
is no longer used by libcurl but is instead #defined here only to not
|
is no longer used by libcurl but is instead #defined here only to not
|
||||||
make programs break */
|
make programs break */
|
||||||
@@ -266,6 +292,12 @@ typedef enum {
|
|||||||
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
|
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This macro-mania below setups the CURLOPT_[what] enum, to be used with
|
||||||
|
* curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
|
||||||
|
* word.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
||||||
|
|
||||||
@@ -275,24 +307,19 @@ typedef enum {
|
|||||||
/* The full URL to get/put */
|
/* The full URL to get/put */
|
||||||
CINIT(URL, OBJECTPOINT, 2),
|
CINIT(URL, OBJECTPOINT, 2),
|
||||||
|
|
||||||
/* Port number to connect to, if other than default. Specify the CONF_PORT
|
/* Port number to connect to, if other than default. */
|
||||||
flag in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(PORT, LONG, 3),
|
CINIT(PORT, LONG, 3),
|
||||||
|
|
||||||
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to
|
/* Name of proxy to use. */
|
||||||
activate this */
|
|
||||||
CINIT(PROXY, OBJECTPOINT, 4),
|
CINIT(PROXY, OBJECTPOINT, 4),
|
||||||
|
|
||||||
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in
|
/* "name:password" to use when fetching. */
|
||||||
the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||||
|
|
||||||
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD
|
/* "name:password" to use with proxy. */
|
||||||
flag in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||||
|
|
||||||
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag
|
/* Range to get, specified as an ASCII string. */
|
||||||
in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(RANGE, OBJECTPOINT, 7),
|
CINIT(RANGE, OBJECTPOINT, 7),
|
||||||
|
|
||||||
/* not used */
|
/* not used */
|
||||||
@@ -413,7 +440,6 @@ typedef enum {
|
|||||||
as described elsewhere. */
|
as described elsewhere. */
|
||||||
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
||||||
|
|
||||||
/* Previous FLAG bits */
|
|
||||||
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
||||||
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
||||||
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
||||||
@@ -624,6 +650,25 @@ typedef enum {
|
|||||||
and password to whatever host the server decides. */
|
and password to whatever host the server decides. */
|
||||||
CINIT(UNRESTRICTED_AUTH, LONG, 105),
|
CINIT(UNRESTRICTED_AUTH, LONG, 105),
|
||||||
|
|
||||||
|
/* Specificly switch on or off the FTP engine's use of the EPRT command ( it
|
||||||
|
also disables the LPRT attempt). By default, those ones will always be
|
||||||
|
attempted before the good old traditional PORT command. */
|
||||||
|
CINIT(FTP_USE_EPRT, LONG, 106),
|
||||||
|
|
||||||
|
/* Set this to a bitmask value to enable the particular authentications
|
||||||
|
methods you like. Use this in combination with CURLOPT_USERPWD.
|
||||||
|
Note that setting multiple bits may cause extra network round-trips. */
|
||||||
|
CINIT(HTTPAUTH, LONG, 107),
|
||||||
|
|
||||||
|
/* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
|
||||||
|
in second argument. The function must be matching the
|
||||||
|
curl_ssl_ctx_callback proto. */
|
||||||
|
CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
|
||||||
|
|
||||||
|
/* Set the userdata for the ssl context callback function's third
|
||||||
|
argument */
|
||||||
|
CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -692,9 +737,9 @@ typedef enum {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* These functions are in the libcurl, they're here for portable reasons and
|
/* These functions are in libcurl, they're here for portable reasons and they
|
||||||
they are used by the 'curl' client. They really should be moved to some kind
|
are used by the 'curl' client. They really should be moved to some kind of
|
||||||
of "portability library" since it has nothing to do with file transfers and
|
"portability library" since it has nothing to do with file transfers and
|
||||||
might be usable to other programs...
|
might be usable to other programs...
|
||||||
|
|
||||||
NOTE: they return TRUE if the strings match *case insensitively*.
|
NOTE: they return TRUE if the strings match *case insensitively*.
|
||||||
@@ -702,9 +747,12 @@ typedef enum {
|
|||||||
extern int (curl_strequal)(const char *s1, const char *s2);
|
extern int (curl_strequal)(const char *s1, const char *s2);
|
||||||
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
||||||
|
|
||||||
/* DEPRECATED function to build formdata */
|
#ifdef CURL_OLDSTYLE
|
||||||
|
/* DEPRECATED function to build formdata. Stop using this, it will cease
|
||||||
|
to exist. */
|
||||||
int curl_formparse(char *, struct curl_httppost **,
|
int curl_formparse(char *, struct curl_httppost **,
|
||||||
struct curl_httppost **_post);
|
struct curl_httppost **_post);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* name is uppercase CURLFORM_<name> */
|
/* name is uppercase CURLFORM_<name> */
|
||||||
#ifdef CFINIT
|
#ifdef CFINIT
|
||||||
@@ -783,47 +831,122 @@ typedef enum {
|
|||||||
CURL_FORMADD_LAST /* last */
|
CURL_FORMADD_LAST /* last */
|
||||||
} CURLFORMcode;
|
} CURLFORMcode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_formadd()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Pretty advanved function for building multi-part formposts. Each invoke
|
||||||
|
* adds one part that together construct a full post. Then use
|
||||||
|
* CURLOPT_HTTPPOST to send it off to libcurl.
|
||||||
|
*/
|
||||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
struct curl_httppost **last_post,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
/* cleanup a form: */
|
/*
|
||||||
|
* NAME curl_formfree()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Free a multipart formpost previously built with curl_formadd().
|
||||||
|
*/
|
||||||
void curl_formfree(struct curl_httppost *form);
|
void curl_formfree(struct curl_httppost *form);
|
||||||
|
|
||||||
/* Unix and Win32 getenv function call, this returns a malloc()'ed string that
|
/*
|
||||||
MUST be free()ed after usage is complete. */
|
* NAME curl_getenv()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Returns a malloc()'ed string that MUST be curl_free()ed after usage is
|
||||||
|
* complete.
|
||||||
|
*/
|
||||||
char *curl_getenv(const char *variable);
|
char *curl_getenv(const char *variable);
|
||||||
|
|
||||||
/* Returns a static ascii string of the libcurl version. */
|
/*
|
||||||
|
* NAME curl_version()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Returns a static ascii string of the libcurl version.
|
||||||
|
*/
|
||||||
char *curl_version(void);
|
char *curl_version(void);
|
||||||
|
|
||||||
/* Escape and unescape URL encoding in strings. The functions return a new
|
/*
|
||||||
* allocated string or NULL if an error occurred. */
|
* NAME curl_escape()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Escapes URL strings (converts all letters consider illegal in URLs to their
|
||||||
|
* %XX versions). This function returns a new allocated string or NULL if an
|
||||||
|
* error occurred.
|
||||||
|
*/
|
||||||
char *curl_escape(const char *string, int length);
|
char *curl_escape(const char *string, int length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_unescape()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
||||||
|
* versions). This function returns a new allocated string or NULL if an error
|
||||||
|
* occurred.
|
||||||
|
*/
|
||||||
char *curl_unescape(const char *string, int length);
|
char *curl_unescape(const char *string, int length);
|
||||||
/* 20020912 WJM. Provide for a de-allocation in the same translation unit
|
|
||||||
that did the allocation. Added in libcurl 7.10 */
|
/*
|
||||||
|
* NAME curl_free()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Provided for de-allocation in the same translation unit that did the
|
||||||
|
* allocation. Added in libcurl 7.10
|
||||||
|
*/
|
||||||
void curl_free(void *p);
|
void curl_free(void *p);
|
||||||
|
|
||||||
/* curl_global_init() should be invoked exactly once for each application that
|
/*
|
||||||
uses libcurl */
|
* NAME curl_global_init()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* curl_global_init() should be invoked exactly once for each application that
|
||||||
|
* uses libcurl
|
||||||
|
*/
|
||||||
CURLcode curl_global_init(long flags);
|
CURLcode curl_global_init(long flags);
|
||||||
|
|
||||||
/* curl_global_cleanup() should be invoked exactly once for each application
|
/*
|
||||||
that uses libcurl */
|
* NAME curl_global_cleanup()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* curl_global_cleanup() should be invoked exactly once for each application
|
||||||
|
* that uses libcurl
|
||||||
|
*/
|
||||||
void curl_global_cleanup(void);
|
void curl_global_cleanup(void);
|
||||||
|
|
||||||
/* This is the version number */
|
|
||||||
#define LIBCURL_VERSION "7.10.4"
|
|
||||||
#define LIBCURL_VERSION_NUM 0x070a04
|
|
||||||
|
|
||||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||||
struct curl_slist {
|
struct curl_slist {
|
||||||
char *data;
|
char *data;
|
||||||
struct curl_slist *next;
|
struct curl_slist *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_slist_append()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Appends a string to a linked list. If no list exists, it will be created
|
||||||
|
* first. Returns the new list, after appending.
|
||||||
|
*/
|
||||||
struct curl_slist *curl_slist_append(struct curl_slist *, const char *);
|
struct curl_slist *curl_slist_append(struct curl_slist *, const char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_slist_free_all()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* free a previously built curl_slist.
|
||||||
|
*/
|
||||||
void curl_slist_free_all(struct curl_slist *);
|
void curl_slist_free_all(struct curl_slist *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -991,8 +1114,18 @@ typedef struct {
|
|||||||
#define CURL_VERSION_KERBEROS4 (1<<1)
|
#define CURL_VERSION_KERBEROS4 (1<<1)
|
||||||
#define CURL_VERSION_SSL (1<<2)
|
#define CURL_VERSION_SSL (1<<2)
|
||||||
#define CURL_VERSION_LIBZ (1<<3)
|
#define CURL_VERSION_LIBZ (1<<3)
|
||||||
|
#define CURL_VERSION_NTLM (1<<4)
|
||||||
|
#define CURL_VERSION_GSSNEGOTIATE (1<<5)
|
||||||
|
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||||
|
|
||||||
/* returns a pointer to a static copy of the version info struct */
|
/*
|
||||||
|
* NAME curl_version_info()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* This function returns a pointer to a static copy of the version info
|
||||||
|
* struct. See above.
|
||||||
|
*/
|
||||||
curl_version_info_data *curl_version_info(CURLversion);
|
curl_version_info_data *curl_version_info(CURLversion);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -45,10 +45,23 @@
|
|||||||
file descriptors simultaneous easily.
|
file descriptors simultaneous easily.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(WIN32)
|
||||||
|
/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
|
||||||
|
make this adjustment to catch this. */
|
||||||
|
#define WIN32 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||||
|
libc5-based Linux systems. Only include it on system that are known to
|
||||||
|
require it! */
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@@ -23,9 +23,7 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t fread (void *, size_t, size_t, FILE *);
|
size_t fread (void *, size_t, size_t, FILE *);
|
||||||
size_t fwrite (const void *, size_t, size_t, FILE *);
|
size_t fwrite (const void *, size_t, size_t, FILE *);
|
||||||
|
@@ -7,7 +7,8 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
|||||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
||||||
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
||||||
config.h.in ca-bundle.crt README.encoding README.memoryleak
|
config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
||||||
|
makefile.dj config.dj
|
||||||
|
|
||||||
lib_LTLIBRARIES = libcurl.la
|
lib_LTLIBRARIES = libcurl.la
|
||||||
|
|
||||||
@@ -66,16 +67,29 @@ getpass.c netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
|||||||
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
||||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
|
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
|
||||||
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
||||||
content_encoding.c content_encoding.h share.c share.h
|
content_encoding.c content_encoding.h share.c share.h http_digest.c \
|
||||||
|
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
|
||||||
|
http_ntlm.c http_ntlm.h ca-bundle.h
|
||||||
|
|
||||||
noinst_HEADERS = setup.h transfer.h
|
noinst_HEADERS = setup.h transfer.h
|
||||||
|
|
||||||
|
BUILT_SOURCES = $(srcdir)/getdate.c $(srcdir)/ca-bundle.h
|
||||||
|
|
||||||
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
|
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
|
||||||
$(srcdir)/getdate.c: getdate.y
|
$(srcdir)/getdate.c: getdate.y
|
||||||
cd $(srcdir) && \
|
cd $(srcdir) && \
|
||||||
$(YACC) $(YFLAGS) getdate.y; \
|
$(YACC) $(YFLAGS) getdate.y; \
|
||||||
mv -f y.tab.c getdate.c
|
mv -f y.tab.c getdate.c
|
||||||
|
|
||||||
|
$(srcdir)/ca-bundle.h: Makefile.in Makefile
|
||||||
|
cd $(srcdir) && \
|
||||||
|
echo "/* The file is generated automaticly */" > $@
|
||||||
|
if CABUNDLE
|
||||||
|
echo '#define CURL_CA_BUNDLE @CURL_CA_BUNDLE@' >> $@
|
||||||
|
else
|
||||||
|
echo '#undef CURL_CA_BUNDLE /* unknown */' >> $@
|
||||||
|
endif
|
||||||
|
|
||||||
install-data-hook:
|
install-data-hook:
|
||||||
@if test -n "@CURL_CA_BUNDLE@"; then \
|
@if test -n "@CURL_CA_BUNDLE@"; then \
|
||||||
$(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \
|
$(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \
|
||||||
@@ -85,4 +99,4 @@ install-data-hook:
|
|||||||
# this hook is mainly for non-unix systems to build even if configure
|
# this hook is mainly for non-unix systems to build even if configure
|
||||||
# isn't run
|
# isn't run
|
||||||
dist-hook:
|
dist-hook:
|
||||||
cp $(srcdir)/ca-bundle.h.in $(distdir)/ca-bundle.h
|
echo "/* ca bundle path set in here*/" > $(distdir)/ca-bundle.h
|
||||||
|
@@ -35,15 +35,19 @@ COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
|||||||
libcurl_a_LIBRARIES = libcurl.a
|
libcurl_a_LIBRARIES = libcurl.a
|
||||||
|
|
||||||
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
|
libcurl_a_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 \
|
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||||
cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c \
|
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
|
||||||
ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h \
|
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h \
|
||||||
urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \
|
dict.h getdate.c if2ip.h speedcheck.h urldata.h transfer.c getdate.h \
|
||||||
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
|
ldap.c ssluse.c version.c transfer.h getenv.c \
|
||||||
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
|
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h \
|
||||||
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \
|
getpass.c netrc.c telnet.h getinfo.c strequal.c strequal.h easy.c \
|
||||||
strtok.c connect.c hash.c llist.c multi.c share.c share.h\
|
security.h security.c krb4.h krb4.c memdebug.h memdebug.c \
|
||||||
content_encoding.h content_encoding.c
|
inet_ntoa_r.h http_chunks.h http_chunks.c \
|
||||||
|
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
|
||||||
|
content_encoding.h content_encoding.c http_digest.h http_digest.c \
|
||||||
|
http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h md5.h \
|
||||||
|
md5.c
|
||||||
|
|
||||||
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||||
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
||||||
@@ -51,7 +55,7 @@ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
|||||||
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
|
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
|
||||||
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
||||||
strtok.o connect.o hash.o llist.o multi.o share.o \
|
strtok.o connect.o hash.o llist.o multi.o share.o \
|
||||||
content_encoding.o
|
content_encoding.o http_digest.o http_negotiate.o http_ntlm.o md5.o
|
||||||
|
|
||||||
LIBRARIES = $(libcurl_a_LIBRARIES)
|
LIBRARIES = $(libcurl_a_LIBRARIES)
|
||||||
SOURCES = $(libcurl_a_SOURCES)
|
SOURCES = $(libcurl_a_SOURCES)
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
LIB_NAME = libcurl
|
LIB_NAME = libcurl
|
||||||
LIB_NAME_DEBUG = libcurld
|
LIB_NAME_DEBUG = libcurld
|
||||||
!IFNDEF OPENSSL_PATH
|
!IFNDEF OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../openssl-0.9.6
|
OPENSSL_PATH = ../../openssl-0.9.7a
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
@@ -48,7 +48,8 @@ LNKDLL = link.exe /DLL /def:libcurl.def
|
|||||||
LNKLIB = link.exe -lib
|
LNKLIB = link.exe -lib
|
||||||
LFLAGS = /nologo
|
LFLAGS = /nologo
|
||||||
LINKLIBS = ws2_32.lib winmm.lib
|
LINKLIBS = ws2_32.lib winmm.lib
|
||||||
SSLLIBS = libeay32.lib ssleay32.lib RSAglue.lib
|
SSLLIBS = libeay32.lib ssleay32.lib
|
||||||
|
# RSAglue.lib was formerly needed in the SSLLIBS
|
||||||
CFGSET = FALSE
|
CFGSET = FALSE
|
||||||
|
|
||||||
######################
|
######################
|
||||||
@@ -201,7 +202,9 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\hash.obj \
|
$(DIROBJ)\hash.obj \
|
||||||
$(DIROBJ)\llist.obj \
|
$(DIROBJ)\llist.obj \
|
||||||
$(DIROBJ)\share.obj \
|
$(DIROBJ)\share.obj \
|
||||||
$(DIROBJ)\multi.obj
|
$(DIROBJ)\multi.obj \
|
||||||
|
$(DIROBJ)\http_digest.obj \
|
||||||
|
$(DIROBJ)\md5.obj
|
||||||
|
|
||||||
all : $(TARGET)
|
all : $(TARGET)
|
||||||
|
|
||||||
@@ -223,3 +226,6 @@ clean:
|
|||||||
-@erase $(DIROBJ)\*.obj
|
-@erase $(DIROBJ)\*.obj
|
||||||
-@erase vc60.idb
|
-@erase vc60.idb
|
||||||
-@erase vc60.pch
|
-@erase vc60.pch
|
||||||
|
|
||||||
|
getdate.c: getdate.c.cvs
|
||||||
|
copy getdate.c.cvs getdate.c
|
||||||
|
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
HTTP/1.1 [RFC 2616] specifies that a client may request that a server encode
|
HTTP/1.1 [RFC 2616] specifies that a client may request that a server encode
|
||||||
its response. This is usually used to compress a response using one of a set
|
its response. This is usually used to compress a response using one of a set
|
||||||
of commonly available compression techniques. These schemes are `deflate'
|
of commonly available compression techniques. These schemes are `deflate' (the
|
||||||
(the zlib algorithm), `gzip' and `compress' [sec 3.5, RFC 2616]. A client
|
zlib algorithm), `gzip' and `compress' [sec 3.5, RFC 2616]. A client requests
|
||||||
requests that the sever perform an encoding by including an Accept-Encoding
|
that the sever perform an encoding by including an Accept-Encoding header in
|
||||||
header in the request document. The value of the header should be one of the
|
the request document. The value of the header should be one of the recognized
|
||||||
recognized tokens `deflate', ... (there's a way to register new
|
tokens `deflate', ... (there's a way to register new schemes/tokens, see sec
|
||||||
schemes/tokens, see sec 3.5 of the spec). A server MAY honor the client's
|
3.5 of the spec). A server MAY honor the client's encoding request. When a
|
||||||
encoding request. When a response is encoded, the server includes a
|
response is encoded, the server includes a Content-Encoding header in the
|
||||||
Content-Encoding header in the response. The value of the Content-Encoding
|
response. The value of the Content-Encoding header indicates which scheme was
|
||||||
header indicates which scheme was used to encode the data.
|
used to encode the data.
|
||||||
|
|
||||||
A client may tell a server that it can understand several different encoding
|
A client may tell a server that it can understand several different encoding
|
||||||
schemes. In this case the server may choose any one of those and use it to
|
schemes. In this case the server may choose any one of those and use it to
|
||||||
@@ -24,11 +24,10 @@ information on the Accept-Encoding header.
|
|||||||
|
|
||||||
* Current support for content encoding:
|
* Current support for content encoding:
|
||||||
|
|
||||||
I added support for the 'deflate' content encoding to both libcurl and curl.
|
Support for the 'deflate' and 'gzip' content encoding are supported by
|
||||||
Both regular and chunked transfers should work although I've tested only the
|
libcurl. Both regular and chunked transfers should work fine. The library
|
||||||
former. The library zlib is required for this feature. Places where I
|
zlib is required for this feature. 'deflate' support was added by James
|
||||||
modified the source code are commented and typically include my initials and
|
Gallagher, and support for the 'gzip' encoding was added by Dan Fandrich.
|
||||||
the date (e.g., 08/29/02 jhrg).
|
|
||||||
|
|
||||||
* The libcurl interface:
|
* The libcurl interface:
|
||||||
|
|
||||||
@@ -39,11 +38,18 @@ To cause libcurl to request a content encoding use:
|
|||||||
where <string> is the intended value of the Accept-Encoding header.
|
where <string> is the intended value of the Accept-Encoding header.
|
||||||
|
|
||||||
Currently, libcurl only understands how to process responses that use the
|
Currently, libcurl only understands how to process responses that use the
|
||||||
`deflate' Content-Encoding, so the only value for CURLOPT_ENCODING that will
|
"deflate" or "gzip" Content-Encoding, so the only values for CURLOPT_ENCODING
|
||||||
work (besides "identity," which does nothing) is "deflate." If a response is
|
that will work (besides "identity," which does nothing) are "deflate" and
|
||||||
encoded using either the `gzip' or `compress' methods, libcurl will return an
|
"gzip" If a response is encoded using the "compress" or methods, libcurl will
|
||||||
error indicating that the response could not be decoded. If <string> is null
|
return an error indicating that the response could not be decoded. If
|
||||||
or empty no Accept-Encoding header is generated.
|
<string> is NULL no Accept-Encoding header is generated. If <string> is a
|
||||||
|
zero-length string, then an Accept-Encoding header containing all supported
|
||||||
|
encodings will be generated.
|
||||||
|
|
||||||
|
The CURLOPT_ENCODING must be set to any non-NULL value for content to be
|
||||||
|
automatically decoded. If it is not set and the server still sends encoded
|
||||||
|
content (despite not having been asked), the data is returned in its raw form
|
||||||
|
and the Content-Encoding type is not checked.
|
||||||
|
|
||||||
* The curl interface:
|
* The curl interface:
|
||||||
|
|
||||||
@@ -51,3 +57,4 @@ Use the --compressed option with curl to cause it to ask servers to compress
|
|||||||
responses using deflate.
|
responses using deflate.
|
||||||
|
|
||||||
James Gallagher <jgallagher@gso.uri.edu>
|
James Gallagher <jgallagher@gso.uri.edu>
|
||||||
|
Dan Fandrich <dan@coneharvesters.com>
|
||||||
|
@@ -17,7 +17,7 @@ Single-threaded
|
|||||||
|
|
||||||
Build
|
Build
|
||||||
|
|
||||||
Rebuild libcurl with -DMALLOCDEBUG (usually, rerunning configure with
|
Rebuild libcurl with -DCURLDEBUG (usually, rerunning configure with
|
||||||
--enable-debug fixes this). 'make clean' first, then 'make' so that all
|
--enable-debug fixes this). 'make clean' first, then 'make' so that all
|
||||||
files actually are rebuilt properly. It will also make sense to build
|
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
|
libcurl with the debug option (usually -g to the compiler) so that debugging
|
||||||
|
24
lib/base64.c
24
lib/base64.c
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -220,6 +220,8 @@ int main(int argc, char **argv, char **envp)
|
|||||||
#ifdef TEST_DECODE
|
#ifdef TEST_DECODE
|
||||||
/* decoding test harness. Read in a base64 string from stdin and write out the
|
/* decoding test harness. Read in a base64 string from stdin and write out the
|
||||||
* length returned by Curl_base64_decode, followed by the decoded data itself
|
* length returned by Curl_base64_decode, followed by the decoded data itself
|
||||||
|
*
|
||||||
|
* gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -232,13 +234,31 @@ int main(int argc, char **argv, char **envp)
|
|||||||
int base64Len;
|
int base64Len;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int dataLen;
|
int dataLen;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
base64 = (char *)suck(&base64Len);
|
base64 = (char *)suck(&base64Len);
|
||||||
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
||||||
dataLen = Curl_base64_decode(base64, data);
|
dataLen = Curl_base64_decode(base64, data);
|
||||||
|
|
||||||
fprintf(stderr, "%d\n", dataLen);
|
fprintf(stderr, "%d\n", dataLen);
|
||||||
fwrite(data,1,dataLen,stdout);
|
|
||||||
|
for(i=0; i < dataLen; i+=0x10) {
|
||||||
|
printf("0x%02x: ", i);
|
||||||
|
for(j=0; j < 0x10; j++)
|
||||||
|
if((j+i) < dataLen)
|
||||||
|
printf("%02x ", data[i+j]);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
printf(" | ");
|
||||||
|
|
||||||
|
for(j=0; j < 0x10; j++)
|
||||||
|
if((j+i) < dataLen)
|
||||||
|
printf("%c", isgraph(data[i+j])?data[i+j]:'.');
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
free(base64); free(data);
|
free(base64); free(data);
|
||||||
return 0;
|
return 0;
|
||||||
|
92
lib/config.dj
Normal file
92
lib/config.dj
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#ifndef _CURL_CONFIG_DJGPP_H
|
||||||
|
#define _CURL_CONFIG_DJGPP_H
|
||||||
|
|
||||||
|
#define OS "djgpp"
|
||||||
|
#define PACKAGE "curl"
|
||||||
|
|
||||||
|
#define CURL_CA_BUNDLE "/dev/env/CURL_CA_BUNDLE"
|
||||||
|
|
||||||
|
#if (DJGPP_MINOR >= 4)
|
||||||
|
/* #define HAVE_DLOPEN 1 maybe not (DXE3) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1 /* use ioctlsocket() via fsext'ed fcntl() */
|
||||||
|
#define HAVE_O_NONBLOCK 1
|
||||||
|
#else
|
||||||
|
#define HAVE_IOCTLSOCKET 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_ALARM 1
|
||||||
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
#define HAVE_CLOSESOCKET 1
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
#define HAVE_GETHOSTBYADDR 1
|
||||||
|
#define HAVE_GETHOSTNAME 1
|
||||||
|
#define HAVE_GETPASS 1
|
||||||
|
#define HAVE_GETSERVBYNAME 1
|
||||||
|
#define HAVE_GETTIMEOFDAY 1
|
||||||
|
#define HAVE_INET_ADDR 1
|
||||||
|
#define HAVE_INET_NTOA 1
|
||||||
|
#define HAVE_IO_H 1
|
||||||
|
#define HAVE_MALLOC_H 1
|
||||||
|
#define HAVE_MEMORY_H 1
|
||||||
|
#define HAVE_NETDB_H 1
|
||||||
|
#define HAVE_NETINET_IN_H 1
|
||||||
|
#define HAVE_NET_IF_H 1
|
||||||
|
#define HAVE_PERROR 1
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
#define HAVE_SETJMP_H 1
|
||||||
|
#define HAVE_SETVBUF 1
|
||||||
|
#define HAVE_SIGNAL 1
|
||||||
|
#define HAVE_SIGACTION 1
|
||||||
|
#define HAVE_SIGSETJMP 1
|
||||||
|
#define HAVE_SOCKET 1
|
||||||
|
#define HAVE_STRCASECMP 1
|
||||||
|
#define HAVE_STRDUP 1
|
||||||
|
#define HAVE_STRFTIME 1
|
||||||
|
#define HAVE_STRICMP 1
|
||||||
|
#define HAVE_STRSTR 1
|
||||||
|
#define HAVE_SYS_SOCKET_H 1
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
#define HAVE_TERMIOS_H 1
|
||||||
|
#define HAVE_TIME_H 1
|
||||||
|
#define HAVE_UNAME 1
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
#define HAVE_VPRINTF 1
|
||||||
|
|
||||||
|
#define RETSIGTYPE void
|
||||||
|
#define SIZEOF_LONG_DOUBLE 16
|
||||||
|
#define SIZEOF_LONG_LONG 8
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
#define TIME_WITH_SYS_TIME 1
|
||||||
|
|
||||||
|
#define BSD
|
||||||
|
#define USE_ZLIB
|
||||||
|
|
||||||
|
/* #define MALLOCDEBUG */
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL_ENGINE_H /* on cmd-line */
|
||||||
|
#define HAVE_OPENSSL_X509_H 1
|
||||||
|
#define HAVE_OPENSSL_SSL_H 1
|
||||||
|
#define HAVE_OPENSSL_RSA_H 1
|
||||||
|
#define HAVE_OPENSSL_PEM_H 1
|
||||||
|
#define HAVE_OPENSSL_ERR_H 1
|
||||||
|
#define HAVE_OPENSSL_CRYPTO_H 1
|
||||||
|
#define HAVE_LIBSSL 1
|
||||||
|
#define HAVE_LIBCRYPTO 1
|
||||||
|
#define OPENSSL_NO_KRB5 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define in_addr_t u_long
|
||||||
|
#define socklen_t int
|
||||||
|
#define ssize_t int
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <tcp.h> /* Watt-32 API */
|
||||||
|
|
||||||
|
#undef word
|
||||||
|
|
||||||
|
#endif /* _CURL_CONFIG_DJGPP_H */
|
||||||
|
|
@@ -77,12 +77,11 @@
|
|||||||
#include "if2ip.h"
|
#include "if2ip.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static
|
int Curl_ourerrno(void)
|
||||||
int ourerrno(void)
|
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return (int)GetLastError();
|
return (int)GetLastError();
|
||||||
@@ -198,10 +197,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
|
|
||||||
#ifdef HAVE_INET_NTOA
|
#ifdef HAVE_INET_NTOA
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
|
||||||
#define INADDR_NONE (in_addr_t) ~0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -214,7 +209,11 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
char myhost[256] = "";
|
char myhost[256] = "";
|
||||||
in_addr_t in;
|
in_addr_t in;
|
||||||
|
|
||||||
if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
/* First check if the given name is an IP address */
|
||||||
|
in=inet_addr(data->set.device);
|
||||||
|
|
||||||
|
if((in == CURL_INADDR_NONE) &&
|
||||||
|
Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
||||||
/*
|
/*
|
||||||
* We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
|
* We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
|
||||||
*/
|
*/
|
||||||
@@ -247,7 +246,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
infof(data, "We bind local end to %s\n", myhost);
|
infof(data, "We bind local end to %s\n", myhost);
|
||||||
|
|
||||||
in=inet_addr(myhost);
|
in=inet_addr(myhost);
|
||||||
if (INADDR_NONE != in) {
|
if (CURL_INADDR_NONE != in) {
|
||||||
|
|
||||||
if ( h ) {
|
if ( h ) {
|
||||||
Curl_addrinfo *addr = h->addr;
|
Curl_addrinfo *addr = h->addr;
|
||||||
@@ -350,7 +349,7 @@ int socketerror(int sockfd)
|
|||||||
|
|
||||||
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
|
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
|
||||||
(void *)&err, &errSize))
|
(void *)&err, &errSize))
|
||||||
err = ourerrno();
|
err = Curl_ourerrno();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -414,7 +413,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
else if(1 != rc) {
|
else if(1 != rc) {
|
||||||
int error = ourerrno();
|
int error = Curl_ourerrno();
|
||||||
failf(data, "Failed connect to %s:%d, errno: %d",
|
failf(data, "Failed connect to %s:%d, errno: %d",
|
||||||
conn->hostname, conn->port, error);
|
conn->hostname, conn->port, error);
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
@@ -526,7 +525,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
|
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
int error=ourerrno();
|
int error=Curl_ourerrno();
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case EINPROGRESS:
|
case EINPROGRESS:
|
||||||
@@ -645,7 +644,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
sizeof(serv_addr));
|
sizeof(serv_addr));
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
int error=ourerrno();
|
int error=Curl_ourerrno();
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case EINPROGRESS:
|
case EINPROGRESS:
|
||||||
|
@@ -37,4 +37,6 @@ CURLcode Curl_connecthost(struct connectdata *conn,
|
|||||||
Curl_ipconnect **addr, /* the one we used */
|
Curl_ipconnect **addr, /* the one we used */
|
||||||
bool *connected /* truly connected? */
|
bool *connected /* truly connected? */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int Curl_ourerrno(void);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -25,13 +25,26 @@
|
|||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <curl/types.h>
|
#include <curl/types.h>
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
|
||||||
#define DSIZ 4096 /* buffer size for decompressed data */
|
#define DSIZ 0x10000 /* buffer size for decompressed data */
|
||||||
|
|
||||||
|
#define GZIP_MAGIC_0 0x1f
|
||||||
|
#define GZIP_MAGIC_1 0x8b
|
||||||
|
|
||||||
|
/* gzip flag byte */
|
||||||
|
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||||
|
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
|
||||||
|
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||||
|
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||||
|
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||||
|
#define RESERVED 0xE0 /* bits 5..7: reserved */
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
process_zlib_error(struct SessionHandle *data, z_stream *z)
|
process_zlib_error(struct SessionHandle *data, z_stream *z)
|
||||||
@@ -74,7 +87,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
|
|||||||
k->zlib_init = 1;
|
k->zlib_init = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the compressed input when this fucntion is called */
|
/* Set the compressed input when this function is called */
|
||||||
z->next_in = (Bytef *)k->str;
|
z->next_in = (Bytef *)k->str;
|
||||||
z->avail_in = nread;
|
z->avail_in = nread;
|
||||||
|
|
||||||
@@ -87,10 +100,11 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
|
|||||||
|
|
||||||
status = inflate(z, Z_SYNC_FLUSH);
|
status = inflate(z, Z_SYNC_FLUSH);
|
||||||
if (status == Z_OK || status == Z_STREAM_END) {
|
if (status == Z_OK || status == Z_STREAM_END) {
|
||||||
|
if (DSIZ - z->avail_out) {
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
|
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
|
||||||
DSIZ - z->avail_out);
|
DSIZ - z->avail_out);
|
||||||
/* if !CURLE_OK, clean up, return */
|
/* if !CURLE_OK, clean up, return */
|
||||||
if (result) {
|
if (result)
|
||||||
return exit_zlib(z, &k->zlib_init, result);
|
return exit_zlib(z, &k->zlib_init, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,4 +125,230 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip over the gzip header */
|
||||||
|
static enum {
|
||||||
|
GZIP_OK,
|
||||||
|
GZIP_BAD,
|
||||||
|
GZIP_UNDERFLOW
|
||||||
|
} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
|
||||||
|
{
|
||||||
|
int method, flags;
|
||||||
|
const ssize_t totallen = len;
|
||||||
|
|
||||||
|
/* The shortest header is 10 bytes */
|
||||||
|
if (len < 10)
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
if ((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
|
||||||
|
return GZIP_BAD;
|
||||||
|
|
||||||
|
method = data[2];
|
||||||
|
flags = data[3];
|
||||||
|
|
||||||
|
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
|
||||||
|
/* Can't handle this compression method or unknown flag */
|
||||||
|
return GZIP_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip over time, xflags, OS code and all previous bytes */
|
||||||
|
len -= 10;
|
||||||
|
data += 10;
|
||||||
|
|
||||||
|
if (flags & EXTRA_FIELD) {
|
||||||
|
ssize_t extra_len;
|
||||||
|
|
||||||
|
if (len < 2)
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
extra_len = (data[1] << 8) | data[0];
|
||||||
|
|
||||||
|
if (len < (extra_len+2))
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
len -= (extra_len + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & ORIG_NAME) {
|
||||||
|
/* Skip over NUL-terminated file name */
|
||||||
|
while (len && *data) {
|
||||||
|
--len;
|
||||||
|
++data;
|
||||||
|
}
|
||||||
|
if (!len || *data)
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
/* Skip over the NUL */
|
||||||
|
--len;
|
||||||
|
++data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & COMMENT) {
|
||||||
|
/* Skip over NUL-terminated comment */
|
||||||
|
while (len && *data) {
|
||||||
|
--len;
|
||||||
|
++data;
|
||||||
|
}
|
||||||
|
if (!len || *data)
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
/* Skip over the NUL */
|
||||||
|
--len;
|
||||||
|
++data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & HEAD_CRC) {
|
||||||
|
if (len < 2)
|
||||||
|
return GZIP_UNDERFLOW;
|
||||||
|
|
||||||
|
len -= 2;
|
||||||
|
data += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*headerlen = totallen - len;
|
||||||
|
return GZIP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode
|
||||||
|
Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||||
|
struct Curl_transfer_keeper *k,
|
||||||
|
ssize_t nread)
|
||||||
|
{
|
||||||
|
int status; /* zlib status */
|
||||||
|
int result; /* Curl_client_write status */
|
||||||
|
char decomp[DSIZ]; /* Put the decompressed data here. */
|
||||||
|
z_stream *z = &k->z; /* zlib state structure */
|
||||||
|
|
||||||
|
/* Initialize zlib? */
|
||||||
|
if (!k->zlib_init) {
|
||||||
|
z->zalloc = (alloc_func)Z_NULL;
|
||||||
|
z->zfree = (free_func)Z_NULL;
|
||||||
|
z->opaque = 0; /* of dubious use 08/27/02 jhrg */
|
||||||
|
if (inflateInit2(z, -MAX_WBITS) != Z_OK)
|
||||||
|
return process_zlib_error(data, z);
|
||||||
|
k->zlib_init = 1; /* Initial call state */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This next mess is to get around the potential case where there isn't
|
||||||
|
enough data passed in to skip over the gzip header. If that happens,
|
||||||
|
we malloc a block and copy what we have then wait for the next call. If
|
||||||
|
there still isn't enough (this is definitely a worst-case scenario), we
|
||||||
|
make the block bigger, copy the next part in and keep waiting. */
|
||||||
|
|
||||||
|
/* Skip over gzip header? */
|
||||||
|
if (k->zlib_init == 1) {
|
||||||
|
/* Initial call state */
|
||||||
|
ssize_t hlen;
|
||||||
|
|
||||||
|
switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
|
||||||
|
case GZIP_OK:
|
||||||
|
z->next_in = (Bytef *)k->str + hlen;
|
||||||
|
z->avail_in = nread - hlen;
|
||||||
|
k->zlib_init = 3; /* Inflating stream state */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GZIP_UNDERFLOW:
|
||||||
|
/* We need more data so we can find the end of the gzip header.
|
||||||
|
It's possible that the memory block we malloc here will never be
|
||||||
|
freed if the transfer abruptly aborts after this point. Since it's
|
||||||
|
unlikely that circumstances will be right for this code path to be
|
||||||
|
followed in the first place, and it's even more unlikely for a transfer
|
||||||
|
to fail immediately afterwards, it should seldom be a problem. */
|
||||||
|
z->avail_in = nread;
|
||||||
|
z->next_in = malloc(z->avail_in);
|
||||||
|
if (z->next_in == NULL) {
|
||||||
|
return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
memcpy(z->next_in, k->str, z->avail_in);
|
||||||
|
k->zlib_init = 2; /* Need more gzip header data state */
|
||||||
|
/* We don't have any data to inflate yet */
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case GZIP_BAD:
|
||||||
|
default:
|
||||||
|
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (k->zlib_init == 2) {
|
||||||
|
/* Need more gzip header data state */
|
||||||
|
ssize_t hlen;
|
||||||
|
unsigned char *oldblock = z->next_in;
|
||||||
|
|
||||||
|
z->avail_in += nread;
|
||||||
|
z->next_in = realloc(z->next_in, z->avail_in);
|
||||||
|
if (z->next_in == NULL) {
|
||||||
|
free(oldblock);
|
||||||
|
return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
/* Append the new block of data to the previous one */
|
||||||
|
memcpy(z->next_in + z->avail_in - nread, k->str, nread);
|
||||||
|
|
||||||
|
switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
|
||||||
|
case GZIP_OK:
|
||||||
|
/* This is the zlib stream data */
|
||||||
|
free(z->next_in);
|
||||||
|
/* Don't point into the malloced block since we just freed it */
|
||||||
|
z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
|
||||||
|
z->avail_in = z->avail_in - hlen;
|
||||||
|
k->zlib_init = 3; /* Inflating stream state */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GZIP_UNDERFLOW:
|
||||||
|
/* We still don't have any data to inflate! */
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case GZIP_BAD:
|
||||||
|
default:
|
||||||
|
free(z->next_in);
|
||||||
|
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Inflating stream state */
|
||||||
|
z->next_in = (Bytef *)k->str;
|
||||||
|
z->avail_in = nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z->avail_in == 0) {
|
||||||
|
/* We don't have any data to inflate; wait until next time */
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* because the buffer size is fixed, iteratively decompress
|
||||||
|
and transfer to the client via client_write. */
|
||||||
|
for (;;) {
|
||||||
|
/* (re)set buffer for decompressed output for every iteration */
|
||||||
|
z->next_out = (Bytef *)&decomp[0];
|
||||||
|
z->avail_out = DSIZ;
|
||||||
|
|
||||||
|
status = inflate(z, Z_SYNC_FLUSH);
|
||||||
|
if (status == Z_OK || status == Z_STREAM_END) {
|
||||||
|
if(DSIZ - z->avail_out) {
|
||||||
|
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
|
||||||
|
DSIZ - z->avail_out);
|
||||||
|
/* if !CURLE_OK, clean up, return */
|
||||||
|
if (result)
|
||||||
|
return exit_zlib(z, &k->zlib_init, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done?; clean up, return */
|
||||||
|
/* We should really check the gzip CRC here */
|
||||||
|
if (status == Z_STREAM_END) {
|
||||||
|
if (inflateEnd(z) == Z_OK)
|
||||||
|
return exit_zlib(z, &k->zlib_init, result);
|
||||||
|
else
|
||||||
|
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done with these bytes, exit */
|
||||||
|
if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else { /* Error; exit loop, handle below */
|
||||||
|
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* HAVE_LIBZ */
|
#endif /* HAVE_LIBZ */
|
||||||
|
@@ -20,7 +20,22 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comma-separated list all supported Content-Encodings ('identity' is implied)
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_LIBZ
|
||||||
|
#define ALL_CONTENT_ENCODINGS "deflate, gzip"
|
||||||
|
#else
|
||||||
|
#define ALL_CONTENT_ENCODINGS "identity"
|
||||||
|
#endif
|
||||||
|
|
||||||
CURLcode Curl_unencode_deflate_write(struct SessionHandle *data,
|
CURLcode Curl_unencode_deflate_write(struct SessionHandle *data,
|
||||||
struct Curl_transfer_keeper *k,
|
struct Curl_transfer_keeper *k,
|
||||||
ssize_t nread);
|
ssize_t nread);
|
||||||
|
|
||||||
|
CURLcode
|
||||||
|
Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||||
|
struct Curl_transfer_keeper *k,
|
||||||
|
ssize_t nread);
|
||||||
|
138
lib/cookie.c
138
lib/cookie.c
@@ -92,7 +92,7 @@ Example set of cookies:
|
|||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -111,6 +111,17 @@ free_cookiemess(struct Cookie *co)
|
|||||||
free(co);
|
free(co);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tailmatch(const char *little, const char *bigone)
|
||||||
|
{
|
||||||
|
unsigned int littlelen = strlen(little);
|
||||||
|
unsigned int biglen = strlen(bigone);
|
||||||
|
|
||||||
|
if(littlelen > biglen)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return strequal(little, bigone+biglen-littlelen);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Curl_cookie_add()
|
* Curl_cookie_add()
|
||||||
@@ -123,7 +134,10 @@ struct Cookie *
|
|||||||
Curl_cookie_add(struct CookieInfo *c,
|
Curl_cookie_add(struct CookieInfo *c,
|
||||||
bool httpheader, /* TRUE if HTTP header-style line */
|
bool httpheader, /* TRUE if HTTP header-style line */
|
||||||
char *lineptr, /* first character of the line */
|
char *lineptr, /* first character of the line */
|
||||||
char *domain) /* default domain */
|
char *domain, /* default domain */
|
||||||
|
char *path) /* full path used when this cookie is set,
|
||||||
|
used to get default path for the cookie
|
||||||
|
unless set */
|
||||||
{
|
{
|
||||||
struct Cookie *clist;
|
struct Cookie *clist;
|
||||||
char what[MAX_COOKIE_LINE];
|
char what[MAX_COOKIE_LINE];
|
||||||
@@ -134,6 +148,7 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
struct Cookie *lastc=NULL;
|
struct Cookie *lastc=NULL;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
bool replace_old = FALSE;
|
bool replace_old = FALSE;
|
||||||
|
bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
|
||||||
|
|
||||||
/* First, alloc and init a new struct for it */
|
/* First, alloc and init a new struct for it */
|
||||||
co = (struct Cookie *)malloc(sizeof(struct Cookie));
|
co = (struct Cookie *)malloc(sizeof(struct Cookie));
|
||||||
@@ -186,8 +201,63 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
co->path=strdup(whatptr);
|
co->path=strdup(whatptr);
|
||||||
}
|
}
|
||||||
else if(strequal("domain", name)) {
|
else if(strequal("domain", name)) {
|
||||||
co->domain=strdup(whatptr);
|
/* note that this name may or may not have a preceeding dot, but
|
||||||
co->field1= (whatptr[0]=='.')?2:1;
|
we don't care about that, we treat the names the same anyway */
|
||||||
|
|
||||||
|
char *ptr=whatptr;
|
||||||
|
int dotcount=1;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
static const char *seventhree[]= {
|
||||||
|
"com", "edu", "net", "org", "gov", "mil", "int"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Count the dots, we need to make sure that there are THREE dots
|
||||||
|
in the normal domains, or TWO in the seventhree-domains. */
|
||||||
|
|
||||||
|
if('.' == whatptr[0])
|
||||||
|
/* don't count the initial dot, assume it */
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ptr = strchr(ptr, '.');
|
||||||
|
if(ptr) {
|
||||||
|
ptr++;
|
||||||
|
dotcount++;
|
||||||
|
}
|
||||||
|
} while(ptr);
|
||||||
|
|
||||||
|
for(i=0;
|
||||||
|
i<sizeof(seventhree)/sizeof(seventhree[0]); i++) {
|
||||||
|
if(tailmatch(seventhree[i], whatptr)) {
|
||||||
|
dotcount++; /* we allow one dot less for these */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dotcount < 3) {
|
||||||
|
/* Received and skipped a cookie with a domain using too few
|
||||||
|
dots. */
|
||||||
|
badcookie=TRUE; /* mark this as a bad cookie */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Now, we make sure that our host is within the given domain,
|
||||||
|
or the given domain is not valid and thus cannot be set. */
|
||||||
|
|
||||||
|
if(!domain || tailmatch(whatptr, domain)) {
|
||||||
|
char *ptr=whatptr;
|
||||||
|
if(ptr[0] == '.')
|
||||||
|
ptr++;
|
||||||
|
co->domain=strdup(ptr); /* dont prefix with dots internally */
|
||||||
|
co->tailmatch=TRUE; /* we always do that if the domain name was
|
||||||
|
given */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we did not get a tailmatch and then the attempted set domain
|
||||||
|
is not a domain to which the current host belongs. Mark as
|
||||||
|
bad. */
|
||||||
|
badcookie=TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(strequal("version", name)) {
|
else if(strequal("version", name)) {
|
||||||
co->version=strdup(whatptr);
|
co->version=strdup(whatptr);
|
||||||
@@ -249,8 +319,11 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
semiptr=strchr(ptr, '\0');
|
semiptr=strchr(ptr, '\0');
|
||||||
} while(semiptr);
|
} while(semiptr);
|
||||||
|
|
||||||
if(NULL == co->name) {
|
if(badcookie || (NULL == co->name)) {
|
||||||
/* we didn't get a cookie name, this is an illegal line, bail out */
|
/* we didn't get a cookie name or a bad one,
|
||||||
|
this is an illegal line, bail out */
|
||||||
|
if(co->expirestr)
|
||||||
|
free(co->expirestr);
|
||||||
if(co->domain)
|
if(co->domain)
|
||||||
free(co->domain);
|
free(co->domain);
|
||||||
if(co->path)
|
if(co->path)
|
||||||
@@ -264,8 +337,20 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(NULL == co->domain)
|
if(NULL == co->domain)
|
||||||
/* no domain given in the header line, set the default now */
|
/* no domain was given in the header line, set the default now */
|
||||||
co->domain=domain?strdup(domain):NULL;
|
co->domain=domain?strdup(domain):NULL;
|
||||||
|
if((NULL == co->path) && path) {
|
||||||
|
/* no path was given in the header line, set the default now */
|
||||||
|
char *endslash = strrchr(path, '/');
|
||||||
|
if(endslash) {
|
||||||
|
int pathlen = endslash-path+1; /* include the ending slash */
|
||||||
|
co->path=malloc(pathlen+1); /* one extra for the zero byte */
|
||||||
|
if(co->path) {
|
||||||
|
memcpy(co->path, path, pathlen);
|
||||||
|
co->path[pathlen]=0; /* zero terminate */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* This line is NOT a HTTP header style line, we do offer support for
|
/* This line is NOT a HTTP header style line, we do offer support for
|
||||||
@@ -297,9 +382,12 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
|
|
||||||
/* Now loop through the fields and init the struct we already have
|
/* Now loop through the fields and init the struct we already have
|
||||||
allocated */
|
allocated */
|
||||||
for(ptr=firstptr, fields=0; ptr; ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
|
for(ptr=firstptr, fields=0; ptr;
|
||||||
|
ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
|
||||||
switch(fields) {
|
switch(fields) {
|
||||||
case 0:
|
case 0:
|
||||||
|
if(ptr[0]=='.') /* skip preceeding dots */
|
||||||
|
ptr++;
|
||||||
co->domain = strdup(ptr);
|
co->domain = strdup(ptr);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@@ -312,10 +400,8 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
|
|
||||||
As far as I can see, it is set to true when the cookie says
|
As far as I can see, it is set to true when the cookie says
|
||||||
.domain.com and to false when the domain is complete www.domain.com
|
.domain.com and to false when the domain is complete www.domain.com
|
||||||
|
|
||||||
We don't currently take advantage of this knowledge.
|
|
||||||
*/
|
*/
|
||||||
co->field1=strequal(ptr, "TRUE")+1; /* store information */
|
co->tailmatch=strequal(ptr, "TRUE"); /* store information */
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* It turns out, that sometimes the file format allows the path
|
/* It turns out, that sometimes the file format allows the path
|
||||||
@@ -374,13 +460,8 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
/* the names are identical */
|
/* the names are identical */
|
||||||
|
|
||||||
if(clist->domain && co->domain) {
|
if(clist->domain && co->domain) {
|
||||||
if(strequal(clist->domain, co->domain) ||
|
if(strequal(clist->domain, co->domain))
|
||||||
(clist->domain[0]=='.' &&
|
/* The domains are identical */
|
||||||
strequal(&(clist->domain[1]), co->domain)) ||
|
|
||||||
(co->domain[0]=='.' &&
|
|
||||||
strequal(clist->domain, &(co->domain[1]))) )
|
|
||||||
/* The domains are identical, or at least identical if you skip the
|
|
||||||
preceeding dot */
|
|
||||||
replace_old=TRUE;
|
replace_old=TRUE;
|
||||||
}
|
}
|
||||||
else if(!clist->domain && !co->domain)
|
else if(!clist->domain && !co->domain)
|
||||||
@@ -470,7 +551,6 @@ Curl_cookie_add(struct CookieInfo *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->numcookies++; /* one more cookie in the jar */
|
c->numcookies++; /* one more cookie in the jar */
|
||||||
|
|
||||||
return co;
|
return co;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +612,7 @@ struct CookieInfo *Curl_cookie_init(char *file,
|
|||||||
while(*lineptr && isspace((int)*lineptr))
|
while(*lineptr && isspace((int)*lineptr))
|
||||||
lineptr++;
|
lineptr++;
|
||||||
|
|
||||||
Curl_cookie_add(c, headerline, lineptr, NULL);
|
Curl_cookie_add(c, headerline, lineptr, NULL, NULL);
|
||||||
}
|
}
|
||||||
if(fromfile)
|
if(fromfile)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -561,9 +641,6 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
struct Cookie *newco;
|
struct Cookie *newco;
|
||||||
struct Cookie *co;
|
struct Cookie *co;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
int hostlen=strlen(host);
|
|
||||||
int domlen;
|
|
||||||
|
|
||||||
struct Cookie *mainco=NULL;
|
struct Cookie *mainco=NULL;
|
||||||
|
|
||||||
if(!c || !c->cookies)
|
if(!c || !c->cookies)
|
||||||
@@ -579,10 +656,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
(co->secure?secure:TRUE) ) {
|
(co->secure?secure:TRUE) ) {
|
||||||
|
|
||||||
/* now check if the domain is correct */
|
/* now check if the domain is correct */
|
||||||
domlen=co->domain?strlen(co->domain):0;
|
|
||||||
if(!co->domain ||
|
if(!co->domain ||
|
||||||
((domlen<=hostlen) &&
|
(co->tailmatch && tailmatch(co->domain, host)) ||
|
||||||
strequal(host+(hostlen-domlen), co->domain)) ) {
|
(!co->tailmatch && strequal(host, co->domain)) ) {
|
||||||
/* the right part of the host matches the domain stuff in the
|
/* the right part of the host matches the domain stuff in the
|
||||||
cookie data */
|
cookie data */
|
||||||
|
|
||||||
@@ -716,15 +792,19 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
|||||||
|
|
||||||
while(co) {
|
while(co) {
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
"%s\t" /* domain */
|
"%s%s\t" /* domain */
|
||||||
"%s\t" /* field1 */
|
"%s\t" /* tailmatch */
|
||||||
"%s\t" /* path */
|
"%s\t" /* path */
|
||||||
"%s\t" /* secure */
|
"%s\t" /* secure */
|
||||||
"%u\t" /* expires */
|
"%u\t" /* expires */
|
||||||
"%s\t" /* name */
|
"%s\t" /* name */
|
||||||
"%s\n", /* value */
|
"%s\n", /* value */
|
||||||
|
|
||||||
|
/* Make sure all domains are prefixed with a dot if they allow
|
||||||
|
tailmatching. This is Mozilla-style. */
|
||||||
|
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
|
||||||
co->domain?co->domain:"unknown",
|
co->domain?co->domain:"unknown",
|
||||||
co->field1==2?"TRUE":"FALSE",
|
co->tailmatch?"TRUE":"FALSE",
|
||||||
co->path?co->path:"/",
|
co->path?co->path:"/",
|
||||||
co->secure?"TRUE":"FALSE",
|
co->secure?"TRUE":"FALSE",
|
||||||
(unsigned int)co->expires,
|
(unsigned int)co->expires,
|
||||||
|
@@ -40,8 +40,7 @@ struct Cookie {
|
|||||||
char *domain; /* domain = <this> */
|
char *domain; /* domain = <this> */
|
||||||
long expires; /* expires = <this> */
|
long expires; /* expires = <this> */
|
||||||
char *expirestr; /* the plain text version */
|
char *expirestr; /* the plain text version */
|
||||||
|
bool tailmatch; /* weather we do tail-matchning of the domain name */
|
||||||
char field1; /* read from a cookie file, 1 => FALSE, 2=> TRUE */
|
|
||||||
|
|
||||||
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
||||||
char *version; /* Version = <value> */
|
char *version; /* Version = <value> */
|
||||||
@@ -70,11 +69,11 @@ struct CookieInfo {
|
|||||||
#define MAX_NAME_TXT "255"
|
#define MAX_NAME_TXT "255"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a cookie to the internal list of cookies. The domain argument is only
|
* Add a cookie to the internal list of cookies. The domain and path arguments
|
||||||
* used if the header boolean is TRUE.
|
* are only used if the header boolean is TRUE.
|
||||||
*/
|
*/
|
||||||
struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line,
|
struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line,
|
||||||
char *domain);
|
char *domain, char *path);
|
||||||
|
|
||||||
struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *, bool);
|
struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *, bool);
|
||||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
|
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
|
||||||
|
@@ -243,6 +243,10 @@ SOURCE=.\url.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\share.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\version.c
|
SOURCE=.\version.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
@@ -385,6 +389,22 @@ SOURCE=.\url.h
|
|||||||
|
|
||||||
SOURCE=.\urldata.h
|
SOURCE=.\urldata.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\http_digest.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\md5.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\http_digest.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\md5.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Resource Files"
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
@@ -44,7 +44,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
10
lib/easy.c
10
lib/easy.c
@@ -46,7 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -200,6 +199,7 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
|||||||
long param_long = 0;
|
long param_long = 0;
|
||||||
void *param_obj = NULL;
|
void *param_obj = NULL;
|
||||||
struct SessionHandle *data = curl;
|
struct SessionHandle *data = curl;
|
||||||
|
CURLcode ret=CURLE_FAILED_INIT;
|
||||||
|
|
||||||
va_start(arg, tag);
|
va_start(arg, tag);
|
||||||
|
|
||||||
@@ -213,20 +213,20 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
|||||||
if(tag < CURLOPTTYPE_OBJECTPOINT) {
|
if(tag < CURLOPTTYPE_OBJECTPOINT) {
|
||||||
/* This is a LONG type */
|
/* This is a LONG type */
|
||||||
param_long = va_arg(arg, long);
|
param_long = va_arg(arg, long);
|
||||||
Curl_setopt(data, tag, param_long);
|
ret = Curl_setopt(data, tag, param_long);
|
||||||
}
|
}
|
||||||
else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
|
else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
|
||||||
/* This is a object pointer type */
|
/* This is a object pointer type */
|
||||||
param_obj = va_arg(arg, void *);
|
param_obj = va_arg(arg, void *);
|
||||||
Curl_setopt(data, tag, param_obj);
|
ret = Curl_setopt(data, tag, param_obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
param_func = va_arg(arg, func_T );
|
param_func = va_arg(arg, func_T );
|
||||||
Curl_setopt(data, tag, param_func);
|
ret = Curl_setopt(data, tag, param_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
return CURLE_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode curl_easy_perform(CURL *curl)
|
CURLcode curl_easy_perform(CURL *curl)
|
||||||
|
23
lib/escape.c
23
lib/escape.c
@@ -33,7 +33,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -79,6 +79,10 @@ char *curl_escape(const char *string, int length)
|
|||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ishex(in) ((in >= 'a' && in <= 'f') || \
|
||||||
|
(in >= 'A' && in <= 'F') || \
|
||||||
|
(in >= '0' && in <= '9'))
|
||||||
|
|
||||||
char *curl_unescape(const char *string, int length)
|
char *curl_unescape(const char *string, int length)
|
||||||
{
|
{
|
||||||
int alloc = (length?length:(int)strlen(string))+1;
|
int alloc = (length?length:(int)strlen(string))+1;
|
||||||
@@ -93,14 +97,20 @@ char *curl_unescape(const char *string, int length)
|
|||||||
|
|
||||||
while(--alloc > 0) {
|
while(--alloc > 0) {
|
||||||
in = *string;
|
in = *string;
|
||||||
if('%' == in) {
|
if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
|
||||||
/* encoded part */
|
/* this is two hexadecimal digits following a '%' */
|
||||||
if(sscanf(string+1, "%02X", &hex)) {
|
char hexstr[3];
|
||||||
|
char *ptr;
|
||||||
|
hexstr[0] = string[1];
|
||||||
|
hexstr[1] = string[2];
|
||||||
|
hexstr[2] = 0;
|
||||||
|
|
||||||
|
hex = strtol(hexstr, &ptr, 16);
|
||||||
|
|
||||||
in = hex;
|
in = hex;
|
||||||
string+=2;
|
string+=2;
|
||||||
alloc-=2;
|
alloc-=2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ns[index++] = in;
|
ns[index++] = in;
|
||||||
string++;
|
string++;
|
||||||
@@ -109,6 +119,9 @@ char *curl_unescape(const char *string, int length)
|
|||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For operating systems/environments that use different malloc/free
|
||||||
|
ssystems for the app and for this library, we provide a free that uses
|
||||||
|
the library's memory system */
|
||||||
void curl_free(void *p)
|
void curl_free(void *p)
|
||||||
{
|
{
|
||||||
free(p);
|
free(p);
|
||||||
|
@@ -48,7 +48,6 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -124,15 +124,12 @@ Content-Disposition: form-data; name="FILECONTENT"
|
|||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Length of the random boundary string. The risk of this being used
|
/* Length of the random boundary string. */
|
||||||
in binary data is very close to zero, 64^32 makes
|
#define BOUNDARY_LENGTH 40
|
||||||
6277101735386680763835789423207666416102355444464034512896
|
|
||||||
combinations... */
|
|
||||||
#define BOUNDARY_LENGTH 32
|
|
||||||
|
|
||||||
/* What kind of Content-Type to use on un-specified files with unrecognized
|
/* What kind of Content-Type to use on un-specified files with unrecognized
|
||||||
extensions. */
|
extensions. */
|
||||||
@@ -520,7 +517,7 @@ static const char * ContentTypeForFilename (const char *filename,
|
|||||||
{".jpg", "image/jpeg"},
|
{".jpg", "image/jpeg"},
|
||||||
{".jpeg", "image/jpeg"},
|
{".jpeg", "image/jpeg"},
|
||||||
{".txt", "text/plain"},
|
{".txt", "text/plain"},
|
||||||
{".html", "text/plain"}
|
{".html", "text/html"}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(prevtype)
|
if(prevtype)
|
||||||
@@ -1049,22 +1046,23 @@ char *Curl_FormBoundary(void)
|
|||||||
the same form won't be identical */
|
the same form won't be identical */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
static char table62[]=
|
static char table16[]="abcdef0123456789";
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
|
|
||||||
retstring = (char *)malloc(BOUNDARY_LENGTH);
|
retstring = (char *)malloc(BOUNDARY_LENGTH+1);
|
||||||
|
|
||||||
if(!retstring)
|
if(!retstring)
|
||||||
return NULL; /* failed */
|
return NULL; /* failed */
|
||||||
|
|
||||||
srand(time(NULL)+randomizer++); /* seed */
|
srand(time(NULL)+randomizer++); /* seed */
|
||||||
|
|
||||||
strcpy(retstring, "curl"); /* bonus commercials 8*) */
|
strcpy(retstring, "----------------------------");
|
||||||
|
|
||||||
for(i=4; i<(BOUNDARY_LENGTH-1); i++) {
|
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
|
||||||
retstring[i] = table62[rand()%62];
|
retstring[i] = table16[rand()%16];
|
||||||
}
|
|
||||||
retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */
|
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
|
||||||
|
combinations */
|
||||||
|
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
|
||||||
|
|
||||||
return retstring;
|
return retstring;
|
||||||
}
|
}
|
||||||
|
195
lib/ftp.c
195
lib/ftp.c
@@ -94,7 +94,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -158,6 +158,7 @@ static CURLcode AllowServerConnect(struct SessionHandle *data,
|
|||||||
infof(data, "Connection accepted from server\n");
|
infof(data, "Connection accepted from server\n");
|
||||||
|
|
||||||
conn->secondarysocket = s;
|
conn->secondarysocket = s;
|
||||||
|
Curl_nonblock(s, TRUE); /* enable non-blocking */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -237,7 +238,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
|
|
||||||
if(!ftp->cache) {
|
if(!ftp->cache) {
|
||||||
readfd = rkeepfd; /* set every lap */
|
readfd = rkeepfd; /* set every lap */
|
||||||
interval.tv_sec = timeout;
|
interval.tv_sec = 1; /* use 1 second timeout intervals */
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
|
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
|
||||||
@@ -246,9 +247,10 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
failf(data, "Transfer aborted due to select() error: %d", errno);
|
failf(data, "Transfer aborted due to select() error: %d", errno);
|
||||||
break;
|
break;
|
||||||
case 0: /* timeout */
|
case 0: /* timeout */
|
||||||
result = CURLE_OPERATION_TIMEDOUT;
|
if(Curl_pgrsUpdate(conn))
|
||||||
failf(data, "Transfer aborted due to timeout");
|
return CURLE_ABORTED_BY_CALLBACK;
|
||||||
break;
|
continue; /* just continue in our loop for the timeout duration */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -407,9 +409,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
|||||||
/* get some initial data into the ftp struct */
|
/* get some initial data into the ftp struct */
|
||||||
ftp->bytecountp = &conn->bytecount;
|
ftp->bytecountp = &conn->bytecount;
|
||||||
|
|
||||||
/* no need to duplicate them, the data struct won't change */
|
/* no need to duplicate them, this connectdata struct won't change */
|
||||||
ftp->user = data->state.user;
|
ftp->user = conn->user;
|
||||||
ftp->passwd = data->state.passwd;
|
ftp->passwd = conn->passwd;
|
||||||
ftp->response_time = 3600; /* set default response time-out */
|
ftp->response_time = 3600; /* set default response time-out */
|
||||||
|
|
||||||
if (data->set.tunnel_thru_httpproxy) {
|
if (data->set.tunnel_thru_httpproxy) {
|
||||||
@@ -510,7 +512,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
|||||||
/* we may need to issue a KAUTH here to have access to the files
|
/* we may need to issue a KAUTH here to have access to the files
|
||||||
* do it if user supplied a password
|
* do it if user supplied a password
|
||||||
*/
|
*/
|
||||||
if(data->state.passwd && *data->state.passwd) {
|
if(conn->passwd && *conn->passwd) {
|
||||||
result = Curl_krb_kauth(conn);
|
result = Curl_krb_kauth(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -726,7 +728,10 @@ CURLcode ftp_cwd(struct connectdata *conn, char *path)
|
|||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (ftpcode != 250) {
|
/* According to RFC959, CWD is supposed to return 250 on success, but
|
||||||
|
there seem to be non-compliant FTP servers out there that return 200,
|
||||||
|
so we accept any '2xy' code here. */
|
||||||
|
if (ftpcode/100 != 2) {
|
||||||
failf(conn->data, "Couldn't cd to %s", path);
|
failf(conn->data, "Couldn't cd to %s", path);
|
||||||
return CURLE_FTP_ACCESS_DENIED;
|
return CURLE_FTP_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
@@ -933,6 +938,7 @@ ftp_pasv_verbose(struct connectdata *conn,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
(void)hostent_buf; /* avoid compiler warning */
|
||||||
answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);
|
answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
@@ -961,7 +967,7 @@ ftp_pasv_verbose(struct connectdata *conn,
|
|||||||
#else
|
#else
|
||||||
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
#endif
|
#endif
|
||||||
port = 0; /* unused, prevent warning */
|
(void)port; /* prevent compiler warning */
|
||||||
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
||||||
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {
|
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {
|
||||||
snprintf(nbuf, sizeof(nbuf), "?");
|
snprintf(nbuf, sizeof(nbuf), "?");
|
||||||
@@ -1076,7 +1082,8 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (modep = (char **)mode; modep && *modep; modep++) {
|
for (modep = (char **)(data->set.ftp_use_eprt?&mode[0]:&mode[2]);
|
||||||
|
modep && *modep; modep++) {
|
||||||
int lprtaf, eprtaf;
|
int lprtaf, eprtaf;
|
||||||
int alen=0, plen=0;
|
int alen=0, plen=0;
|
||||||
|
|
||||||
@@ -1177,7 +1184,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (ftpcode != 200) {
|
if (ftpcode != 200) {
|
||||||
failf(data, "Server does not grok %s", *modep);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1186,6 +1192,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
|
|
||||||
if (!*modep) {
|
if (!*modep) {
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
|
failf(data, "PORT command attempts failed");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
/* we set the secondary socket variable to this for now, it
|
/* we set the secondary socket variable to this for now, it
|
||||||
@@ -1206,7 +1213,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
bool sa_filled_in = FALSE;
|
bool sa_filled_in = FALSE;
|
||||||
|
|
||||||
if(data->set.ftpport) {
|
if(data->set.ftpport) {
|
||||||
if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
|
in_addr_t in;
|
||||||
|
|
||||||
|
/* First check if the given name is an IP address */
|
||||||
|
in=inet_addr(data->set.ftpport);
|
||||||
|
|
||||||
|
if((in == CURL_INADDR_NONE) &&
|
||||||
|
Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
|
||||||
h = Curl_resolv(data, myhost, 0);
|
h = Curl_resolv(data, myhost, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1917,10 +1930,16 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if(dirlist && (ftpcode == 450)) {
|
||||||
|
/* simply no matching files */
|
||||||
|
ftp->no_transfer = TRUE; /* don't think we should download anything */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "%s", buf+4);
|
failf(data, "%s", buf+4);
|
||||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* end of transfer */
|
/* end of transfer */
|
||||||
@@ -1963,17 +1982,46 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change directory first! */
|
{
|
||||||
if(ftp->dir && ftp->dir[0]) {
|
int i; /* counter for loop */
|
||||||
if ((result = ftp_cwd(conn, ftp->dir)) != CURLE_OK)
|
for (i=0; ftp->dirs[i]; i++) {
|
||||||
|
/* RFC 1738 says empty components should be respected too */
|
||||||
|
if ((result = ftp_cwd(conn, ftp->dirs[i])) != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Requested time of file? */
|
/* Requested time of file or time-depended transfer? */
|
||||||
if(data->set.get_filetime && ftp->file) {
|
if((data->set.get_filetime || data->set.timecondition) &&
|
||||||
|
ftp->file) {
|
||||||
result = ftp_getfiletime(conn, ftp->file);
|
result = ftp_getfiletime(conn, ftp->file);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
if(data->set.timecondition) {
|
||||||
|
if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
|
||||||
|
switch(data->set.timecondition) {
|
||||||
|
case TIMECOND_IFMODSINCE:
|
||||||
|
default:
|
||||||
|
if(data->info.filetime < data->set.timevalue) {
|
||||||
|
infof(data, "The requested document is not new enough\n");
|
||||||
|
ftp->no_transfer = TRUE; /* mark this to not transfer data */
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TIMECOND_IFUNMODSINCE:
|
||||||
|
if(data->info.filetime > data->set.timevalue) {
|
||||||
|
infof(data, "The requested document is not old enough\n");
|
||||||
|
ftp->no_transfer = TRUE; /* mark this to not transfer data */
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infof(data, "Skipping time comparison\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||||
@@ -2013,10 +2061,10 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
struct tm buffer;
|
struct tm buffer;
|
||||||
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
|
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
|
||||||
#else
|
#else
|
||||||
tm = localtime((unsigned long *)&data->info.filetime);
|
tm = localtime(&data->info.filetime);
|
||||||
#endif
|
#endif
|
||||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||||
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S %Z\r\n",
|
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n",
|
||||||
tm);
|
tm);
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
|
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
|
||||||
if(result)
|
if(result)
|
||||||
@@ -2061,34 +2109,81 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
CURLcode Curl_ftp(struct connectdata *conn)
|
CURLcode Curl_ftp(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode retcode;
|
CURLcode retcode=CURLE_OK;
|
||||||
bool connected;
|
bool connected=0;
|
||||||
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct FTP *ftp;
|
struct FTP *ftp;
|
||||||
int dirlength=0; /* 0 forces strlen() */
|
|
||||||
|
char *slash_pos; /* position of the first '/' char in curpos */
|
||||||
|
char *cur_pos=conn->ppath; /* current position in ppath. point at the begin
|
||||||
|
of next path component */
|
||||||
|
int path_part=0;/* current path component */
|
||||||
|
|
||||||
/* the ftp struct is already inited in ftp_connect() */
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
ftp = conn->proto.ftp;
|
ftp = conn->proto.ftp;
|
||||||
conn->size = -1; /* make sure this is unknown at this point */
|
conn->size = -1; /* make sure this is unknown at this point */
|
||||||
|
|
||||||
/* We split the path into dir and file parts *before* we URLdecode
|
Curl_pgrsSetUploadCounter(data, 0);
|
||||||
it */
|
Curl_pgrsSetDownloadCounter(data, 0);
|
||||||
ftp->file = strrchr(conn->ppath, '/');
|
Curl_pgrsSetUploadSize(data, 0);
|
||||||
if(ftp->file) {
|
Curl_pgrsSetDownloadSize(data, 0);
|
||||||
if(ftp->file != conn->ppath)
|
|
||||||
dirlength=ftp->file-conn->ppath; /* don't count the traling slash */
|
|
||||||
|
|
||||||
ftp->file++; /* point to the first letter in the file name part or
|
/* fixed : initialize ftp->dirs[xxx] to NULL !
|
||||||
remain NULL */
|
is done in Curl_ftp_connect() */
|
||||||
|
|
||||||
|
/* parse the URL path into separate path components */
|
||||||
|
while((slash_pos=strchr(cur_pos, '/'))) {
|
||||||
|
/* 1 or 0 to indicate absolute directory */
|
||||||
|
bool absolute_dir = (cur_pos - conn->ppath > 0) && (path_part == 0);
|
||||||
|
|
||||||
|
/* seek out the next path component */
|
||||||
|
if (slash_pos-cur_pos) {
|
||||||
|
/* we skip empty path components, like "x//y" since the FTP command CWD
|
||||||
|
requires a parameter and a non-existant parameter a) doesn't work on
|
||||||
|
many servers and b) has no effect on the others. */
|
||||||
|
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir,
|
||||||
|
slash_pos - cur_pos + absolute_dir);
|
||||||
|
|
||||||
|
if (!ftp->dirs[path_part]) { /* run out of memory ... */
|
||||||
|
failf(data, "no memory");
|
||||||
|
retcode = CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ftp->file = conn->ppath; /* there's only a file part */
|
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!retcode) {
|
||||||
|
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||||
|
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
||||||
|
/* too deep, we need the last entry to be kept NULL at all
|
||||||
|
times to signal end of list */
|
||||||
|
failf(data, "too deep dir hierarchy");
|
||||||
|
retcode = CURLE_URL_MALFORMAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retcode) {
|
||||||
|
int i;
|
||||||
|
for (i=0;i<path_part;i++) { /* free previous parts */
|
||||||
|
free(ftp->dirs[i]);
|
||||||
|
ftp->dirs[i]=NULL;
|
||||||
|
}
|
||||||
|
return retcode; /* failure */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ftp->file = cur_pos; /* the rest is the file name */
|
||||||
|
|
||||||
if(*ftp->file) {
|
if(*ftp->file) {
|
||||||
ftp->file = curl_unescape(ftp->file, 0);
|
ftp->file = curl_unescape(ftp->file, 0);
|
||||||
if(NULL == ftp->file) {
|
if(NULL == ftp->file) {
|
||||||
|
int i;
|
||||||
|
for (i=0;i<path_part;i++){
|
||||||
|
free(ftp->dirs[i]);
|
||||||
|
ftp->dirs[i]=NULL;
|
||||||
|
}
|
||||||
failf(data, "no memory");
|
failf(data, "no memory");
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -2097,25 +2192,22 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
|||||||
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
||||||
pointer */
|
pointer */
|
||||||
|
|
||||||
ftp->urlpath = conn->ppath;
|
|
||||||
if(dirlength) {
|
|
||||||
ftp->dir = curl_unescape(ftp->urlpath, dirlength);
|
|
||||||
if(NULL == ftp->dir) {
|
|
||||||
if(ftp->file)
|
|
||||||
free(ftp->file);
|
|
||||||
failf(data, "no memory");
|
|
||||||
return CURLE_OUT_OF_MEMORY; /* failure */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ftp->dir = NULL;
|
|
||||||
|
|
||||||
retcode = ftp_perform(conn, &connected);
|
retcode = ftp_perform(conn, &connected);
|
||||||
|
|
||||||
if(CURLE_OK == retcode) {
|
if(CURLE_OK == retcode) {
|
||||||
if(connected)
|
if(connected)
|
||||||
retcode = Curl_ftp_nextconnect(conn);
|
retcode = Curl_ftp_nextconnect(conn);
|
||||||
else
|
|
||||||
|
if(retcode && (conn->secondarysocket >= 0)) {
|
||||||
|
/* Failure detected, close the second socket if it was created already */
|
||||||
|
sclose(conn->secondarysocket);
|
||||||
|
conn->secondarysocket = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ftp->no_transfer)
|
||||||
|
/* no data to transfer */
|
||||||
|
retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||||
|
else if(!connected)
|
||||||
/* since we didn't connect now, we want do_more to get called */
|
/* since we didn't connect now, we want do_more to get called */
|
||||||
conn->bits.do_more = TRUE;
|
conn->bits.do_more = TRUE;
|
||||||
}
|
}
|
||||||
@@ -2182,6 +2274,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
|||||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct FTP *ftp= conn->proto.ftp;
|
struct FTP *ftp= conn->proto.ftp;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* The FTP session may or may not have been allocated/setup at this point! */
|
/* The FTP session may or may not have been allocated/setup at this point! */
|
||||||
if(ftp) {
|
if(ftp) {
|
||||||
@@ -2191,10 +2284,12 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
|||||||
free(ftp->cache);
|
free(ftp->cache);
|
||||||
if(ftp->file)
|
if(ftp->file)
|
||||||
free(ftp->file);
|
free(ftp->file);
|
||||||
if(ftp->dir)
|
for (i=0;ftp->dirs[i];i++){
|
||||||
free(ftp->dir);
|
free(ftp->dirs[i]);
|
||||||
|
ftp->dirs[i]=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ftp->file = ftp->dir = NULL; /* zero */
|
ftp->file = NULL; /* zero */
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
#include <unixlib.h>
|
#include <unixlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -36,8 +36,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make this the last #include */
|
/* Make this the last #include */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -89,7 +89,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
char infp_fclose = 0;
|
char infp_fclose = 0;
|
||||||
FILE *outfp;
|
FILE *outfp;
|
||||||
RETSIGTYPE (*sigint)();
|
RETSIGTYPE (*sigint)();
|
||||||
#ifndef __EMX__
|
#ifdef SIGTSTP
|
||||||
RETSIGTYPE (*sigtstp)();
|
RETSIGTYPE (*sigtstp)();
|
||||||
#endif
|
#endif
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
@@ -117,9 +117,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sigint = signal(SIGINT, SIG_IGN);
|
sigint = signal(SIGINT, SIG_IGN);
|
||||||
/* 20000318 mgs
|
#ifdef SIGTSTP
|
||||||
* this is needed by the emx system, SIGTSTP is not a supported signal */
|
|
||||||
#ifndef __EMX__
|
|
||||||
sigtstp = signal(SIGTSTP, SIG_IGN);
|
sigtstp = signal(SIGTSTP, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -181,7 +179,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
signal(SIGINT, sigint);
|
signal(SIGINT, sigint);
|
||||||
#ifndef __EMX__
|
#ifdef SIGTSTP
|
||||||
signal(SIGTSTP, sigtstp);
|
signal(SIGTSTP, sigtstp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "llist.h"
|
#include "llist.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
36
lib/hostip.c
36
lib/hostip.c
@@ -74,7 +74,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
|
|||||||
hostcache_timestamp_remove);
|
hostcache_timestamp_remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
|
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||||
/* Called from Curl_done() to check that there's no DNS cache entry with
|
/* Called from Curl_done() to check that there's no DNS cache entry with
|
||||||
a non-zero counter left. */
|
a non-zero counter left. */
|
||||||
void Curl_scan_cache_used(void *user, void *ptr)
|
void Curl_scan_cache_used(void *user, void *ptr)
|
||||||
@@ -239,7 +239,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
|||||||
will generate a signal and we will siglongjmp() from that here */
|
will generate a signal and we will siglongjmp() from that here */
|
||||||
if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
|
if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
|
||||||
/* this is coming from a siglongjmp() */
|
/* this is coming from a siglongjmp() */
|
||||||
failf(data, "name lookup time-outed");
|
failf(data, "name lookup timed out");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -252,9 +252,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
}
|
|
||||||
|
|
||||||
/* See if its already in our dns cache */
|
/* See if its already in our dns cache */
|
||||||
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
|
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
|
||||||
@@ -282,7 +280,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
|||||||
|
|
||||||
dns->timestamp = now;
|
dns->timestamp = now;
|
||||||
dns->inuse++; /* mark entry as in-use */
|
dns->inuse++; /* mark entry as in-use */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
dns->entry_id = entry_id;
|
dns->entry_id = entry_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -297,14 +295,13 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
|||||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||||
{
|
{
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
}
|
|
||||||
dns->inuse--;
|
dns->inuse--;
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -337,7 +334,7 @@ void Curl_freednsinfo(void *freethis)
|
|||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* These two are strictly for memory tracing and are using the same
|
/* These two are strictly for memory tracing and are using the same
|
||||||
* style as the family otherwise present in memdebug.c. I put these ones
|
* style as the family otherwise present in memdebug.c. I put these ones
|
||||||
* here since they require a bunch of struct types I didn't wanna include
|
* here since they require a bunch of struct types I didn't wanna include
|
||||||
@@ -455,18 +452,22 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
|||||||
copy->h_aliases = (char**)bufptr;
|
copy->h_aliases = (char**)bufptr;
|
||||||
|
|
||||||
/* Figure out how many aliases there are */
|
/* Figure out how many aliases there are */
|
||||||
for (i = 0; orig->h_aliases[i] != NULL; ++i);
|
for (i = 0; orig->h_aliases && orig->h_aliases[i]; ++i);
|
||||||
|
|
||||||
/* Reserve room for the array */
|
/* Reserve room for the array */
|
||||||
bufptr += (i + 1) * sizeof(char*);
|
bufptr += (i + 1) * sizeof(char*);
|
||||||
|
|
||||||
/* Clone all known aliases */
|
/* Clone all known aliases */
|
||||||
|
if(orig->h_aliases) {
|
||||||
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
||||||
len = strlen(str) + 1;
|
len = strlen(str) + 1;
|
||||||
strncpy(bufptr, str, len);
|
strncpy(bufptr, str, len);
|
||||||
copy->h_aliases[i] = bufptr;
|
copy->h_aliases[i] = bufptr;
|
||||||
bufptr += len;
|
bufptr += len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* if(!orig->h_aliases) i was already set to 0 */
|
||||||
|
|
||||||
/* Terminate the alias list with a NULL */
|
/* Terminate the alias list with a NULL */
|
||||||
copy->h_aliases[i] = NULL;
|
copy->h_aliases[i] = NULL;
|
||||||
|
|
||||||
@@ -532,10 +533,6 @@ static char *MakeIP(unsigned long num, char *addr, int addr_len)
|
|||||||
return (addr);
|
return (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
|
||||||
#define INADDR_NONE (in_addr_t) ~0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void hostcache_fixoffset(struct hostent *h, int offset)
|
static void hostcache_fixoffset(struct hostent *h, int offset)
|
||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
@@ -573,7 +570,8 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
|||||||
port=0; /* unused in IPv4 code */
|
port=0; /* unused in IPv4 code */
|
||||||
ret = 0; /* to prevent the compiler warning */
|
ret = 0; /* to prevent the compiler warning */
|
||||||
|
|
||||||
if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
|
in=inet_addr(hostname);
|
||||||
|
if (in != CURL_INADDR_NONE) {
|
||||||
struct in_addr *addrentry;
|
struct in_addr *addrentry;
|
||||||
struct namebuf {
|
struct namebuf {
|
||||||
struct hostent hostentry;
|
struct hostent hostentry;
|
||||||
@@ -630,7 +628,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
|||||||
step_size+=200;
|
step_size+=200;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -680,7 +678,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
|||||||
if(!h) /* failure */
|
if(!h) /* failure */
|
||||||
res=1;
|
res=1;
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||||
#endif
|
#endif
|
||||||
if(!res) {
|
if(!res) {
|
||||||
|
11
lib/hostip.h
11
lib/hostip.h
@@ -41,7 +41,7 @@ struct Curl_dns_entry {
|
|||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
long inuse; /* use-counter, make very sure you decrease this
|
long inuse; /* use-counter, make very sure you decrease this
|
||||||
when you're done using the address you received */
|
when you're done using the address you received */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
char *entry_id;
|
char *entry_id;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -70,7 +70,7 @@ void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
|||||||
/* free cached name info */
|
/* free cached name info */
|
||||||
void Curl_freednsinfo(void *freethis);
|
void Curl_freednsinfo(void *freethis);
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
void curl_freeaddrinfo(struct addrinfo *freethis,
|
void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||||
int line, const char *source);
|
int line, const char *source);
|
||||||
int curl_getaddrinfo(char *hostname, char *service,
|
int curl_getaddrinfo(char *hostname, char *service,
|
||||||
@@ -79,4 +79,11 @@ int curl_getaddrinfo(char *hostname, char *service,
|
|||||||
int line, const char *source);
|
int line, const char *source);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef INADDR_NONE
|
||||||
|
#define CURL_INADDR_NONE (in_addr_t) ~0
|
||||||
|
#else
|
||||||
|
#define CURL_INADDR_NONE INADDR_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
258
lib/http.c
258
lib/http.c
@@ -54,7 +54,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -89,12 +88,15 @@
|
|||||||
#include "cookie.h"
|
#include "cookie.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_ntlm.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -190,6 +192,7 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
char *ptr;
|
char *ptr;
|
||||||
int size;
|
int size;
|
||||||
struct HTTP *http = conn->proto.http;
|
struct HTTP *http = conn->proto.http;
|
||||||
|
int sendsize;
|
||||||
|
|
||||||
/* The looping below is required since we use non-blocking sockets, but due
|
/* The looping below is required since we use non-blocking sockets, but due
|
||||||
to the circumstances we will just loop and try again and again etc */
|
to the circumstances we will just loop and try again and again etc */
|
||||||
@@ -197,7 +200,28 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
ptr = in->buffer;
|
ptr = in->buffer;
|
||||||
size = in->size_used;
|
size = in->size_used;
|
||||||
|
|
||||||
res = Curl_write(conn, sockfd, ptr, size, &amount);
|
if(conn->protocol & PROT_HTTPS) {
|
||||||
|
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
|
||||||
|
when we speak HTTPS, as if only a fraction of it is sent now, this data
|
||||||
|
needs to fit into the normal read-callback buffer later on and that
|
||||||
|
buffer is using this size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
|
||||||
|
|
||||||
|
/* OpenSSL is very picky and we must send the SAME buffer pointer to the
|
||||||
|
library when we attempt to re-send this buffer. Sending the same data
|
||||||
|
is not enough, we must use the exact same address. For this reason, we
|
||||||
|
must copy the data to the uploadbuffer first, since that is the buffer
|
||||||
|
we will be using if this send is retried later.
|
||||||
|
*/
|
||||||
|
memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
|
||||||
|
ptr = conn->data->state.uploadbuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sendsize = size;
|
||||||
|
|
||||||
|
res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
|
||||||
|
|
||||||
if(CURLE_OK == res) {
|
if(CURLE_OK == res) {
|
||||||
|
|
||||||
@@ -213,7 +237,8 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
and wait until it might work again. */
|
and wait until it might work again. */
|
||||||
|
|
||||||
size -= amount;
|
size -= amount;
|
||||||
ptr += amount;
|
|
||||||
|
ptr = in->buffer + amount;
|
||||||
|
|
||||||
/* backup the currently set pointers */
|
/* backup the currently set pointers */
|
||||||
http->backup.fread = conn->fread;
|
http->backup.fread = conn->fread;
|
||||||
@@ -491,16 +516,16 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||||
the line isn't really terminated until the LF comes */
|
the line isn't really terminated until the LF comes */
|
||||||
|
|
||||||
/* output debug output if that is requested */
|
|
||||||
if(data->set.verbose)
|
|
||||||
Curl_debug(data, CURLINFO_DATA_IN, line_start, perline);
|
|
||||||
|
|
||||||
if('\r' == line_start[0]) {
|
if('\r' == line_start[0]) {
|
||||||
/* end of headers */
|
/* end of headers */
|
||||||
keepon=FALSE;
|
keepon=FALSE;
|
||||||
break; /* breaks out of loop, not switch */
|
break; /* breaks out of loop, not switch */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* output debug output if that is requested */
|
||||||
|
if(data->set.verbose)
|
||||||
|
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline);
|
||||||
|
|
||||||
if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||||
&subversion,
|
&subversion,
|
||||||
&httperror)) {
|
&httperror)) {
|
||||||
@@ -591,11 +616,15 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
conn->fread = data->set.fread; /* restore */
|
conn->fread = data->set.fread; /* restore */
|
||||||
conn->fread_in = data->set.in; /* restore */
|
conn->fread_in = data->set.in; /* restore */
|
||||||
|
|
||||||
|
if (http == NULL)
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
if(http->send_buffer) {
|
if(http->send_buffer) {
|
||||||
send_buffer *buff = http->send_buffer;
|
send_buffer *buff = http->send_buffer;
|
||||||
|
|
||||||
free(buff->buffer);
|
free(buff->buffer);
|
||||||
free(buff);
|
free(buff);
|
||||||
|
http->send_buffer = NULL; /* cleaer the pointer */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||||
@@ -616,6 +645,25 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode Curl_output_basic(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
char *authorization;
|
||||||
|
struct SessionHandle *data=conn->data;
|
||||||
|
|
||||||
|
sprintf(data->state.buffer, "%s:%s", conn->user, conn->passwd);
|
||||||
|
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||||
|
&authorization) >= 0) {
|
||||||
|
if(conn->allocptr.userpwd)
|
||||||
|
free(conn->allocptr.userpwd);
|
||||||
|
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
||||||
|
authorization);
|
||||||
|
free(authorization);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_http(struct connectdata *conn)
|
CURLcode Curl_http(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
@@ -626,6 +674,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
char *ppath = conn->ppath; /* three previous function arguments */
|
char *ppath = conn->ppath; /* three previous function arguments */
|
||||||
char *host = conn->name;
|
char *host = conn->name;
|
||||||
const char *te = ""; /* tranfer-encoding */
|
const char *te = ""; /* tranfer-encoding */
|
||||||
|
char *ptr;
|
||||||
|
char *request;
|
||||||
|
|
||||||
if(!conn->proto.http) {
|
if(!conn->proto.http) {
|
||||||
/* Only allocate this struct if we don't already have it! */
|
/* Only allocate this struct if we don't already have it! */
|
||||||
@@ -647,6 +697,13 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
data->set.httpreq = HTTPREQ_PUT;
|
data->set.httpreq = HTTPREQ_PUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request = data->set.customrequest?
|
||||||
|
data->set.customrequest:
|
||||||
|
(data->set.no_body?(char *)"HEAD":
|
||||||
|
((HTTPREQ_POST == data->set.httpreq) ||
|
||||||
|
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
|
||||||
|
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
|
||||||
|
|
||||||
/* The User-Agent string has been built in url.c already, because it might
|
/* The User-Agent string has been built in url.c already, because it might
|
||||||
have been used in the proxy connect, but if we have got a header with
|
have been used in the proxy connect, but if we have got a header with
|
||||||
the user-agent string specified, we erase the previously made string
|
the user-agent string specified, we erase the previously made string
|
||||||
@@ -656,27 +713,50 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
conn->allocptr.uagent=NULL;
|
conn->allocptr.uagent=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((conn->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
|
|
||||||
char *authorization;
|
|
||||||
|
|
||||||
/* To prevent the user+password to get sent to other than the original
|
/* To prevent the user+password to get sent to other than the original
|
||||||
host due to a location-follow, we do some weirdo checks here */
|
host due to a location-follow, we do some weirdo checks here */
|
||||||
if(!data->state.this_is_a_follow ||
|
if(!data->state.this_is_a_follow ||
|
||||||
!data->state.auth_host ||
|
!data->state.auth_host ||
|
||||||
curl_strequal(data->state.auth_host, conn->hostname) ||
|
curl_strequal(data->state.auth_host, conn->hostname) ||
|
||||||
data->set.http_disable_hostname_check_before_authentication) {
|
data->set.http_disable_hostname_check_before_authentication) {
|
||||||
sprintf(data->state.buffer, "%s:%s",
|
|
||||||
data->state.user, data->state.passwd);
|
#ifdef GSSAPI
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
|
||||||
&authorization) >= 0) {
|
data->state.negotiate.context &&
|
||||||
if(conn->allocptr.userpwd)
|
!GSS_ERROR(data->state.negotiate.status)) {
|
||||||
free(conn->allocptr.userpwd);
|
result = Curl_output_negotiate(conn);
|
||||||
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
if (result)
|
||||||
authorization);
|
return result;
|
||||||
free(authorization);
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
|
result = Curl_output_ntlm(conn, FALSE);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if((data->state.authwant == CURLAUTH_DIGEST) &&
|
||||||
|
data->state.digest.nonce) {
|
||||||
|
result = Curl_output_digest(conn,
|
||||||
|
(unsigned char *)request,
|
||||||
|
(unsigned char *)ppath);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
|
||||||
|
conn->bits.user_passwd &&
|
||||||
|
!checkheaders(data, "Authorization:")) {
|
||||||
|
result = Curl_output_basic(conn);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((data->change.referer) && !checkheaders(data, "Referer:")) {
|
if((data->change.referer) && !checkheaders(data, "Referer:")) {
|
||||||
if(conn->allocptr.ref)
|
if(conn->allocptr.ref)
|
||||||
free(conn->allocptr.ref);
|
free(conn->allocptr.ref);
|
||||||
@@ -714,30 +794,30 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->cookies) {
|
ptr = checkheaders(data, "Host:");
|
||||||
co = Curl_cookie_getlist(data->cookies,
|
if(ptr) {
|
||||||
host, ppath,
|
/* If we have a given custom Host: header, we extract the host name
|
||||||
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
|
in order to possibly use it for cookie reasons later on. */
|
||||||
}
|
char *start = ptr+strlen("Host:");
|
||||||
if (data->change.proxy && *data->change.proxy &&
|
char *ptr;
|
||||||
!data->set.tunnel_thru_httpproxy &&
|
while(*start && isspace((int)*start ))
|
||||||
!(conn->protocol&PROT_HTTPS)) {
|
start++;
|
||||||
/* The path sent to the proxy is in fact the entire URL */
|
ptr = start; /* start host-scanning here */
|
||||||
ppath = data->change.url;
|
|
||||||
}
|
|
||||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
|
||||||
/* we must build the whole darned post sequence first, so that we have
|
|
||||||
a size of the whole shebang before we start to send it */
|
|
||||||
result = Curl_getFormData(&http->sendit, data->set.httppost,
|
|
||||||
&http->postsize);
|
|
||||||
if(CURLE_OK != result) {
|
|
||||||
/* Curl_getFormData() doesn't use failf() */
|
|
||||||
failf(data, "failed creating formpost data");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!checkheaders(data, "Host:")) {
|
/* scan through the string to find the end (space or colon) */
|
||||||
|
while(*ptr && !isspace((int)*ptr) && !(':'==*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if(ptr != start) {
|
||||||
|
int len=ptr-start;
|
||||||
|
conn->allocptr.cookiehost = malloc(len+1);
|
||||||
|
if(!conn->allocptr.cookiehost)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
memcpy(conn->allocptr.cookiehost, start, len);
|
||||||
|
conn->allocptr.cookiehost[len]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* if ptr_host is already set, it is almost OK since we only re-use
|
/* if ptr_host is already set, it is almost OK since we only re-use
|
||||||
connections to the very same host and port, but when we use a HTTP
|
connections to the very same host and port, but when we use a HTTP
|
||||||
proxy we have a persistant connect and yet we must change the Host:
|
proxy we have a persistant connect and yet we must change the Host:
|
||||||
@@ -765,6 +845,32 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
conn->remote_port);
|
conn->remote_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(data->cookies) {
|
||||||
|
co = Curl_cookie_getlist(data->cookies,
|
||||||
|
conn->allocptr.cookiehost?
|
||||||
|
conn->allocptr.cookiehost:host, ppath,
|
||||||
|
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->bits.httpproxy &&
|
||||||
|
!data->set.tunnel_thru_httpproxy &&
|
||||||
|
!(conn->protocol&PROT_HTTPS)) {
|
||||||
|
/* The path sent to the proxy is in fact the entire URL */
|
||||||
|
ppath = data->change.url;
|
||||||
|
}
|
||||||
|
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||||
|
/* we must build the whole darned post sequence first, so that we have
|
||||||
|
a size of the whole shebang before we start to send it */
|
||||||
|
result = Curl_getFormData(&http->sendit, data->set.httppost,
|
||||||
|
&http->postsize);
|
||||||
|
if(CURLE_OK != result) {
|
||||||
|
/* Curl_getFormData() doesn't use failf() */
|
||||||
|
failf(data, "failed creating formpost data");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!checkheaders(data, "Pragma:"))
|
if(!checkheaders(data, "Pragma:"))
|
||||||
http->p_pragma = "Pragma: no-cache\r\n";
|
http->p_pragma = "Pragma: no-cache\r\n";
|
||||||
|
|
||||||
@@ -861,13 +967,14 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
{
|
||||||
/* Use 1.1 unless the use specificly asked for 1.0 */
|
/* Use 1.1 unless the use specificly asked for 1.0 */
|
||||||
const char *httpstring=
|
const char *httpstring=
|
||||||
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
||||||
|
|
||||||
send_buffer *req_buffer;
|
send_buffer *req_buffer;
|
||||||
struct curl_slist *headers=data->set.headers;
|
struct curl_slist *headers=data->set.headers;
|
||||||
|
size_t postsize;
|
||||||
|
|
||||||
/* initialize a dynamic send-buffer */
|
/* initialize a dynamic send-buffer */
|
||||||
req_buffer = add_buffer_init();
|
req_buffer = add_buffer_init();
|
||||||
@@ -875,7 +982,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* add the main request stuff */
|
/* add the main request stuff */
|
||||||
add_bufferf(req_buffer,
|
add_bufferf(req_buffer,
|
||||||
"%s " /* GET/HEAD/POST/PUT */
|
"%s " /* GET/HEAD/POST/PUT */
|
||||||
"%s HTTP/%s\r\n" /* path */
|
"%s HTTP/%s\r\n" /* path + HTTP version */
|
||||||
"%s" /* proxyuserpwd */
|
"%s" /* proxyuserpwd */
|
||||||
"%s" /* userpwd */
|
"%s" /* userpwd */
|
||||||
"%s" /* range */
|
"%s" /* range */
|
||||||
@@ -888,16 +995,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
"%s" /* referer */
|
"%s" /* referer */
|
||||||
"%s",/* transfer-encoding */
|
"%s",/* transfer-encoding */
|
||||||
|
|
||||||
data->set.customrequest?data->set.customrequest:
|
request,
|
||||||
(data->set.no_body?"HEAD":
|
ppath,
|
||||||
((HTTPREQ_POST == data->set.httpreq) ||
|
httpstring,
|
||||||
(HTTPREQ_POST_FORM == data->set.httpreq))?"POST":
|
(conn->bits.httpproxy && conn->allocptr.proxyuserpwd)?
|
||||||
(HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"),
|
conn->allocptr.proxyuserpwd:"",
|
||||||
ppath, httpstring,
|
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||||
(conn->bits.proxy_user_passwd &&
|
|
||||||
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
|
|
||||||
(conn->bits.user_passwd && conn->allocptr.userpwd)?
|
|
||||||
conn->allocptr.userpwd:"",
|
|
||||||
(conn->bits.use_range && conn->allocptr.rangeline)?
|
(conn->bits.use_range && conn->allocptr.rangeline)?
|
||||||
conn->allocptr.rangeline:"",
|
conn->allocptr.rangeline:"",
|
||||||
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
|
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
|
||||||
@@ -1105,6 +1208,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
case HTTPREQ_POST:
|
case HTTPREQ_POST:
|
||||||
/* this is the simple POST, using x-www-form-urlencoded style */
|
/* this is the simple POST, using x-www-form-urlencoded style */
|
||||||
|
|
||||||
|
/* store the size of the postfields */
|
||||||
|
postsize = data->set.postfieldsize?
|
||||||
|
data->set.postfieldsize:
|
||||||
|
(data->set.postfields?strlen(data->set.postfields):0);
|
||||||
|
|
||||||
if(!conn->bits.upload_chunky) {
|
if(!conn->bits.upload_chunky) {
|
||||||
/* We only set Content-Length and allow a custom Content-Length if
|
/* We only set Content-Length and allow a custom Content-Length if
|
||||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||||
@@ -1113,11 +1221,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
if(!checkheaders(data, "Content-Length:"))
|
if(!checkheaders(data, "Content-Length:"))
|
||||||
/* we allow replacing this header, although it isn't very wise to
|
/* we allow replacing this header, although it isn't very wise to
|
||||||
actually set your own */
|
actually set your own */
|
||||||
add_bufferf(req_buffer,
|
add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize);
|
||||||
"Content-Length: %d\r\n",
|
|
||||||
data->set.postfieldsize?
|
|
||||||
data->set.postfieldsize:
|
|
||||||
(data->set.postfields?strlen(data->set.postfields):0) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!checkheaders(data, "Content-Type:"))
|
if(!checkheaders(data, "Content-Type:"))
|
||||||
@@ -1126,12 +1230,28 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
|
|
||||||
add_buffer(req_buffer, "\r\n", 2);
|
add_buffer(req_buffer, "\r\n", 2);
|
||||||
|
|
||||||
/* and here we setup the pointers to the actual data */
|
|
||||||
if(data->set.postfields) {
|
if(data->set.postfields) {
|
||||||
if(data->set.postfieldsize)
|
|
||||||
http->postsize = data->set.postfieldsize;
|
if(postsize < (100*1024)) {
|
||||||
else
|
/* The post data is less than 100K, then append it to the header.
|
||||||
http->postsize = strlen(data->set.postfields);
|
This limit is no magic limit but only set to prevent really huge
|
||||||
|
POSTs to get the data duplicated with malloc() and family. */
|
||||||
|
|
||||||
|
if(!conn->bits.upload_chunky)
|
||||||
|
/* We're not sending it 'chunked', append it to the request
|
||||||
|
already now to reduce the number if send() calls */
|
||||||
|
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||||
|
else {
|
||||||
|
/* Append the POST data chunky-style */
|
||||||
|
add_bufferf(req_buffer, "%x\r\n", postsize);
|
||||||
|
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||||
|
add_buffer(req_buffer, "\r\n0\r\n", 5); /* end of a chunked
|
||||||
|
transfer stream */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* A huge POST coming up, do data separate from the request */
|
||||||
|
http->postsize = postsize;
|
||||||
http->postdata = data->set.postfields;
|
http->postdata = data->set.postfields;
|
||||||
|
|
||||||
http->sending = HTTPSEND_BODY;
|
http->sending = HTTPSEND_BODY;
|
||||||
@@ -1142,6 +1262,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||||
@@ -1156,8 +1277,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
result =
|
result =
|
||||||
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
|
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
conn->firstsocket,
|
http->postdata?conn->firstsocket:-1,
|
||||||
&http->writebytecount);
|
http->postdata?&http->writebytecount:NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1178,8 +1299,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
} while (0); /* this is just a left-over from the multiple document download
|
}
|
||||||
attempts */
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -186,15 +186,22 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEFLATE:
|
case DEFLATE:
|
||||||
|
/* update conn->keep.str to point to the chunk data. */
|
||||||
|
conn->keep.str = datap;
|
||||||
result = Curl_unencode_deflate_write(conn->data, &conn->keep, piece);
|
result = Curl_unencode_deflate_write(conn->data, &conn->keep, piece);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GZIP:
|
case GZIP:
|
||||||
|
/* update conn->keep.str to point to the chunk data. */
|
||||||
|
conn->keep.str = datap;
|
||||||
|
result = Curl_unencode_gzip_write(conn->data, &conn->keep, piece);
|
||||||
|
break;
|
||||||
|
|
||||||
case COMPRESS:
|
case COMPRESS:
|
||||||
default:
|
default:
|
||||||
failf (conn->data,
|
failf (conn->data,
|
||||||
"Unrecognized content encoding type. "
|
"Unrecognized content encoding type. "
|
||||||
"libcurl understands `identity' and `deflate' "
|
"libcurl understands `identity', `deflate' and `gzip' "
|
||||||
"content encodings.");
|
"content encodings.");
|
||||||
return CHUNKE_BAD_ENCODING;
|
return CHUNKE_BAD_ENCODING;
|
||||||
}
|
}
|
||||||
|
231
lib/http_digest.c
Normal file
231
lib/http_digest.c
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#ifndef CURL_DISABLE_HTTP
|
||||||
|
/* -- WIN32 approved -- */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "strequal.h"
|
||||||
|
|
||||||
|
#include "md5.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
#include "memdebug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Test example header:
|
||||||
|
|
||||||
|
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||||
|
char *header) /* rest of the www-authenticate:
|
||||||
|
header */
|
||||||
|
{
|
||||||
|
bool more = TRUE;
|
||||||
|
struct SessionHandle *data=conn->data;
|
||||||
|
|
||||||
|
/* skip initial whitespaces */
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
|
||||||
|
if(checkprefix("Digest", header)) {
|
||||||
|
header += strlen("Digest");
|
||||||
|
|
||||||
|
/* clear off any former leftovers and init to defaults */
|
||||||
|
Curl_digest_cleanup(data);
|
||||||
|
|
||||||
|
while(more) {
|
||||||
|
char value[32];
|
||||||
|
char content[128];
|
||||||
|
int totlen=0;
|
||||||
|
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
|
||||||
|
/* how big can these strings be? */
|
||||||
|
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||||
|
value, content)) {
|
||||||
|
if(strequal(value, "nonce")) {
|
||||||
|
data->state.digest.nonce = strdup(content);
|
||||||
|
}
|
||||||
|
else if(strequal(value, "cnonce")) {
|
||||||
|
data->state.digest.cnonce = strdup(content);
|
||||||
|
}
|
||||||
|
else if(strequal(value, "realm")) {
|
||||||
|
data->state.digest.realm = strdup(content);
|
||||||
|
}
|
||||||
|
else if(strequal(value, "algorithm")) {
|
||||||
|
if(strequal(content, "MD5-sess"))
|
||||||
|
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
|
||||||
|
/* else, remain using the default md5 */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* unknown specifier, ignore it! */
|
||||||
|
}
|
||||||
|
totlen = strlen(value)+strlen(content)+3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break; /* we're done here */
|
||||||
|
|
||||||
|
header += totlen;
|
||||||
|
if(',' == *header)
|
||||||
|
/* allow the list to be comma-separated */
|
||||||
|
header++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!data->state.digest.nonce)
|
||||||
|
return CURLDIGEST_BAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* else not a digest, get out */
|
||||||
|
return CURLDIGEST_NONE;
|
||||||
|
|
||||||
|
return CURLDIGEST_FINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
|
||||||
|
static void md5_to_ascii(unsigned char *source, /* 16 bytes */
|
||||||
|
unsigned char *dest) /* 33 bytes */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<16; i++)
|
||||||
|
sprintf((char *)&dest[i*2], "%02x", source[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||||
|
unsigned char *request,
|
||||||
|
unsigned char *uripath)
|
||||||
|
{
|
||||||
|
/* We have a Digest setup for this, use it!
|
||||||
|
Now, to get all the details for this sorted out, I must urge you dear friend
|
||||||
|
to read up on the RFC2617 section 3.2.2, */
|
||||||
|
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
||||||
|
unsigned char ha1[33]; /* 32 digits and 1 zero byte */
|
||||||
|
unsigned char ha2[33];
|
||||||
|
unsigned char request_digest[33];
|
||||||
|
unsigned char *md5this;
|
||||||
|
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
||||||
|
|
||||||
|
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
|
||||||
|
|
||||||
|
if the algorithm is "MD5-sess" then:
|
||||||
|
|
||||||
|
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||||
|
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||||
|
*/
|
||||||
|
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
|
||||||
|
md5this = (unsigned char *)
|
||||||
|
aprintf("%s:%s:%s:%s:%s",
|
||||||
|
conn->user,
|
||||||
|
data->state.digest.realm,
|
||||||
|
conn->passwd,
|
||||||
|
data->state.digest.nonce,
|
||||||
|
data->state.digest.cnonce);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
md5this = (unsigned char *)
|
||||||
|
aprintf("%s:%s:%s",
|
||||||
|
conn->user,
|
||||||
|
data->state.digest.realm,
|
||||||
|
conn->passwd);
|
||||||
|
}
|
||||||
|
Curl_md5it(md5buf, md5this);
|
||||||
|
free(md5this); /* free this again */
|
||||||
|
md5_to_ascii(md5buf, ha1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
A2 = Method ":" digest-uri-value
|
||||||
|
|
||||||
|
(The "Method" value is the HTTP request method as specified in section
|
||||||
|
5.1.1 of RFC 2616)
|
||||||
|
*/
|
||||||
|
|
||||||
|
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
|
||||||
|
Curl_md5it(md5buf, md5this);
|
||||||
|
free(md5this); /* free this again */
|
||||||
|
md5_to_ascii(md5buf, ha2);
|
||||||
|
|
||||||
|
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, data->state.digest.nonce,
|
||||||
|
ha2);
|
||||||
|
Curl_md5it(md5buf, md5this);
|
||||||
|
free(md5this); /* free this again */
|
||||||
|
md5_to_ascii(md5buf, request_digest);
|
||||||
|
|
||||||
|
/* for test case 64 (snooped from a Mozilla 1.3a request)
|
||||||
|
|
||||||
|
Authorization: Digest username="testuser", realm="testrealm", \
|
||||||
|
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||||
|
*/
|
||||||
|
|
||||||
|
conn->allocptr.userpwd =
|
||||||
|
aprintf( "Authorization: Digest "
|
||||||
|
"username=\"%s\", "
|
||||||
|
"realm=\"%s\", "
|
||||||
|
"nonce=\"%s\", "
|
||||||
|
"uri=\"%s\", "
|
||||||
|
"response=\"%s\"\r\n",
|
||||||
|
conn->user,
|
||||||
|
data->state.digest.realm,
|
||||||
|
data->state.digest.nonce,
|
||||||
|
uripath, /* this is the PATH part of the URL */
|
||||||
|
request_digest );
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
if(data->state.digest.nonce)
|
||||||
|
free(data->state.digest.nonce);
|
||||||
|
data->state.digest.nonce = NULL;
|
||||||
|
|
||||||
|
if(data->state.digest.cnonce)
|
||||||
|
free(data->state.digest.cnonce);
|
||||||
|
data->state.digest.cnonce = NULL;
|
||||||
|
|
||||||
|
if(data->state.digest.realm)
|
||||||
|
free(data->state.digest.realm);
|
||||||
|
data->state.digest.realm = NULL;
|
||||||
|
|
||||||
|
data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
48
lib/http_digest.h
Normal file
48
lib/http_digest.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef __HTTP_DIGEST_H
|
||||||
|
#define __HTTP_DIGEST_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CURLDIGEST_NONE, /* not a digest */
|
||||||
|
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||||
|
CURLDIGEST_FINE, /* a digest we act on */
|
||||||
|
|
||||||
|
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||||
|
} CURLdigest;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CURLDIGESTALGO_MD5,
|
||||||
|
CURLDIGESTALGO_MD5SESS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this is for digest header input */
|
||||||
|
CURLdigest Curl_input_digest(struct connectdata *conn, char *header);
|
||||||
|
|
||||||
|
/* this is for creating digest header output */
|
||||||
|
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||||
|
unsigned char *request,
|
||||||
|
unsigned char *uripath);
|
||||||
|
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||||
|
|
||||||
|
#endif
|
216
lib/http_negotiate.c
Normal file
216
lib/http_negotiate.c
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
#ifndef CURL_DISABLE_HTTP
|
||||||
|
/* -- WIN32 approved -- */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "strequal.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
#include "memdebug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_gss_name(struct connectdata *conn, gss_name_t *server)
|
||||||
|
{
|
||||||
|
OM_uint32 major_status, minor_status;
|
||||||
|
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
|
||||||
|
char name[2048];
|
||||||
|
|
||||||
|
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
|
||||||
|
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
|
||||||
|
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
|
||||||
|
Change following lines if you want to use GSI */
|
||||||
|
token.length = strlen("khttp@") + strlen(conn->hostname) + 1;
|
||||||
|
if (token.length + 1 > sizeof(name))
|
||||||
|
return EMSGSIZE;
|
||||||
|
sprintf(name, "khttp@%s", conn->hostname);
|
||||||
|
|
||||||
|
token.value = (void *) name;
|
||||||
|
major_status = gss_import_name(&minor_status,
|
||||||
|
&token,
|
||||||
|
GSS_C_NT_HOSTBASED_SERVICE,
|
||||||
|
server);
|
||||||
|
return GSS_ERROR(major_status) ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)
|
||||||
|
{
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
OM_uint32 msg_ctx = 0;
|
||||||
|
gss_buffer_desc status_string;
|
||||||
|
char buf[1024];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||||
|
len = strlen(buf);
|
||||||
|
do {
|
||||||
|
maj_stat = gss_display_status (&min_stat,
|
||||||
|
error_status,
|
||||||
|
GSS_C_MECH_CODE,
|
||||||
|
GSS_C_NO_OID,
|
||||||
|
&msg_ctx,
|
||||||
|
&status_string);
|
||||||
|
if (sizeof(buf) > len + status_string.length + 1) {
|
||||||
|
sprintf(buf + len, ": %s", (char*) status_string.value);
|
||||||
|
len += status_string.length;
|
||||||
|
}
|
||||||
|
gss_release_buffer(&min_stat, &status_string);
|
||||||
|
} while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||||
|
|
||||||
|
infof(conn->data, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Curl_input_negotiate(struct connectdata *conn, char *header)
|
||||||
|
{
|
||||||
|
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
|
||||||
|
OM_uint32 major_status, minor_status, minor_status2;
|
||||||
|
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||||
|
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
if(!checkprefix("GSS-Negotiate", header))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
|
||||||
|
/* We finished succesfully our part of authentication, but server
|
||||||
|
* rejected it (since we're again here). Exit with an error since we
|
||||||
|
* can't invent anything better */
|
||||||
|
Curl_cleanup_negotiate(conn->data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neg_ctx->server_name == NULL &&
|
||||||
|
(ret = get_gss_name(conn, &neg_ctx->server_name)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
header += strlen("GSS-Negotiate");
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
|
||||||
|
len = strlen(header);
|
||||||
|
if (len > 0) {
|
||||||
|
int rawlen;
|
||||||
|
input_token.length = (len+3)/4 * 3;
|
||||||
|
input_token.value = malloc(input_token.length);
|
||||||
|
if (input_token.value == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
rawlen = Curl_base64_decode(header, input_token.value);
|
||||||
|
if (rawlen < 0)
|
||||||
|
return -1;
|
||||||
|
input_token.length = rawlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
major_status = gss_init_sec_context(&minor_status,
|
||||||
|
GSS_C_NO_CREDENTIAL,
|
||||||
|
&neg_ctx->context,
|
||||||
|
neg_ctx->server_name,
|
||||||
|
GSS_C_NO_OID,
|
||||||
|
GSS_C_DELEG_FLAG,
|
||||||
|
0,
|
||||||
|
GSS_C_NO_CHANNEL_BINDINGS,
|
||||||
|
&input_token,
|
||||||
|
NULL,
|
||||||
|
&output_token,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (input_token.length > 0)
|
||||||
|
gss_release_buffer(&minor_status2, &input_token);
|
||||||
|
neg_ctx->status = major_status;
|
||||||
|
if (GSS_ERROR(major_status)) {
|
||||||
|
/* Curl_cleanup_negotiate(conn->data) ??? */
|
||||||
|
log_gss_error(conn, minor_status,
|
||||||
|
(char *)"gss_init_sec_context() failed: ");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output_token.length == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
neg_ctx->output_token = output_token;
|
||||||
|
/* conn->bits.close = FALSE; */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CURLcode Curl_output_negotiate(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
|
||||||
|
OM_uint32 minor_status;
|
||||||
|
char *encoded = NULL;
|
||||||
|
int len = Curl_base64_encode(neg_ctx->output_token.value,
|
||||||
|
neg_ctx->output_token.length,
|
||||||
|
&encoded);
|
||||||
|
if (len < 0)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
conn->allocptr.userpwd =
|
||||||
|
aprintf("Authorization: GSS-Negotiate %s\r\n", encoded);
|
||||||
|
free(encoded);
|
||||||
|
gss_release_buffer(&minor_status, &neg_ctx->output_token);
|
||||||
|
return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
OM_uint32 minor_status;
|
||||||
|
struct negotiatedata *neg_ctx = &data->state.negotiate;
|
||||||
|
|
||||||
|
if (neg_ctx->context != GSS_C_NO_CONTEXT)
|
||||||
|
gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
|
||||||
|
|
||||||
|
if (neg_ctx->output_token.length != 0)
|
||||||
|
gss_release_buffer(&minor_status, &neg_ctx->output_token);
|
||||||
|
|
||||||
|
if (neg_ctx->server_name != GSS_C_NO_NAME)
|
||||||
|
gss_release_name(&minor_status, &neg_ctx->server_name);
|
||||||
|
|
||||||
|
memset(neg_ctx, 0, sizeof(*neg_ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
39
lib/http_negotiate.h
Normal file
39
lib/http_negotiate.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef __HTTP_NEGOTIATE_H
|
||||||
|
#define __HTTP_NEGOTIATE_H
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
/* this is for Negotiate header input */
|
||||||
|
int Curl_input_negotiate(struct connectdata *conn, char *header);
|
||||||
|
|
||||||
|
/* this is for creating Negotiate header output */
|
||||||
|
CURLcode Curl_output_negotiate(struct connectdata *conn);
|
||||||
|
|
||||||
|
void Curl_cleanup_negotiate(struct SessionHandle *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
571
lib/http_ntlm.c
Normal file
571
lib/http_ntlm.c
Normal file
@@ -0,0 +1,571 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
/* NTLM details:
|
||||||
|
|
||||||
|
http://davenport.sourceforge.net/ntlm.html
|
||||||
|
http://www.innovation.ch/java/ntlm.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CURL_DISABLE_HTTP
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
|
||||||
|
|
||||||
|
/* -- WIN32 approved -- */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "strequal.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "http_ntlm.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
#include <openssl/des.h>
|
||||||
|
#include <openssl/md4.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||||
|
#define DES_key_schedule des_key_schedule
|
||||||
|
#define DES_cblock des_cblock
|
||||||
|
#define DES_set_odd_parity des_set_odd_parity
|
||||||
|
#define DES_set_key des_set_key
|
||||||
|
#define DES_ecb_encrypt des_ecb_encrypt
|
||||||
|
|
||||||
|
/* This is how things were done in the old days */#define DESKEY(x) x
|
||||||
|
#define DESKEY(x) x
|
||||||
|
#define DESKEYARG(x) x
|
||||||
|
#else
|
||||||
|
/* Modern version */
|
||||||
|
#define DESKEYARG(x) *x
|
||||||
|
#define DESKEY(x) &x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
#include "memdebug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define this to make the type-3 message include the NT response message */
|
||||||
|
#undef USE_NTRESPONSES
|
||||||
|
|
||||||
|
/*
|
||||||
|
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
||||||
|
long:
|
||||||
|
|
||||||
|
1. a 'short' containing the length of the buffer in bytes
|
||||||
|
2. a 'short' containing the allocated space for the buffer in bytes
|
||||||
|
3. a 'long' containing the offset to the start of the buffer from the
|
||||||
|
beginning of the NTLM message, in bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
||||||
|
bool proxy, /* if proxy or not */
|
||||||
|
char *header) /* rest of the www-authenticate:
|
||||||
|
header */
|
||||||
|
{
|
||||||
|
/* point to the correct struct with this */
|
||||||
|
struct ntlmdata *ntlm;
|
||||||
|
|
||||||
|
ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
|
||||||
|
|
||||||
|
/* skip initial whitespaces */
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
|
||||||
|
if(checkprefix("NTLM", header)) {
|
||||||
|
unsigned char buffer[256];
|
||||||
|
header += strlen("NTLM");
|
||||||
|
|
||||||
|
while(*header && isspace((int)*header))
|
||||||
|
header++;
|
||||||
|
|
||||||
|
if(*header) {
|
||||||
|
/* We got a type-2 message here:
|
||||||
|
|
||||||
|
Index Description Content
|
||||||
|
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||||
|
(0x4e544c4d53535000)
|
||||||
|
8 NTLM Message Type long (0x02000000)
|
||||||
|
12 Target Name security buffer(*)
|
||||||
|
20 Flags long
|
||||||
|
24 Challenge 8 bytes
|
||||||
|
(32) Context (optional) 8 bytes (two consecutive longs)
|
||||||
|
(40) Target Information (optional) security buffer(*)
|
||||||
|
32 (48) start of data block
|
||||||
|
*/
|
||||||
|
|
||||||
|
int size = Curl_base64_decode(header, buffer);
|
||||||
|
|
||||||
|
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
|
||||||
|
|
||||||
|
if(size >= 48)
|
||||||
|
/* the nonce of interest is index [24 .. 31], 8 bytes */
|
||||||
|
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||||
|
|
||||||
|
/* at index decimal 20, there's a 32bit NTLM flag field */
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(ntlm->state >= NTLMSTATE_TYPE1)
|
||||||
|
return CURLNTLM_BAD;
|
||||||
|
|
||||||
|
ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CURLNTLM_FINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||||
|
* key schedule ks is also set.
|
||||||
|
*/
|
||||||
|
static void setup_des_key(unsigned char *key_56,
|
||||||
|
DES_key_schedule DESKEYARG(ks))
|
||||||
|
{
|
||||||
|
DES_cblock key;
|
||||||
|
|
||||||
|
key[0] = key_56[0];
|
||||||
|
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
|
||||||
|
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
|
||||||
|
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
|
||||||
|
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
|
||||||
|
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
|
||||||
|
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
|
||||||
|
key[7] = (key_56[6] << 1) & 0xFF;
|
||||||
|
|
||||||
|
DES_set_odd_parity(&key);
|
||||||
|
DES_set_key(&key, ks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||||
|
* 8 byte plaintext is encrypted with each key and the resulting 24
|
||||||
|
* bytes are stored in the results array.
|
||||||
|
*/
|
||||||
|
static void calc_resp(unsigned char *keys,
|
||||||
|
unsigned char *plaintext,
|
||||||
|
unsigned char *results)
|
||||||
|
{
|
||||||
|
DES_key_schedule ks;
|
||||||
|
|
||||||
|
setup_des_key(keys, DESKEY(ks));
|
||||||
|
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
||||||
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
|
||||||
|
setup_des_key(keys+7, DESKEY(ks));
|
||||||
|
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
|
||||||
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
|
||||||
|
setup_des_key(keys+14, DESKEY(ks));
|
||||||
|
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
|
||||||
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up lanmanager and nt hashed passwords
|
||||||
|
*/
|
||||||
|
static void mkhash(char *password,
|
||||||
|
unsigned char *nonce, /* 8 bytes */
|
||||||
|
unsigned char *lmresp /* must fit 0x18 bytes */
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
, unsigned char *ntresp /* must fit 0x18 bytes */
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned char lmbuffer[21];
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
unsigned char ntbuffer[21];
|
||||||
|
#endif
|
||||||
|
unsigned char *pw;
|
||||||
|
static const unsigned char magic[] = {
|
||||||
|
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
int len = strlen(password);
|
||||||
|
|
||||||
|
/* make it fit at least 14 bytes */
|
||||||
|
pw = malloc(len<7?14:len*2);
|
||||||
|
if(!pw)
|
||||||
|
return; /* this will lead to a badly generated package */
|
||||||
|
|
||||||
|
if (len > 14)
|
||||||
|
len = 14;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++)
|
||||||
|
pw[i] = toupper(password[i]);
|
||||||
|
|
||||||
|
for (; i<14; i++)
|
||||||
|
pw[i] = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* create LanManager hashed password */
|
||||||
|
DES_key_schedule ks;
|
||||||
|
|
||||||
|
setup_des_key(pw, DESKEY(ks));
|
||||||
|
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
||||||
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
|
||||||
|
setup_des_key(pw+7, DESKEY(ks));
|
||||||
|
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
||||||
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
|
||||||
|
memset(lmbuffer+16, 0, 5);
|
||||||
|
}
|
||||||
|
/* create LM responses */
|
||||||
|
calc_resp(lmbuffer, nonce, lmresp);
|
||||||
|
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
{
|
||||||
|
/* create NT hashed password */
|
||||||
|
MD4_CTX MD4;
|
||||||
|
|
||||||
|
len = strlen(password);
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
pw[2*i] = password[i];
|
||||||
|
pw[2*i+1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MD4_Init(&MD4);
|
||||||
|
MD4_Update(&MD4, pw, 2*len);
|
||||||
|
MD4_Final(ntbuffer, &MD4);
|
||||||
|
|
||||||
|
memset(ntbuffer+16, 0, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
calc_resp(ntbuffer, nonce, ntresp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
free(pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
|
||||||
|
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
|
||||||
|
(((x) >>16)&0xff), ((x)>>24)
|
||||||
|
|
||||||
|
/* this is for creating ntlm header output */
|
||||||
|
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||||
|
bool proxy)
|
||||||
|
{
|
||||||
|
const char *domain=""; /* empty */
|
||||||
|
const char *host=""; /* empty */
|
||||||
|
int domlen=strlen(domain);
|
||||||
|
int hostlen = strlen(host);
|
||||||
|
int hostoff; /* host name offset */
|
||||||
|
int domoff; /* domain name offset */
|
||||||
|
int size;
|
||||||
|
char *base64=NULL;
|
||||||
|
unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */
|
||||||
|
|
||||||
|
/* point to the address of the pointer that holds the string to sent to the
|
||||||
|
server, which is for a plain host or for a HTTP proxy */
|
||||||
|
char **allocuserpwd;
|
||||||
|
|
||||||
|
/* point to the name and password for this */
|
||||||
|
char *userp;
|
||||||
|
char *passwdp;
|
||||||
|
/* point to the correct struct with this */
|
||||||
|
struct ntlmdata *ntlm;
|
||||||
|
|
||||||
|
if(proxy) {
|
||||||
|
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||||
|
userp = conn->proxyuser;
|
||||||
|
passwdp = conn->proxypasswd;
|
||||||
|
ntlm = &conn->proxyntlm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allocuserpwd = &conn->allocptr.userpwd;
|
||||||
|
userp = conn->user;
|
||||||
|
passwdp = conn->passwd;
|
||||||
|
ntlm = &conn->ntlm;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ntlm->state) {
|
||||||
|
case NTLMSTATE_TYPE1:
|
||||||
|
default: /* for the weird cases we (re)start here */
|
||||||
|
hostoff = 32;
|
||||||
|
domoff = hostoff + hostlen;
|
||||||
|
|
||||||
|
/* Create and send a type-1 message:
|
||||||
|
|
||||||
|
Index Description Content
|
||||||
|
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||||
|
(0x4e544c4d53535000)
|
||||||
|
8 NTLM Message Type long (0x01000000)
|
||||||
|
12 Flags long
|
||||||
|
16 Supplied Domain security buffer(*)
|
||||||
|
24 Supplied Workstation security buffer(*)
|
||||||
|
32 start of data block
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
|
||||||
|
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||||
|
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||||
|
"%c%c" /* domain length */
|
||||||
|
"%c%c" /* domain allocated space */
|
||||||
|
"%c%c" /* domain name offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
"%c%c" /* host length */
|
||||||
|
"%c%c" /* host allocated space */
|
||||||
|
"%c%c" /* host name offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
"%s" /* host name */
|
||||||
|
"%s", /* domain string */
|
||||||
|
0, /* trailing zero */
|
||||||
|
0,0,0, /* part of type-1 long */
|
||||||
|
|
||||||
|
LONGQUARTET(
|
||||||
|
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
||||||
|
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
||||||
|
/* equals 0x0202 */
|
||||||
|
),
|
||||||
|
SHORTPAIR(domlen),
|
||||||
|
SHORTPAIR(domlen),
|
||||||
|
SHORTPAIR(domoff),
|
||||||
|
0,0,
|
||||||
|
SHORTPAIR(hostlen),
|
||||||
|
SHORTPAIR(hostlen),
|
||||||
|
SHORTPAIR(hostoff),
|
||||||
|
0,0,
|
||||||
|
host, domain);
|
||||||
|
|
||||||
|
/* initial packet length */
|
||||||
|
size = 32 + hostlen + domlen;
|
||||||
|
|
||||||
|
/* now keeper of the base64 encoded package size */
|
||||||
|
size = Curl_base64_encode(ntlmbuf, size, &base64);
|
||||||
|
|
||||||
|
if(size >0 ) {
|
||||||
|
Curl_safefree(*allocuserpwd);
|
||||||
|
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||||
|
proxy?"Proxy-":"",
|
||||||
|
base64);
|
||||||
|
free(base64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NTLMSTATE_TYPE2:
|
||||||
|
/* We received the type-2 already, create a type-3 message:
|
||||||
|
|
||||||
|
Index Description Content
|
||||||
|
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||||
|
(0x4e544c4d53535000)
|
||||||
|
8 NTLM Message Type long (0x03000000)
|
||||||
|
12 LM/LMv2 Response security buffer(*)
|
||||||
|
20 NTLM/NTLMv2 Response security buffer(*)
|
||||||
|
28 Domain Name security buffer(*)
|
||||||
|
36 User Name security buffer(*)
|
||||||
|
44 Workstation Name security buffer(*)
|
||||||
|
(52) Session Key (optional) security buffer(*)
|
||||||
|
(60) Flags (optional) long
|
||||||
|
52 (64) start of data block
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
int lmrespoff;
|
||||||
|
int ntrespoff;
|
||||||
|
int useroff;
|
||||||
|
unsigned char lmresp[0x18]; /* fixed-size */
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
unsigned char ntresp[0x18]; /* fixed-size */
|
||||||
|
#endif
|
||||||
|
const char *user;
|
||||||
|
int userlen;
|
||||||
|
|
||||||
|
user = strchr(userp, '\\');
|
||||||
|
if(!user)
|
||||||
|
user = strchr(userp, '/');
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
domain = userp;
|
||||||
|
domlen = user - domain;
|
||||||
|
user++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
user = userp;
|
||||||
|
userlen = strlen(user);
|
||||||
|
|
||||||
|
mkhash(passwdp, &ntlm->nonce[0], lmresp
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
, ntresp
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
domoff = 64; /* always */
|
||||||
|
useroff = domoff + domlen;
|
||||||
|
hostoff = useroff + userlen;
|
||||||
|
lmrespoff = hostoff + hostlen;
|
||||||
|
ntrespoff = lmrespoff + 0x18;
|
||||||
|
|
||||||
|
/* Create the big type-3 message binary blob */
|
||||||
|
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
||||||
|
"NTLMSSP%c"
|
||||||
|
"\x03%c%c%c" /* type-3, 32 bits */
|
||||||
|
|
||||||
|
"%c%c%c%c" /* LanManager length + allocated space */
|
||||||
|
"%c%c" /* LanManager offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"%c%c" /* NT-response length */
|
||||||
|
"%c%c" /* NT-response allocated space */
|
||||||
|
"%c%c" /* NT-response offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"%c%c" /* domain length */
|
||||||
|
"%c%c" /* domain allocated space */
|
||||||
|
"%c%c" /* domain name offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"%c%c" /* user length */
|
||||||
|
"%c%c" /* user allocated space */
|
||||||
|
"%c%c" /* user offset */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"%c%c" /* host length */
|
||||||
|
"%c%c" /* host allocated space */
|
||||||
|
"%c%c" /* host offset */
|
||||||
|
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||||
|
|
||||||
|
"\xff\xff" /* message length */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"\x01\x82" /* flags */
|
||||||
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
/* domain string */
|
||||||
|
/* user string */
|
||||||
|
/* host string */
|
||||||
|
/* LanManager response */
|
||||||
|
/* NT response */
|
||||||
|
,
|
||||||
|
0, /* zero termination */
|
||||||
|
0,0,0, /* type-3 long, the 24 upper bits */
|
||||||
|
|
||||||
|
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||||
|
SHORTPAIR(0x18),
|
||||||
|
SHORTPAIR(lmrespoff),
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||||
|
SHORTPAIR(0x18),
|
||||||
|
#else
|
||||||
|
0x0, 0x0,
|
||||||
|
0x0, 0x0,
|
||||||
|
#endif
|
||||||
|
SHORTPAIR(ntrespoff),
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
|
SHORTPAIR(domlen),
|
||||||
|
SHORTPAIR(domlen),
|
||||||
|
SHORTPAIR(domoff),
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
|
SHORTPAIR(userlen),
|
||||||
|
SHORTPAIR(userlen),
|
||||||
|
SHORTPAIR(useroff),
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
|
SHORTPAIR(hostlen),
|
||||||
|
SHORTPAIR(hostlen),
|
||||||
|
SHORTPAIR(hostoff),
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0);
|
||||||
|
|
||||||
|
/* size is now 64 */
|
||||||
|
size=64;
|
||||||
|
ntlmbuf[62]=ntlmbuf[63]=0;
|
||||||
|
|
||||||
|
memcpy(&ntlmbuf[size], domain, domlen);
|
||||||
|
size += domlen;
|
||||||
|
|
||||||
|
memcpy(&ntlmbuf[size], user, userlen);
|
||||||
|
size += userlen;
|
||||||
|
|
||||||
|
/* we append the binary hashes to the end of the blob */
|
||||||
|
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||||
|
memcpy(&ntlmbuf[size], lmresp, 0x18);
|
||||||
|
size += 0x18;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_NTRESPONSES
|
||||||
|
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||||
|
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
||||||
|
size += 0x18;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ntlmbuf[56] = size & 0xff;
|
||||||
|
ntlmbuf[57] = size >> 8;
|
||||||
|
|
||||||
|
/* convert the binary blob into base64 */
|
||||||
|
size = Curl_base64_encode(ntlmbuf, size, &base64);
|
||||||
|
|
||||||
|
if(size >0 ) {
|
||||||
|
Curl_safefree(*allocuserpwd);
|
||||||
|
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||||
|
proxy?"Proxy-":"",
|
||||||
|
base64);
|
||||||
|
free(base64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||||
|
|
||||||
|
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NTLMSTATE_TYPE3:
|
||||||
|
/* connection is already authenticated,
|
||||||
|
* don't send a header in future requests */
|
||||||
|
if(*allocuserpwd) {
|
||||||
|
free(*allocuserpwd);
|
||||||
|
*allocuserpwd=NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
#endif /* !CURL_DISABLE_HTTP */
|
143
lib/http_ntlm.h
Normal file
143
lib/http_ntlm.h
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#ifndef __HTTP_NTLM_H
|
||||||
|
#define __HTTP_NTLM_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CURLNTLM_NONE, /* not a ntlm */
|
||||||
|
CURLNTLM_BAD, /* an ntlm, but one we don't like */
|
||||||
|
CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */
|
||||||
|
CURLNTLM_FINE, /* an ntlm we act on */
|
||||||
|
|
||||||
|
CURLNTLM_LAST /* last entry in this enum, don't use */
|
||||||
|
} CURLntlm;
|
||||||
|
|
||||||
|
/* this is for ntlm header input */
|
||||||
|
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||||
|
|
||||||
|
/* this is for creating ntlm header output */
|
||||||
|
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||||
|
|
||||||
|
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
||||||
|
|
||||||
|
|
||||||
|
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
|
||||||
|
/* Indicates that Unicode strings are supported for use in security buffer
|
||||||
|
data. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
|
||||||
|
/* Indicates that OEM strings are supported for use in security buffer data. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_REQUEST_TARGET (1<<2)
|
||||||
|
/* Requests that the server's authentication realm be included in the Type 2
|
||||||
|
message. */
|
||||||
|
|
||||||
|
/* unknown (1<<3) */
|
||||||
|
#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
|
||||||
|
/* Specifies that authenticated communication between the client and server
|
||||||
|
should carry a digital signature (message integrity). */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
|
||||||
|
/* Specifies that authenticated communication between the client and server
|
||||||
|
should be encrypted (message confidentiality). */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
|
||||||
|
/* Indicates that the LAN Manager session key should be used for signing and
|
||||||
|
sealing authenticated communications. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
|
||||||
|
/* Indicates that NTLM authentication is being used. */
|
||||||
|
|
||||||
|
/* unknown (1<<10) */
|
||||||
|
/* unknown (1<<11) */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
|
||||||
|
/* Sent by the client in the Type 1 message to indicate that a desired
|
||||||
|
authentication realm is included in the message. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
|
||||||
|
/* Sent by the client in the Type 1 message to indicate that the client
|
||||||
|
workstation's name is included in the message. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
|
||||||
|
/* Sent by the server to indicate that the server and client are on the same
|
||||||
|
machine. Implies that the client may use a pre-established local security
|
||||||
|
context rather than responding to the challenge. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
|
||||||
|
/* Indicates that authenticated communication between the client and server
|
||||||
|
should be signed with a "dummy" signature. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
|
||||||
|
/* Sent by the server in the Type 2 message to indicate that the target
|
||||||
|
authentication realm is a domain. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
|
||||||
|
/* Sent by the server in the Type 2 message to indicate that the target
|
||||||
|
authentication realm is a server. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
|
||||||
|
/* Sent by the server in the Type 2 message to indicate that the target
|
||||||
|
authentication realm is a share. Presumably, this is for share-level
|
||||||
|
authentication. Usage is unclear. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
|
||||||
|
/* Indicates that the NTLM2 signing and sealing scheme should be used for
|
||||||
|
protecting authenticated communications. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
|
||||||
|
/* Sent by the server in the Type 2 message to indicate that it is including a
|
||||||
|
Target Information block in the message. */
|
||||||
|
|
||||||
|
/* unknown (1<24) */
|
||||||
|
/* unknown (1<25) */
|
||||||
|
/* unknown (1<26) */
|
||||||
|
/* unknown (1<27) */
|
||||||
|
/* unknown (1<28) */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_128 (1<<29)
|
||||||
|
/* Indicates that 128-bit encryption is supported. */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
|
||||||
|
/* unknown purpose */
|
||||||
|
|
||||||
|
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
|
||||||
|
/* Indicates that 56-bit encryption is supported. */
|
||||||
|
#endif
|
@@ -73,10 +73,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#define IOCTL_3_ARGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SYS_ERROR -1
|
#define SYS_ERROR -1
|
||||||
|
|
||||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||||
|
@@ -64,7 +64,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
|
|
||||||
save = Curl_set_command_prot(conn, prot_private);
|
save = Curl_set_command_prot(conn, prot_private);
|
||||||
|
|
||||||
result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user);
|
result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -363,7 +363,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
|
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
des_string_to_key (conn->data->state.passwd, &key);
|
des_string_to_key (conn->passwd, &key);
|
||||||
des_key_sched(&key, schedule);
|
des_key_sched(&key, schedule);
|
||||||
|
|
||||||
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
||||||
|
@@ -74,7 +74,7 @@ static void DynaOpen(void)
|
|||||||
* liblber.so automatically, but since it does not we will
|
* liblber.so automatically, but since it does not we will
|
||||||
* handle it here by opening liblber.so as global.
|
* handle it here by opening liblber.so as global.
|
||||||
*/
|
*/
|
||||||
dlopen("liblber.so",
|
liblber = dlopen("liblber.so",
|
||||||
#ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
|
#ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
|
||||||
RTLD_LAZY_GLOBAL
|
RTLD_LAZY_GLOBAL
|
||||||
#else
|
#else
|
||||||
@@ -178,8 +178,8 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
|||||||
status = CURLE_COULDNT_CONNECT;
|
status = CURLE_COULDNT_CONNECT;
|
||||||
} else {
|
} else {
|
||||||
rc = ldap_simple_bind_s(server,
|
rc = ldap_simple_bind_s(server,
|
||||||
conn->bits.user_passwd?data->state.user:NULL,
|
conn->bits.user_passwd?conn->user:NULL,
|
||||||
conn->bits.user_passwd?data->state.passwd:NULL);
|
conn->bits.user_passwd?conn->passwd:NULL);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||||
status = CURLE_LDAP_CANNOT_BIND;
|
status = CURLE_LDAP_CANNOT_BIND;
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "llist.h"
|
#include "llist.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
157
lib/makefile.dj
Normal file
157
lib/makefile.dj
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#
|
||||||
|
# Adapted for djgpp2 / Watt-32 / DOS by
|
||||||
|
# Gisle Vanem <giva@bgnett.no>
|
||||||
|
#
|
||||||
|
|
||||||
|
DEPEND_PREREQ = config.h getdate.c
|
||||||
|
|
||||||
|
include ../packages/DOS/common.dj
|
||||||
|
|
||||||
|
ifeq ($(USE_SSL),1)
|
||||||
|
CFLAGS += -I$(OPENSSL_ROOT)
|
||||||
|
endif
|
||||||
|
|
||||||
|
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
|
||||||
|
easy.c escape.c file.c formdata.c ftp.c \
|
||||||
|
getdate.c getenv.c getinfo.c getpass.c hash.c \
|
||||||
|
hostip.c http.c http_chu.c if2ip.c krb4.c \
|
||||||
|
ldap.c llist.c memdebug.c mprintf.c multi.c \
|
||||||
|
netrc.c progress.c security.c sendf.c share.c \
|
||||||
|
speedche.c ssluse.c strequal.c strtok.c telnet.c \
|
||||||
|
timeval.c transfer.c url.c version.c
|
||||||
|
|
||||||
|
OBJECTS = $(SOURCES:.c=.o)
|
||||||
|
CURL_LIB = libcurl.a
|
||||||
|
|
||||||
|
all: config.h $(CURL_LIB)
|
||||||
|
|
||||||
|
$(CURL_LIB): $(OBJECTS)
|
||||||
|
ar rs $@ $?
|
||||||
|
|
||||||
|
config.h: config.dj
|
||||||
|
@echo '#include "./config.dj"' > $@
|
||||||
|
|
||||||
|
getdate.c: getdate.y
|
||||||
|
$(YACC) -o $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
- rm -f $(OBJECTS) $(CURL_LIB) Makefile.bak config.h getdate.c
|
||||||
|
|
||||||
|
# DO NOT DELETE THIS LINE
|
||||||
|
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
|
||||||
|
base64.h
|
||||||
|
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h sendf.h if2ip.h
|
||||||
|
content_.o: content_.c setup.h config.h config.dj
|
||||||
|
cookie.o: cookie.c setup.h config.h config.dj cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h getdate.h strequal.h strtok.h
|
||||||
|
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
|
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h transfer.h ssluse.h url.h getinfo.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
|
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
|
||||||
|
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h progress.h sendf.h escape.h ../include/curl/mprintf.h
|
||||||
|
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h strequal.h
|
||||||
|
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
|
||||||
|
strequal.h ssluse.h connect.h ../include/curl/mprintf.h
|
||||||
|
getdate.o: getdate.c setup.h config.h config.dj getdate.h
|
||||||
|
getenv.o: getenv.c setup.h config.h config.dj
|
||||||
|
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h
|
||||||
|
getpass.o: getpass.c setup.h config.h config.dj
|
||||||
|
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
|
||||||
|
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h sendf.h share.h ../include/curl/mprintf.h
|
||||||
|
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h transfer.h sendf.h progress.h base64.h strequal.h \
|
||||||
|
ssluse.h ../include/curl/mprintf.h
|
||||||
|
http_chu.o: http_chu.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h sendf.h content_encoding.h ../include/curl/mprintf.h
|
||||||
|
if2ip.o: if2ip.c setup.h config.h config.dj
|
||||||
|
krb4.o: krb4.c setup.h config.h config.dj
|
||||||
|
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h sendf.h escape.h transfer.h ../include/curl/mprintf.h
|
||||||
|
llist.o: llist.c setup.h config.h config.dj llist.h
|
||||||
|
memdebug.o: memdebug.c
|
||||||
|
mprintf.o: mprintf.c setup.h config.h config.dj
|
||||||
|
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h transfer.h url.h connect.h progress.h
|
||||||
|
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
strequal.h strtok.h
|
||||||
|
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h sendf.h progress.h ../include/curl/mprintf.h
|
||||||
|
security.o: security.c setup.h config.h config.dj
|
||||||
|
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h sendf.h connect.h ../include/curl/mprintf.h
|
||||||
|
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h share.h
|
||||||
|
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h sendf.h speedcheck.h
|
||||||
|
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h sendf.h url.h
|
||||||
|
strequal.o: strequal.c setup.h config.h config.dj
|
||||||
|
strtok.o: strtok.c setup.h config.h config.dj
|
||||||
|
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h transfer.h sendf.h ../include/curl/mprintf.h \
|
||||||
|
arpa_telnet.h
|
||||||
|
timeval.o: timeval.c timeval.h setup.h config.h config.dj
|
||||||
|
transfer.o: transfer.c setup.h config.h config.dj strequal.h urldata.h \
|
||||||
|
cookie.h ../include/curl/curl.h ../include/curl/types.h \
|
||||||
|
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
|
||||||
|
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
|
||||||
|
transfer.h sendf.h speedcheck.h getpass.h progress.h getdate.h http.h \
|
||||||
|
url.h getinfo.h ssluse.h ../include/curl/mprintf.h
|
||||||
|
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||||
|
hash.h llist.h netrc.h base64.h ssluse.h if2ip.h transfer.h sendf.h \
|
||||||
|
getpass.h progress.h strequal.h escape.h strtok.h share.h \
|
||||||
|
content_encoding.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h \
|
||||||
|
connect.h ca-bundle.h ../include/curl/mprintf.h
|
||||||
|
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||||
|
llist.h
|
356
lib/md5.c
Normal file
356
lib/md5.c
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#ifndef USE_SSLEAY
|
||||||
|
/* This code segment is only used if OpenSSL is not provided, as if it is
|
||||||
|
we use the MD5-function provided there instead. No good duplicating
|
||||||
|
code! */
|
||||||
|
|
||||||
|
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted provided that it
|
||||||
|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
License is also granted to make and use derivative works provided
|
||||||
|
that such works are identified as "derived from the RSA Data
|
||||||
|
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||||
|
mentioning or referencing the derived work.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* UINT4 defines a four byte word */
|
||||||
|
typedef unsigned long int UINT4;
|
||||||
|
|
||||||
|
/* MD5 context. */
|
||||||
|
struct md5_ctx {
|
||||||
|
UINT4 state[4]; /* state (ABCD) */
|
||||||
|
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||||
|
unsigned char buffer[64]; /* input buffer */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct md5_ctx MD5_CTX;
|
||||||
|
|
||||||
|
static void MD5_Init(struct md5_ctx *);
|
||||||
|
static void MD5_Update(struct md5_ctx *, unsigned char *, unsigned int);
|
||||||
|
static void MD5_Final(unsigned char [16], struct md5_ctx *);
|
||||||
|
|
||||||
|
/* Constants for MD5Transform routine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define S11 7
|
||||||
|
#define S12 12
|
||||||
|
#define S13 17
|
||||||
|
#define S14 22
|
||||||
|
#define S21 5
|
||||||
|
#define S22 9
|
||||||
|
#define S23 14
|
||||||
|
#define S24 20
|
||||||
|
#define S31 4
|
||||||
|
#define S32 11
|
||||||
|
#define S33 16
|
||||||
|
#define S34 23
|
||||||
|
#define S41 6
|
||||||
|
#define S42 10
|
||||||
|
#define S43 15
|
||||||
|
#define S44 21
|
||||||
|
|
||||||
|
static void MD5Transform(UINT4 [4], unsigned char [64]);
|
||||||
|
static void Encode(unsigned char *, UINT4 *, unsigned int);
|
||||||
|
static void Decode(UINT4 *, unsigned char *, unsigned int);
|
||||||
|
|
||||||
|
#define MD5_memcpy(dst,src,len) memcpy(dst,src,len)
|
||||||
|
#define MD5_memset(dst,val,len) memset(dst,val,len)
|
||||||
|
|
||||||
|
static unsigned char PADDING[64] = {
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* F, G, H and I are basic MD5 functions.
|
||||||
|
*/
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||||
|
|
||||||
|
/* ROTATE_LEFT rotates x left n bits.
|
||||||
|
*/
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||||
|
Rotation is separate from addition to prevent recomputation.
|
||||||
|
*/
|
||||||
|
#define FF(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define II(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||||
|
*/
|
||||||
|
static void MD5_Init (context)
|
||||||
|
struct md5_ctx *context; /* context */
|
||||||
|
{
|
||||||
|
context->count[0] = context->count[1] = 0;
|
||||||
|
/* Load magic initialization constants.
|
||||||
|
*/
|
||||||
|
context->state[0] = 0x67452301;
|
||||||
|
context->state[1] = 0xefcdab89;
|
||||||
|
context->state[2] = 0x98badcfe;
|
||||||
|
context->state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 block update operation. Continues an MD5 message-digest
|
||||||
|
operation, processing another message block, and updating the
|
||||||
|
context.
|
||||||
|
*/
|
||||||
|
static void MD5_Update (context, input, inputLen)
|
||||||
|
struct md5_ctx *context; /* context */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
{
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Update number of bits */
|
||||||
|
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||||
|
< ((UINT4)inputLen << 3))
|
||||||
|
context->count[1]++;
|
||||||
|
context->count[1] += ((UINT4)inputLen >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
/* Transform as many times as possible. */
|
||||||
|
if (inputLen >= partLen) {
|
||||||
|
MD5_memcpy((void *)&context->buffer[index], (void *)input, partLen);
|
||||||
|
MD5Transform(context->state, context->buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||||
|
MD5Transform(context->state, &input[i]);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
MD5_memcpy((void *)&context->buffer[index], (void *)&input[i],
|
||||||
|
inputLen-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||||
|
the message digest and zeroizing the context.
|
||||||
|
*/
|
||||||
|
static void MD5_Final (digest, context)
|
||||||
|
unsigned char digest[16]; /* message digest */
|
||||||
|
struct md5_ctx *context; /* context */
|
||||||
|
{
|
||||||
|
unsigned char bits[8];
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
/* Save number of bits */
|
||||||
|
Encode (bits, context->count, 8);
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64. */
|
||||||
|
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
MD5_Update (context, PADDING, padLen);
|
||||||
|
|
||||||
|
/* Append length (before padding) */
|
||||||
|
MD5_Update (context, bits, 8);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
Encode (digest, context->state, 16);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
MD5_memset ((void *)context, 0, sizeof (*context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 basic transformation. Transforms state based on block. */
|
||||||
|
static void MD5Transform (state, block)
|
||||||
|
UINT4 state[4];
|
||||||
|
unsigned char block[64];
|
||||||
|
{
|
||||||
|
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
|
Decode (x, block, 64);
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||||
|
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||||
|
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||||
|
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||||
|
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||||
|
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||||
|
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||||
|
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||||
|
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||||
|
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||||
|
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||||
|
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||||
|
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||||
|
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||||
|
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||||
|
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||||
|
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||||
|
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||||
|
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||||
|
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||||
|
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||||
|
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||||
|
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||||
|
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||||
|
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||||
|
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||||
|
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||||
|
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||||
|
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||||
|
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||||
|
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||||
|
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||||
|
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||||
|
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||||
|
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||||
|
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||||
|
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||||
|
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||||
|
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||||
|
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||||
|
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||||
|
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||||
|
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||||
|
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||||
|
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||||
|
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||||
|
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||||
|
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||||
|
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||||
|
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||||
|
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||||
|
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||||
|
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||||
|
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||||
|
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||||
|
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||||
|
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||||
|
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||||
|
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||||
|
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||||
|
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||||
|
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
MD5_memset ((void *)x, 0, sizeof (x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
static void Encode (unsigned char *output,
|
||||||
|
UINT4 *input,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||||
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
|
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
static void Decode (UINT4 *output,
|
||||||
|
unsigned char *input,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||||
|
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* If OpenSSL is present */
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
|
||||||
|
unsigned char *input)
|
||||||
|
{
|
||||||
|
MD5_CTX ctx;
|
||||||
|
MD5_Init(&ctx);
|
||||||
|
MD5_Update(&ctx, input, strlen((char *)input));
|
||||||
|
MD5_Final(outbuffer, &ctx);
|
||||||
|
}
|
@@ -1,31 +1,29 @@
|
|||||||
#ifndef __CA_BUNDLE_H
|
#ifndef __MD5_H
|
||||||
#define __CA_BUNDLE_H
|
#define __MD5_H
|
||||||
/*****************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* In order to be useful for every potential user, curl and libcurl are
|
* This software is licensed as described in the file COPYING, which
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
* licenses. You may pick one of these licenses.
|
|
||||||
*
|
*
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*****************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
void Curl_md5it(unsigned char *output,
|
||||||
|
unsigned char *input);
|
||||||
|
|
||||||
#ifndef CURL_CA_BUNDLE
|
|
||||||
/* Set this to the full path file name of the ca cert bundle */
|
|
||||||
#undef CURL_CA_BUNDLE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __CA_BUNDLE_H */
|
|
@@ -1,4 +1,4 @@
|
|||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
@@ -220,4 +220,4 @@ int curl_fclose(FILE *file, int line, const char *source)
|
|||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
int VOID_VAR_MEMDEBUG;
|
int VOID_VAR_MEMDEBUG;
|
||||||
#endif
|
#endif
|
||||||
#endif /* MALLOCDEBUG */
|
#endif /* CURLDEBUG */
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
17
lib/multi.c
17
lib/multi.c
@@ -31,6 +31,9 @@
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
@@ -38,9 +41,10 @@
|
|||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
|
#include "progress.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -298,7 +302,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
easy=multi->easy.next;
|
easy=multi->easy.next;
|
||||||
while(easy) {
|
while(easy) {
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
fprintf(stderr, "HANDLE %p: State: %x\n",
|
fprintf(stderr, "HANDLE %p: State: %x\n",
|
||||||
(char *)easy, easy->state);
|
(char *)easy, easy->state);
|
||||||
#endif
|
#endif
|
||||||
@@ -328,6 +332,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Connect. We get a connection identifier filled in. */
|
/* Connect. We get a connection identifier filled in. */
|
||||||
|
Curl_pgrsTime(easy->easy_handle, TIMER_STARTSINGLE);
|
||||||
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
||||||
|
|
||||||
/* after the connect has been sent off, go WAITCONNECT */
|
/* after the connect has been sent off, go WAITCONNECT */
|
||||||
@@ -435,8 +440,9 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
|
|
||||||
/* When we follow redirects, must to go back to the CONNECT state */
|
/* When we follow redirects, must to go back to the CONNECT state */
|
||||||
if(easy->easy_conn->newurl) {
|
if(easy->easy_conn->newurl) {
|
||||||
easy->result = Curl_follow(easy->easy_handle,
|
char *newurl = easy->easy_conn->newurl;
|
||||||
strdup(easy->easy_conn->newurl));
|
easy->easy_conn->newurl = NULL;
|
||||||
|
easy->result = Curl_follow(easy->easy_handle, newurl);
|
||||||
if(CURLE_OK == easy->result) {
|
if(CURLE_OK == easy->result) {
|
||||||
easy->state = CURLM_STATE_CONNECT;
|
easy->state = CURLM_STATE_CONNECT;
|
||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
@@ -468,11 +474,12 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(CURLM_STATE_COMPLETED != easy->state) {
|
if(CURLM_STATE_COMPLETED != easy->state) {
|
||||||
if(CURLE_OK != easy->result)
|
if(CURLE_OK != easy->result) {
|
||||||
/*
|
/*
|
||||||
* If an error was returned, and we aren't in completed state now,
|
* If an error was returned, and we aren't in completed state now,
|
||||||
* then we go to completed and consider this transfer aborted. */
|
* then we go to completed and consider this transfer aborted. */
|
||||||
easy->state = CURLM_STATE_COMPLETED;
|
easy->state = CURLM_STATE_COMPLETED;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* this one still lives! */
|
/* this one still lives! */
|
||||||
(*running_handles)++;
|
(*running_handles)++;
|
||||||
|
@@ -46,7 +46,7 @@
|
|||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
|
|
||||||
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
{
|
{
|
||||||
/* This is a hack to allow testing.
|
/* This is a hack to allow testing.
|
||||||
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
||||||
@@ -141,7 +141,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
free(override);
|
free(override);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* MALLOCDEBUG */
|
#endif /* CURLDEBUG */
|
||||||
|
|
||||||
file = fopen(netrcbuffer, "r");
|
file = fopen(netrcbuffer, "r");
|
||||||
if(file) {
|
if(file) {
|
||||||
|
@@ -172,18 +172,20 @@ void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size)
|
|||||||
|
|
||||||
void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size)
|
void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size)
|
||||||
{
|
{
|
||||||
if(size > 0) {
|
|
||||||
data->progress.size_dl = size;
|
data->progress.size_dl = size;
|
||||||
|
if(size > 0)
|
||||||
data->progress.flags |= PGRS_DL_SIZE_KNOWN;
|
data->progress.flags |= PGRS_DL_SIZE_KNOWN;
|
||||||
}
|
else
|
||||||
|
data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size)
|
void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size)
|
||||||
{
|
{
|
||||||
if(size > 0) {
|
|
||||||
data->progress.size_ul = size;
|
data->progress.size_ul = size;
|
||||||
|
if(size > 0)
|
||||||
data->progress.flags |= PGRS_UL_SIZE_KNOWN;
|
data->progress.flags |= PGRS_UL_SIZE_KNOWN;
|
||||||
}
|
else
|
||||||
|
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EXAMPLE OUTPUT to follow:
|
/* EXAMPLE OUTPUT to follow:
|
||||||
|
@@ -60,7 +60,7 @@
|
|||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
64
lib/sendf.c
64
lib/sendf.c
@@ -46,6 +46,7 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
#include "connect.h" /* for the Curl_ourerrno() proto */
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -93,7 +94,6 @@ struct curl_slist *curl_slist_append(struct curl_slist *list,
|
|||||||
new_item->data = strdup(data);
|
new_item->data = strdup(data);
|
||||||
}
|
}
|
||||||
if (new_item == NULL || new_item->data == NULL) {
|
if (new_item == NULL || new_item->data == NULL) {
|
||||||
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +228,8 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
ssize_t *written)
|
ssize_t *written)
|
||||||
{
|
{
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
|
CURLcode retcode;
|
||||||
|
(void)conn;
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
/* SSL_write() is said to return 'int' while write() and send() returns
|
/* SSL_write() is said to return 'int' while write() and send() returns
|
||||||
@@ -242,12 +244,28 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
switch(err) {
|
switch(err) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* this is basicly the EWOULDBLOCK equivalent */
|
/* The operation did not complete; the same TLS/SSL I/O function
|
||||||
|
should be called again later. This is basicly an EWOULDBLOCK
|
||||||
|
equivalent. */
|
||||||
*written = 0;
|
*written = 0;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n", errno);
|
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
||||||
|
Curl_ourerrno());
|
||||||
return CURLE_SEND_ERROR;
|
return CURLE_SEND_ERROR;
|
||||||
|
case SSL_ERROR_SSL:
|
||||||
|
{
|
||||||
|
/* A failure in the SSL library occurred, usually a
|
||||||
|
protocol error. The OpenSSL error queue contains more
|
||||||
|
information on the error. */
|
||||||
|
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||||
|
120 bytes long. */
|
||||||
|
int sslerror = ERR_get_error();
|
||||||
|
failf(conn->data, "SSL_write() error: %s\n",
|
||||||
|
ERR_error_string(sslerror, error_buffer));
|
||||||
|
return CURLE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* a true error */
|
/* a true error */
|
||||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
failf(conn->data, "SSL_write() return error %d\n", err);
|
||||||
@@ -267,27 +285,31 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
bytes_written = swrite(sockfd, mem, len);
|
bytes_written = swrite(sockfd, mem, len);
|
||||||
}
|
}
|
||||||
if(-1 == bytes_written) {
|
if(-1 == bytes_written) {
|
||||||
#ifdef WIN32
|
int err = Curl_ourerrno();
|
||||||
if(WSAEWOULDBLOCK == GetLastError())
|
|
||||||
|
if(
|
||||||
|
#ifdef WSAEWOULDBLOCK
|
||||||
|
/* This is how Windows does it */
|
||||||
|
(WSAEWOULDBLOCK == err)
|
||||||
#else
|
#else
|
||||||
/* As pointed out by Christophe Demory on March 11 2003, errno
|
/* As pointed out by Christophe Demory on March 11 2003, errno
|
||||||
may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||||
due to its inability to send off data without blocking. We
|
due to its inability to send off data without blocking. We
|
||||||
therefor treat both error codes the same here */
|
therefor treat both error codes the same here */
|
||||||
if((EWOULDBLOCK == errno) || (EAGAIN == errno))
|
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
|
||||||
#endif
|
#endif
|
||||||
{
|
)
|
||||||
/* this is just a case of EWOULDBLOCK */
|
/* this is just a case of EWOULDBLOCK */
|
||||||
*written=0;
|
bytes_written=0;
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*written = bytes_written;
|
*written = bytes_written;
|
||||||
return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
||||||
|
|
||||||
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* client_write() sends data to the write callback(s)
|
/* client_write() sends data to the write callback(s)
|
||||||
@@ -345,6 +367,7 @@ int Curl_read(struct connectdata *conn,
|
|||||||
ssize_t *n)
|
ssize_t *n)
|
||||||
{
|
{
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
(void)conn;
|
||||||
*n=0; /* reset amount to zero */
|
*n=0; /* reset amount to zero */
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
@@ -363,6 +386,17 @@ int Curl_read(struct connectdata *conn,
|
|||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* there's data pending, re-invoke SSL_read() */
|
/* there's data pending, re-invoke SSL_read() */
|
||||||
return -1; /* basicly EWOULDBLOCK */
|
return -1; /* basicly EWOULDBLOCK */
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
/* openssl/ssl.h says "look at error stack/return value/errno" */
|
||||||
|
{
|
||||||
|
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||||
|
120 bytes long. */
|
||||||
|
int sslerror = ERR_get_error();
|
||||||
|
failf(conn->data, "SSL read: %s, errno %d",
|
||||||
|
ERR_error_string(sslerror, error_buffer),
|
||||||
|
Curl_ourerrno() );
|
||||||
|
}
|
||||||
|
return CURLE_RECV_ERROR;
|
||||||
default:
|
default:
|
||||||
failf(conn->data, "SSL read error: %d", err);
|
failf(conn->data, "SSL read error: %d", err);
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
@@ -379,10 +413,11 @@ int Curl_read(struct connectdata *conn,
|
|||||||
nread = sread (sockfd, buf, buffersize);
|
nread = sread (sockfd, buf, buffersize);
|
||||||
|
|
||||||
if(-1 == nread) {
|
if(-1 == nread) {
|
||||||
|
int err = Curl_ourerrno();
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(WSAEWOULDBLOCK == GetLastError())
|
if(WSAEWOULDBLOCK == err)
|
||||||
#else
|
#else
|
||||||
if(EWOULDBLOCK == errno)
|
if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -408,6 +443,7 @@ int Curl_debug(struct SessionHandle *data, curl_infotype type,
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case CURLINFO_TEXT:
|
case CURLINFO_TEXT:
|
||||||
case CURLINFO_HEADER_OUT:
|
case CURLINFO_HEADER_OUT:
|
||||||
|
case CURLINFO_HEADER_IN:
|
||||||
fwrite(s_infotype[type], 2, 1, data->set.err);
|
fwrite(s_infotype[type], 2, 1, data->set.err);
|
||||||
fwrite(ptr, size, 1, data->set.err);
|
fwrite(ptr, size, 1, data->set.err);
|
||||||
break;
|
break;
|
||||||
|
24
lib/setup.h
24
lib/setup.h
@@ -135,20 +135,40 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
|||||||
#define HAVE_ALARM
|
#define HAVE_ALARM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PATH_CHAR ";"
|
|
||||||
#define DIR_CHAR "\\"
|
#define DIR_CHAR "\\"
|
||||||
#define DOT_CHAR "_"
|
#define DOT_CHAR "_"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#define sclose(x) close_s(x)
|
||||||
|
#define sread(x,y,z) read_s(x,y,z)
|
||||||
|
#define swrite(x,y,z) write_s(x,y,z)
|
||||||
|
#define select(n,r,w,x,t) select_s(n,r,w,x,t)
|
||||||
|
#define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
|
||||||
|
#define IOCTL_3_ARGS
|
||||||
|
#include <tcp.h>
|
||||||
|
#ifdef word
|
||||||
|
#undef word
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define sclose(x) close(x)
|
#define sclose(x) close(x)
|
||||||
#define sread(x,y,z) recv(x,y,z,0)
|
#define sread(x,y,z) recv(x,y,z,0)
|
||||||
#define swrite(x,y,z) send(x,y,z,0)
|
#define swrite(x,y,z) send(x,y,z,0)
|
||||||
#define HAVE_ALARM
|
#define HAVE_ALARM
|
||||||
|
|
||||||
#define PATH_CHAR ":"
|
#endif
|
||||||
|
|
||||||
#define DIR_CHAR "/"
|
#define DIR_CHAR "/"
|
||||||
#define DOT_CHAR "."
|
#define DOT_CHAR "."
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#undef DOT_CHAR
|
||||||
|
#define DOT_CHAR "_"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_STRCASECMP
|
#ifdef HAVE_STRCASECMP
|
||||||
/* this is for "-ansi -Wall -pedantic" to stop complaining! */
|
/* this is for "-ansi -Wall -pedantic" to stop complaining! */
|
||||||
extern int (strcasecmp)(const char *s1, const char *s2);
|
extern int (strcasecmp)(const char *s1, const char *s2);
|
||||||
|
@@ -24,12 +24,13 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
47
lib/ssluse.c
47
lib/ssluse.c
@@ -46,7 +46,7 @@
|
|||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -697,6 +697,7 @@ static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ====================================================== */
|
/* ====================================================== */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
static int
|
static int
|
||||||
cert_hostcheck(const char *certname, const char *hostname)
|
cert_hostcheck(const char *certname, const char *hostname)
|
||||||
{
|
{
|
||||||
@@ -733,6 +734,7 @@ cert_hostcheck(const char *certname, const char *hostname)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ====================================================== */
|
/* ====================================================== */
|
||||||
CURLcode
|
CURLcode
|
||||||
@@ -784,6 +786,16 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* OpenSSL contains code to work-around lots of bugs and flaws in various
|
||||||
|
SSL-implementations. SSL_CTX_set_options() is used to enabled those
|
||||||
|
work-arounds. The man page for this option states that SSL_OP_ALL enables
|
||||||
|
ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to
|
||||||
|
enable the bug workaround options if compatibility with somewhat broken
|
||||||
|
implementations is desired."
|
||||||
|
|
||||||
|
*/
|
||||||
|
SSL_CTX_set_options(conn->ssl.ctx, SSL_OP_ALL);
|
||||||
|
|
||||||
if(data->set.cert) {
|
if(data->set.cert) {
|
||||||
if (!cert_stuff(conn,
|
if (!cert_stuff(conn,
|
||||||
data->set.cert,
|
data->set.cert,
|
||||||
@@ -803,7 +815,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.ssl.verifypeer){
|
if(data->set.ssl.verifypeer) {
|
||||||
SSL_CTX_set_verify(conn->ssl.ctx,
|
SSL_CTX_set_verify(conn->ssl.ctx,
|
||||||
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
|
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
|
||||||
SSL_VERIFY_CLIENT_ONCE,
|
SSL_VERIFY_CLIENT_ONCE,
|
||||||
@@ -819,6 +831,15 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
else
|
else
|
||||||
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
|
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
|
||||||
|
|
||||||
|
/* give application a chance to interfere with SSL set up. */
|
||||||
|
if (data->set.ssl.fsslctx) {
|
||||||
|
retcode = (*data->set.ssl.fsslctx)(data, conn->ssl.ctx,
|
||||||
|
data->set.ssl.fsslctxp);
|
||||||
|
if (retcode) {
|
||||||
|
failf(data,"error signaled by ssl ctx callback");
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lets make an SSL structure */
|
/* Lets make an SSL structure */
|
||||||
conn->ssl.handle = SSL_new (conn->ssl.ctx);
|
conn->ssl.handle = SSL_new (conn->ssl.ctx);
|
||||||
@@ -900,9 +921,28 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
/* untreated error */
|
/* untreated error */
|
||||||
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||||
120 bytes long. */
|
120 bytes long. */
|
||||||
|
|
||||||
|
detail = ERR_get_error(); /* Gets the earliest error code from the
|
||||||
|
thread's error queue and removes the
|
||||||
|
entry. */
|
||||||
|
|
||||||
|
switch(detail) {
|
||||||
|
case 0x1407E086:
|
||||||
|
/* 1407E086:
|
||||||
|
SSL routines:
|
||||||
|
SSL2_SET_CERTIFICATE:
|
||||||
|
certificate verify failed */
|
||||||
|
case 0x14090086:
|
||||||
|
/* 14090086:
|
||||||
|
SSL routines:
|
||||||
|
SSL3_GET_SERVER_CERTIFICATE:
|
||||||
|
certificate verify failed */
|
||||||
|
failf(data,
|
||||||
|
"SSL certificate problem, verify that the CA cert is OK");
|
||||||
|
return CURLE_SSL_CACERT;
|
||||||
|
default:
|
||||||
/* detail is already set to the SSL error above */
|
/* detail is already set to the SSL error above */
|
||||||
failf(data, "SSL: %s", ERR_error_string(detail, error_buffer));
|
failf(data, "SSL: %s", ERR_error_string(detail, error_buffer));
|
||||||
|
|
||||||
/* OpenSSL 0.9.6 and later has a function named
|
/* OpenSSL 0.9.6 and later has a function named
|
||||||
ERRO_error_string_n() that takes the size of the buffer as a third
|
ERRO_error_string_n() that takes the size of the buffer as a third
|
||||||
argument, and we should possibly switch to using that one in the
|
argument, and we should possibly switch to using that one in the
|
||||||
@@ -910,6 +950,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* we have been connected fine, get out of the connect loop */
|
/* we have been connected fine, get out of the connect loop */
|
||||||
break;
|
break;
|
||||||
|
@@ -45,7 +45,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -84,7 +83,7 @@
|
|||||||
#include "arpa_telnet.h"
|
#include "arpa_telnet.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -756,7 +755,7 @@ static int check_telnet_options(struct connectdata *conn)
|
|||||||
if(conn->bits.user_passwd)
|
if(conn->bits.user_passwd)
|
||||||
{
|
{
|
||||||
char *buf = malloc(256);
|
char *buf = malloc(256);
|
||||||
sprintf(buf, "USER,%s", data->state.user);
|
sprintf(buf, "USER,%s", conn->user);
|
||||||
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
|
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
|
||||||
|
|
||||||
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
||||||
|
386
lib/transfer.c
386
lib/transfer.c
@@ -46,7 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -95,12 +94,15 @@
|
|||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "getinfo.h"
|
#include "getinfo.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_ntlm.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -284,6 +286,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* header line within buffer loop */
|
/* header line within buffer loop */
|
||||||
do {
|
do {
|
||||||
int hbufp_index;
|
int hbufp_index;
|
||||||
|
int rest_length;
|
||||||
|
int full_length;
|
||||||
|
int writetype;
|
||||||
|
|
||||||
/* str_start is start of line within buf */
|
/* str_start is start of line within buf */
|
||||||
k->str_start = k->str;
|
k->str_start = k->str;
|
||||||
@@ -325,22 +330,24 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
break; /* read more and try again */
|
break; /* read more and try again */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrease the size of the remaining buffer */
|
/* decrease the size of the remaining (supposed) header line */
|
||||||
nread -= (k->end_ptr - k->str)+1;
|
rest_length = (k->end_ptr - k->str)+1;
|
||||||
|
nread -= rest_length;
|
||||||
|
|
||||||
k->str = k->end_ptr + 1; /* move past new line */
|
k->str = k->end_ptr + 1; /* move past new line */
|
||||||
|
|
||||||
|
full_length = k->str - k->str_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're about to copy a chunk of data to the end of the
|
* We're about to copy a chunk of data to the end of the
|
||||||
* already received header. We make sure that the full string
|
* already received header. We make sure that the full string
|
||||||
* fit in the allocated header buffer, or else we enlarge
|
* fit in the allocated header buffer, or else we enlarge
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
if (k->hbuflen + (k->str - k->str_start) >=
|
if (k->hbuflen + full_length >=
|
||||||
data->state.headersize) {
|
data->state.headersize) {
|
||||||
char *newbuff;
|
char *newbuff;
|
||||||
long newsize=MAX((k->hbuflen+
|
long newsize=MAX((k->hbuflen+full_length)*3/2,
|
||||||
(k->str-k->str_start))*3/2,
|
|
||||||
data->state.headersize*2);
|
data->state.headersize*2);
|
||||||
hbufp_index = k->hbufp - data->state.headerbuff;
|
hbufp_index = k->hbufp - data->state.headerbuff;
|
||||||
newbuff = (char *)realloc(data->state.headerbuff, newsize);
|
newbuff = (char *)realloc(data->state.headerbuff, newsize);
|
||||||
@@ -354,10 +361,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy to end of line */
|
/* copy to end of line */
|
||||||
strncpy (k->hbufp, k->str_start, k->str - k->str_start);
|
strncpy (k->hbufp, k->str_start, full_length);
|
||||||
k->hbufp += k->str - k->str_start;
|
k->hbufp += full_length;
|
||||||
k->hbuflen += k->str - k->str_start;
|
k->hbuflen += full_length;
|
||||||
*k->hbufp = 0;
|
*k->hbufp = 0;
|
||||||
|
k->end_ptr = k->hbufp;
|
||||||
|
|
||||||
k->p = data->state.headerbuff;
|
k->p = data->state.headerbuff;
|
||||||
|
|
||||||
@@ -371,7 +379,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
!checkhttpprefix(data, data->state.headerbuff)) {
|
!checkhttpprefix(data, data->state.headerbuff)) {
|
||||||
/* this is not the beginning of a HTTP first header line */
|
/* this is not the beginning of a HTTP first header line */
|
||||||
k->header = FALSE;
|
k->header = FALSE;
|
||||||
|
if(nread)
|
||||||
|
/* since there's more, this is a partial bad header */
|
||||||
k->badheader = HEADER_PARTHEADER;
|
k->badheader = HEADER_PARTHEADER;
|
||||||
|
else {
|
||||||
|
/* this was all we read so its all a bad header */
|
||||||
|
k->badheader = HEADER_ALLBAD;
|
||||||
|
nread = rest_length;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,13 +436,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
|
|
||||||
/* now, only output this if the header AND body are requested:
|
/* now, only output this if the header AND body are requested:
|
||||||
*/
|
*/
|
||||||
k->writetype = CLIENTWRITE_HEADER;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
if (data->set.http_include_header)
|
if (data->set.http_include_header)
|
||||||
k->writetype |= CLIENTWRITE_BODY;
|
writetype |= CLIENTWRITE_BODY;
|
||||||
|
|
||||||
headerlen = k->p - data->state.headerbuff;
|
headerlen = k->p - data->state.headerbuff;
|
||||||
|
|
||||||
result = Curl_client_write(data, k->writetype,
|
result = Curl_client_write(data, writetype,
|
||||||
data->state.headerbuff,
|
data->state.headerbuff,
|
||||||
headerlen);
|
headerlen);
|
||||||
if(result)
|
if(result)
|
||||||
@@ -445,11 +460,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
if(data->set.no_body)
|
if(data->set.no_body)
|
||||||
stop_reading = TRUE;
|
stop_reading = TRUE;
|
||||||
else if(!conn->bits.close) {
|
else {
|
||||||
/* If this is not the last request before a close, we must
|
/* If we know the expected size of this document, we set the
|
||||||
set the maximum download size to the size of the
|
maximum download size to the size of the expected
|
||||||
expected document or else, we won't know when to stop
|
document or else, we won't know when to stop reading!
|
||||||
reading! */
|
|
||||||
|
Note that we set the download maximum even if we read a
|
||||||
|
"Connection: close" header, to make sure that
|
||||||
|
"Content-Length: 0" still prevents us from attempting to
|
||||||
|
read the (missing) response-body.
|
||||||
|
*/
|
||||||
if(-1 != conn->size)
|
if(-1 != conn->size)
|
||||||
conn->maxdownload = conn->size;
|
conn->maxdownload = conn->size;
|
||||||
}
|
}
|
||||||
@@ -519,7 +539,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* If we have been told to fail hard on HTTP-errors,
|
/* If we have been told to fail hard on HTTP-errors,
|
||||||
here is the check for that: */
|
here is the check for that: */
|
||||||
/* serious error, go home! */
|
/* serious error, go home! */
|
||||||
failf (data, "The requested file was not found");
|
failf (data, "The requested URL returned error: %d",
|
||||||
|
k->httpcode);
|
||||||
return CURLE_HTTP_RETURNED_ERROR;
|
return CURLE_HTTP_RETURNED_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +589,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* Find the first non-space letter */
|
/* Find the first non-space letter */
|
||||||
for(start=k->p+14;
|
for(start=k->p+13;
|
||||||
*start && isspace((int)*start);
|
*start && isspace((int)*start);
|
||||||
start++);
|
start++);
|
||||||
|
|
||||||
@@ -647,12 +668,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
else if (checkprefix("Content-Encoding:", k->p) &&
|
else if (checkprefix("Content-Encoding:", k->p) &&
|
||||||
data->set.encoding) {
|
data->set.encoding) {
|
||||||
/*
|
/*
|
||||||
* Process Content-Encoding. Look for the values: identity, gzip,
|
* Process Content-Encoding. Look for the values: identity,
|
||||||
* defalte, compress, x-gzip and x-compress. x-gzip and
|
* gzip, deflate, compress, x-gzip and x-compress. x-gzip and
|
||||||
* x-compress are the same as gzip and compress. (Sec 3.5 RFC
|
* x-compress are the same as gzip and compress. (Sec 3.5 RFC
|
||||||
* 2616). zlib cannot handle compress, and gzip is not currently
|
* 2616). zlib cannot handle compress. However, errors are
|
||||||
* implemented. However, errors are handled further down when the
|
* handled further down when the response body is processed
|
||||||
* response body is processed 08/27/02 jhrg */
|
*/
|
||||||
char *start;
|
char *start;
|
||||||
|
|
||||||
/* Find the first non-space letter */
|
/* Find the first non-space letter */
|
||||||
@@ -686,7 +707,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else if(data->cookies &&
|
else if(data->cookies &&
|
||||||
checkprefix("Set-Cookie:", k->p)) {
|
checkprefix("Set-Cookie:", k->p)) {
|
||||||
Curl_cookie_add(data->cookies, TRUE, k->p+11, conn->name);
|
Curl_cookie_add(data->cookies, TRUE, k->p+11,
|
||||||
|
/* If there is a custom-set Host: name, use it
|
||||||
|
here, or else use real peer host name. */
|
||||||
|
conn->allocptr.cookiehost?
|
||||||
|
conn->allocptr.cookiehost:conn->name,
|
||||||
|
conn->ppath);
|
||||||
}
|
}
|
||||||
else if(checkprefix("Last-Modified:", k->p) &&
|
else if(checkprefix("Last-Modified:", k->p) &&
|
||||||
(data->set.timecondition || data->set.get_filetime) ) {
|
(data->set.timecondition || data->set.get_filetime) ) {
|
||||||
@@ -696,9 +722,93 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(data->set.get_filetime)
|
if(data->set.get_filetime)
|
||||||
data->info.filetime = k->timeofdoc;
|
data->info.filetime = k->timeofdoc;
|
||||||
}
|
}
|
||||||
|
else if(checkprefix("WWW-Authenticate:", k->p) &&
|
||||||
|
(401 == k->httpcode)) {
|
||||||
|
/*
|
||||||
|
* This page requires authentication
|
||||||
|
*/
|
||||||
|
char *start = k->p+strlen("WWW-Authenticate:");
|
||||||
|
|
||||||
|
/* pass all white spaces */
|
||||||
|
while(*start && isspace((int)*start))
|
||||||
|
start++;
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
if (checkprefix("GSS-Negotiate", start)) {
|
||||||
|
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
||||||
|
/* if exactly this is wanted, go */
|
||||||
|
int neg = Curl_input_negotiate(conn, start);
|
||||||
|
if (neg == 0)
|
||||||
|
conn->newurl = strdup(data->change.url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
||||||
|
data->state.authavail |= CURLAUTH_GSSNEGOTIATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
/* NTLM support requires the SSL crypto libs */
|
||||||
|
if(checkprefix("NTLM", start)) {
|
||||||
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
|
/* NTLM authentication is activated */
|
||||||
|
CURLntlm ntlm =
|
||||||
|
Curl_input_ntlm(conn, FALSE, start);
|
||||||
|
|
||||||
|
if(CURLNTLM_BAD != ntlm)
|
||||||
|
conn->newurl = strdup(data->change.url); /* clone string */
|
||||||
|
else
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(data->state.authwant & CURLAUTH_NTLM)
|
||||||
|
data->state.authavail |= CURLAUTH_NTLM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if(checkprefix("Digest", start)) {
|
||||||
|
if(data->state.authwant == CURLAUTH_DIGEST) {
|
||||||
|
/* Digest authentication is activated */
|
||||||
|
CURLdigest dig = CURLDIGEST_BAD;
|
||||||
|
|
||||||
|
if(data->state.digest.nonce)
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
else
|
||||||
|
dig = Curl_input_digest(conn, start);
|
||||||
|
|
||||||
|
if(CURLDIGEST_FINE == dig)
|
||||||
|
/* We act on it. Store our new url, which happens to be
|
||||||
|
the same one we already use! */
|
||||||
|
conn->newurl = strdup(data->change.url); /* clone string */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(data->state.authwant & CURLAUTH_DIGEST) {
|
||||||
|
/* We don't know if Digest is what we're gonna use, but we
|
||||||
|
call this function anyway to store the digest data that
|
||||||
|
is provided on this line, to skip the extra round-trip
|
||||||
|
we need to do otherwise. We must sure to free this
|
||||||
|
data! */
|
||||||
|
Curl_input_digest(conn, start);
|
||||||
|
data->state.authavail |= CURLAUTH_DIGEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(checkprefix("Basic", start)) {
|
||||||
|
if((data->state.authwant == CURLAUTH_BASIC) &&
|
||||||
|
(k->httpcode == 401)) {
|
||||||
|
/* We asked for Basic authentication but got a 401 back
|
||||||
|
anyway, which basicly means our name+password isn't
|
||||||
|
valid. */
|
||||||
|
data->state.authavail = CURLAUTH_NONE;
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
}
|
||||||
|
else if(data->state.authwant & CURLAUTH_BASIC) {
|
||||||
|
data->state.authavail |= CURLAUTH_BASIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
|
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||||
(data->set.http_follow_location) &&
|
|
||||||
checkprefix("Location:", k->p)) {
|
checkprefix("Location:", k->p)) {
|
||||||
|
if(data->set.http_follow_location) {
|
||||||
/* this is the URL that the server advices us to get instead */
|
/* this is the URL that the server advices us to get instead */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *start=k->p;
|
char *start=k->p;
|
||||||
@@ -710,11 +820,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
white spaces after the "Location:" keyword. */
|
white spaces after the "Location:" keyword. */
|
||||||
while(*start && isspace((int)*start ))
|
while(*start && isspace((int)*start ))
|
||||||
start++;
|
start++;
|
||||||
ptr = start; /* start scanning here */
|
|
||||||
|
|
||||||
/* scan through the string to find the end */
|
/* Scan through the string from the end to find the last
|
||||||
while(*ptr && !isspace((int)*ptr))
|
non-space. k->end_ptr points to the actual terminating zero
|
||||||
|
letter, move pointer one letter back and start from
|
||||||
|
there. This logic strips off trailing whitespace, but keeps
|
||||||
|
any embedded whitespace. */
|
||||||
|
ptr = k->end_ptr-1;
|
||||||
|
while((ptr>=start) && isspace((int)*ptr))
|
||||||
|
ptr--;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
backup = *ptr; /* store the ending letter */
|
backup = *ptr; /* store the ending letter */
|
||||||
if(ptr != start) {
|
if(ptr != start) {
|
||||||
*ptr = '\0'; /* zero terminate */
|
*ptr = '\0'; /* zero terminate */
|
||||||
@@ -722,21 +838,28 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
*ptr = backup; /* restore ending letter */
|
*ptr = backup; /* restore ending letter */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0 /* for consideration */
|
||||||
|
else {
|
||||||
|
/* This is a Location: but we have not been instructed to
|
||||||
|
follow it */
|
||||||
|
infof(data, "We ignore this location header as instructed\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of header-checks. Write them to the client.
|
* End of header-checks. Write them to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
k->writetype = CLIENTWRITE_HEADER;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
if (data->set.http_include_header)
|
if (data->set.http_include_header)
|
||||||
k->writetype |= CLIENTWRITE_BODY;
|
writetype |= CLIENTWRITE_BODY;
|
||||||
|
|
||||||
if(data->set.verbose)
|
if(data->set.verbose)
|
||||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||||
k->p, k->hbuflen);
|
k->p, k->hbuflen);
|
||||||
|
|
||||||
result = Curl_client_write(data, k->writetype, k->p,
|
result = Curl_client_write(data, writetype, k->p, k->hbuflen);
|
||||||
k->hbuflen);
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -769,15 +892,41 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
write a piece of the body */
|
write a piece of the body */
|
||||||
if(conn->protocol&PROT_HTTP) {
|
if(conn->protocol&PROT_HTTP) {
|
||||||
/* HTTP-only checks */
|
/* HTTP-only checks */
|
||||||
|
|
||||||
|
if(data->state.authavail) {
|
||||||
|
if(data->state.authavail & CURLAUTH_GSSNEGOTIATE)
|
||||||
|
data->state.authwant = CURLAUTH_GSSNEGOTIATE;
|
||||||
|
else if(data->state.authavail & CURLAUTH_DIGEST)
|
||||||
|
data->state.authwant = CURLAUTH_DIGEST;
|
||||||
|
else if(data->state.authavail & CURLAUTH_NTLM)
|
||||||
|
data->state.authwant = CURLAUTH_NTLM;
|
||||||
|
else if(data->state.authavail & CURLAUTH_BASIC)
|
||||||
|
data->state.authwant = CURLAUTH_BASIC;
|
||||||
|
else
|
||||||
|
data->state.authwant = CURLAUTH_NONE; /* none */
|
||||||
|
|
||||||
|
if(data->state.authwant)
|
||||||
|
conn->newurl = strdup(data->change.url); /* clone string */
|
||||||
|
|
||||||
|
data->state.authavail = CURLAUTH_NONE; /* clear it here */
|
||||||
|
}
|
||||||
|
|
||||||
if (conn->newurl) {
|
if (conn->newurl) {
|
||||||
/* abort after the headers if "follow Location" is set */
|
if(conn->bits.close) {
|
||||||
infof (data, "Follow to new URL: %s\n", conn->newurl);
|
/* Abort after the headers if "follow Location" is set
|
||||||
|
and we're set to close anyway. */
|
||||||
k->keepon &= ~KEEP_READ;
|
k->keepon &= ~KEEP_READ;
|
||||||
FD_ZERO(&k->rkeepfd);
|
FD_ZERO(&k->rkeepfd);
|
||||||
*done = TRUE;
|
*done = TRUE;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
else if (conn->resume_from &&
|
/* We have a new url to load, but since we want to be able
|
||||||
|
to re-use this connection properly, we read the full
|
||||||
|
response in "ignore more" */
|
||||||
|
k->ignorebody = TRUE;
|
||||||
|
infof(data, "Ignoring the response-body\n");
|
||||||
|
}
|
||||||
|
if (conn->resume_from &&
|
||||||
!k->content_range &&
|
!k->content_range &&
|
||||||
(data->set.httpreq==HTTPREQ_GET)) {
|
(data->set.httpreq==HTTPREQ_GET)) {
|
||||||
/* we wanted to resume a download, although the server
|
/* we wanted to resume a download, although the server
|
||||||
@@ -878,7 +1027,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(!conn->bits.chunk && (nread || k->badheader)) {
|
if(!conn->bits.chunk && (nread || k->badheader)) {
|
||||||
/* If this is chunky transfer, it was already written */
|
/* If this is chunky transfer, it was already written */
|
||||||
|
|
||||||
if(k->badheader) {
|
if(k->badheader && !k->ignorebody) {
|
||||||
/* we parsed a piece of data wrongly assuming it was a header
|
/* we parsed a piece of data wrongly assuming it was a header
|
||||||
and now we output it as body instead */
|
and now we output it as body instead */
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||||
@@ -888,7 +1037,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(k->badheader < HEADER_ALLBAD) {
|
if(k->badheader < HEADER_ALLBAD) {
|
||||||
/* This switch handles various content encodings. If there's an
|
/* This switch handles various content encodings. If there's an
|
||||||
error here, be sure to check over the almost identical code
|
error here, be sure to check over the almost identical code
|
||||||
in http_chunk.c. 08/29/02 jhrg */
|
in http_chunks.c. 08/29/02 jhrg
|
||||||
|
Make sure that ALL_CONTENT_ENCODINGS contains all the
|
||||||
|
encodings handled here. */
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
switch (k->content_encoding) {
|
switch (k->content_encoding) {
|
||||||
case IDENTITY:
|
case IDENTITY:
|
||||||
@@ -897,6 +1048,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
Content-Encoding header. See Curl_readwrite_init; the
|
Content-Encoding header. See Curl_readwrite_init; the
|
||||||
memset() call initializes k->content_encoding to zero.
|
memset() call initializes k->content_encoding to zero.
|
||||||
08/28/02 jhrg */
|
08/28/02 jhrg */
|
||||||
|
if(!k->ignorebody)
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||||
nread);
|
nread);
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
@@ -907,11 +1059,15 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
result = Curl_unencode_deflate_write(data, k, nread);
|
result = Curl_unencode_deflate_write(data, k, nread);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GZIP: /* FIXME 08/27/02 jhrg */
|
case GZIP:
|
||||||
case COMPRESS:
|
/* Assume CLIENTWRITE_BODY; headers are not encoded. */
|
||||||
|
result = Curl_unencode_gzip_write(data, k, nread);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMPRESS: /* FIXME 08/27/02 jhrg */
|
||||||
default:
|
default:
|
||||||
failf (data, "Unrecognized content encoding type. "
|
failf (data, "Unrecognized content encoding type. "
|
||||||
"libcurl understands `identity' and `deflate' "
|
"libcurl understands `identity', `deflate' and `gzip' "
|
||||||
"content encodings.");
|
"content encodings.");
|
||||||
result = CURLE_BAD_CONTENT_ENCODING;
|
result = CURLE_BAD_CONTENT_ENCODING;
|
||||||
break;
|
break;
|
||||||
@@ -940,7 +1096,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
|
|
||||||
int i, si;
|
int i, si;
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
bool writedone=FALSE;
|
bool writedone=TRUE;
|
||||||
|
|
||||||
if ((k->bytecount == 0) && (k->writebytecount == 0))
|
if ((k->bytecount == 0) && (k->writebytecount == 0))
|
||||||
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
||||||
@@ -1175,6 +1331,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
|
|||||||
k->maxfd = (conn->sockfd>conn->writesockfd?
|
k->maxfd = (conn->sockfd>conn->writesockfd?
|
||||||
conn->sockfd:conn->writesockfd)+1;
|
conn->sockfd:conn->writesockfd)+1;
|
||||||
k->hbufp = data->state.headerbuff;
|
k->hbufp = data->state.headerbuff;
|
||||||
|
k->ignorebody=FALSE;
|
||||||
|
|
||||||
Curl_pgrsTime(data, TIMER_PRETRANSFER);
|
Curl_pgrsTime(data, TIMER_PRETRANSFER);
|
||||||
Curl_speedinit(data);
|
Curl_speedinit(data);
|
||||||
@@ -1344,6 +1501,10 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
|||||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||||
data->state.errorbuf = FALSE; /* no error has occurred */
|
data->state.errorbuf = FALSE; /* no error has occurred */
|
||||||
|
|
||||||
|
/* set preferred authentication, default to basic */
|
||||||
|
data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC;
|
||||||
|
data->state.authavail = CURLAUTH_NONE; /* nothing so far */
|
||||||
|
|
||||||
/* If there was a list of cookie files to read and we haven't done it before,
|
/* If there was a list of cookie files to read and we haven't done it before,
|
||||||
do it now! */
|
do it now! */
|
||||||
if(data->change.cookielist) {
|
if(data->change.cookielist) {
|
||||||
@@ -1390,6 +1551,60 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int strlen_url(char *url)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int newlen=0;
|
||||||
|
bool left=TRUE; /* left side of the ? */
|
||||||
|
|
||||||
|
for(ptr=url; *ptr; ptr++) {
|
||||||
|
switch(*ptr) {
|
||||||
|
case '?':
|
||||||
|
left=FALSE;
|
||||||
|
default:
|
||||||
|
newlen++;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if(left)
|
||||||
|
newlen+=3;
|
||||||
|
else
|
||||||
|
newlen++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void strcpy_url(char *output, char *url)
|
||||||
|
{
|
||||||
|
/* we must add this with whitespace-replacing */
|
||||||
|
bool left=TRUE;
|
||||||
|
char *iptr;
|
||||||
|
char *optr = output;
|
||||||
|
for(iptr = url; /* read from here */
|
||||||
|
*iptr; /* until zero byte */
|
||||||
|
iptr++) {
|
||||||
|
switch(*iptr) {
|
||||||
|
case '?':
|
||||||
|
left=FALSE;
|
||||||
|
default:
|
||||||
|
*optr++=*iptr;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if(left) {
|
||||||
|
*optr++='%'; /* add a '%' */
|
||||||
|
*optr++='2'; /* add a '2' */
|
||||||
|
*optr++='0'; /* add a '0' */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*optr++='+'; /* add a '+' here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*optr=0; /* zero terminate output buffer */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_follow(struct SessionHandle *data,
|
CURLcode Curl_follow(struct SessionHandle *data,
|
||||||
char *newurl) /* this 'newurl' is the Location: string,
|
char *newurl) /* this 'newurl' is the Location: string,
|
||||||
and it must be malloc()ed before passed
|
and it must be malloc()ed before passed
|
||||||
@@ -1398,6 +1613,8 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
/* Location: redirect */
|
/* Location: redirect */
|
||||||
char prot[16]; /* URL protocol string storage */
|
char prot[16]; /* URL protocol string storage */
|
||||||
char letter; /* used for a silly sscanf */
|
char letter; /* used for a silly sscanf */
|
||||||
|
int newlen;
|
||||||
|
char *newest;
|
||||||
|
|
||||||
if (data->set.maxredirs &&
|
if (data->set.maxredirs &&
|
||||||
(data->set.followlocation >= data->set.maxredirs)) {
|
(data->set.followlocation >= data->set.maxredirs)) {
|
||||||
@@ -1434,9 +1651,9 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
*/
|
*/
|
||||||
char *protsep;
|
char *protsep;
|
||||||
char *pathsep;
|
char *pathsep;
|
||||||
char *newest;
|
|
||||||
|
|
||||||
char *useurl = newurl;
|
char *useurl = newurl;
|
||||||
|
int urllen;
|
||||||
|
|
||||||
/* we must make our own copy of the URL to play with, as it may
|
/* we must make our own copy of the URL to play with, as it may
|
||||||
point to read-only data */
|
point to read-only data */
|
||||||
@@ -1509,42 +1726,79 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
*pathsep=0;
|
*pathsep=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
newest=(char *)malloc( strlen(url_clone) +
|
/* If the new part contains a space, this is a mighty stupid redirect
|
||||||
1 + /* possible slash */
|
but we still make an effort to do "right". To the left of a '?'
|
||||||
strlen(useurl) + 1/* zero byte */);
|
letter we replace each space with %20 while it is replaced with '+'
|
||||||
|
on the right side of the '?' letter.
|
||||||
|
*/
|
||||||
|
newlen = strlen_url(useurl);
|
||||||
|
|
||||||
|
urllen = strlen(url_clone);
|
||||||
|
|
||||||
|
newest=(char *)malloc( urllen + 1 + /* possible slash */
|
||||||
|
newlen + 1 /* zero byte */);
|
||||||
|
|
||||||
if(!newest)
|
if(!newest)
|
||||||
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
||||||
|
|
||||||
sprintf(newest, "%s%s%s", url_clone,
|
/* copy over the root url part */
|
||||||
(('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
|
memcpy(newest, url_clone, urllen);
|
||||||
useurl);
|
|
||||||
|
/* check if we need to append a slash */
|
||||||
|
if(('/' == useurl[0]) || (protsep && !*protsep))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
newest[urllen++]='/';
|
||||||
|
|
||||||
|
/* then append the new piece on the right side */
|
||||||
|
strcpy_url(&newest[urllen], useurl);
|
||||||
|
|
||||||
free(newurl); /* newurl is the allocated pointer */
|
free(newurl); /* newurl is the allocated pointer */
|
||||||
free(url_clone);
|
free(url_clone);
|
||||||
newurl = newest;
|
newurl = newest;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
/* This is an absolute URL, don't allow the custom port number */
|
/* This is an absolute URL, don't allow the custom port number */
|
||||||
data->state.allow_port = FALSE;
|
data->state.allow_port = FALSE;
|
||||||
|
|
||||||
|
if(strchr(newurl, ' ')) {
|
||||||
|
/* This new URL contains at least one space, this is a mighty stupid
|
||||||
|
redirect but we still make an effort to do "right". */
|
||||||
|
newlen = strlen_url(newurl);
|
||||||
|
|
||||||
|
newest = malloc(newlen+1); /* get memory for this */
|
||||||
|
if(newest) {
|
||||||
|
strcpy_url(newest, newurl); /* create a space-free URL */
|
||||||
|
|
||||||
|
free(newurl); /* that was no good */
|
||||||
|
newurl = newest; /* use this instead now */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if(data->change.url_alloc)
|
if(data->change.url_alloc)
|
||||||
free(data->change.url);
|
free(data->change.url);
|
||||||
else
|
else
|
||||||
data->change.url_alloc = TRUE; /* the URL is allocated */
|
data->change.url_alloc = TRUE; /* the URL is allocated */
|
||||||
|
|
||||||
/* TBD: set the URL with curl_setopt() */
|
|
||||||
data->change.url = newurl;
|
data->change.url = newurl;
|
||||||
newurl = NULL; /* don't free! */
|
newurl = NULL; /* don't free! */
|
||||||
|
|
||||||
infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
|
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We get here when the HTTP code is 300-399. We need to perform
|
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
||||||
* differently based on exactly what return code there was.
|
* differently based on exactly what return code there was.
|
||||||
* Discussed on the curl mailing list and posted about on the 26th
|
*
|
||||||
* of January 2001.
|
* News from 7.10.6: we can also get here on a 401, in case we act on a
|
||||||
|
* HTTP authentication scheme other than Basic.
|
||||||
*/
|
*/
|
||||||
switch(data->info.httpcode) {
|
switch(data->info.httpcode) {
|
||||||
|
case 401:
|
||||||
|
/* Act on an authentication, we keep on moving and do the Authorization:
|
||||||
|
XXXX header in the HTTP request code snippet */
|
||||||
|
break;
|
||||||
case 300: /* Multiple Choices */
|
case 300: /* Multiple Choices */
|
||||||
case 306: /* Not used */
|
case 306: /* Not used */
|
||||||
case 307: /* Temporary Redirect */
|
case 307: /* Temporary Redirect */
|
||||||
@@ -1642,9 +1896,29 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
* performed after this do-while loop.
|
* performed after this do-while loop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
do {
|
||||||
|
int urlchanged = FALSE;
|
||||||
do {
|
do {
|
||||||
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
||||||
|
data->change.url_changed = FALSE;
|
||||||
res = Curl_connect(data, &conn);
|
res = Curl_connect(data, &conn);
|
||||||
|
|
||||||
|
/* If a callback (or something) has altered the URL we should use within
|
||||||
|
the Curl_connect(), we detect it here and act as if we are redirected
|
||||||
|
to the new URL */
|
||||||
|
urlchanged = data->change.url_changed;
|
||||||
|
if ((CURLE_OK == res) && urlchanged) {
|
||||||
|
char *newurl;
|
||||||
|
res = Curl_done(conn);
|
||||||
|
if(CURLE_OK == res) {
|
||||||
|
newurl = strdup(data->change.url);
|
||||||
|
res = Curl_follow(data, newurl);
|
||||||
|
if(res)
|
||||||
|
free(newurl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (urlchanged && res == CURLE_OK) ;
|
||||||
|
|
||||||
if(res == CURLE_OK) {
|
if(res == CURLE_OK) {
|
||||||
res = Curl_do(&conn);
|
res = Curl_do(&conn);
|
||||||
|
|
||||||
|
298
lib/url.c
298
lib/url.c
@@ -45,7 +45,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -106,6 +105,9 @@
|
|||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
|
#include "content_encoding.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
/* And now for the protocols */
|
/* And now for the protocols */
|
||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
@@ -132,7 +134,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -164,6 +166,11 @@ RETSIGTYPE alarmfunc(int signal)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Curl_safefree(void *ptr)
|
||||||
|
{
|
||||||
|
if(ptr)
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the internal function curl_easy_cleanup() calls. This should
|
* This is the internal function curl_easy_cleanup() calls. This should
|
||||||
@@ -191,11 +198,8 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
if(data->change.cookielist) /* clean up list if any */
|
if(data->change.cookielist) /* clean up list if any */
|
||||||
curl_slist_free_all(data->change.cookielist);
|
curl_slist_free_all(data->change.cookielist);
|
||||||
|
|
||||||
if(data->state.auth_host)
|
Curl_safefree(data->state.auth_host);
|
||||||
free(data->state.auth_host);
|
Curl_safefree(data->state.scratch);
|
||||||
|
|
||||||
if(data->state.scratch)
|
|
||||||
free(data->state.scratch);
|
|
||||||
|
|
||||||
if(data->change.proxy_alloc)
|
if(data->change.proxy_alloc)
|
||||||
free(data->change.proxy);
|
free(data->change.proxy);
|
||||||
@@ -206,13 +210,14 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
if(data->change.url_alloc)
|
if(data->change.url_alloc)
|
||||||
free(data->change.url);
|
free(data->change.url);
|
||||||
|
|
||||||
if(data->state.headerbuff)
|
Curl_safefree(data->state.headerbuff);
|
||||||
free(data->state.headerbuff);
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
if(data->set.cookiejar)
|
if(data->set.cookiejar) {
|
||||||
/* we have a "destination" for all the cookies to get dumped to */
|
/* we have a "destination" for all the cookies to get dumped to */
|
||||||
Curl_cookie_output(data->cookies, data->set.cookiejar);
|
if(Curl_cookie_output(data->cookies, data->set.cookiejar))
|
||||||
|
infof(data, "WARNING: failed to save cookies in given jar\n");
|
||||||
|
}
|
||||||
|
|
||||||
Curl_cookie_cleanup(data->cookies);
|
Curl_cookie_cleanup(data->cookies);
|
||||||
#endif
|
#endif
|
||||||
@@ -220,8 +225,9 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
/* free the connection cache */
|
/* free the connection cache */
|
||||||
free(data->state.connects);
|
free(data->state.connects);
|
||||||
|
|
||||||
if(data->info.contenttype)
|
Curl_safefree(data->info.contenttype);
|
||||||
free(data->info.contenttype);
|
|
||||||
|
Curl_digest_cleanup(data);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -282,6 +288,7 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
|||||||
|
|
||||||
data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
|
data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
|
||||||
data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
|
data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
|
||||||
|
data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
|
||||||
|
|
||||||
data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||||
|
|
||||||
@@ -632,6 +639,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
data->set.ftp_use_port = data->set.ftpport?1:0;
|
data->set.ftp_use_port = data->set.ftpport?1:0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CURLOPT_FTP_USE_EPRT:
|
||||||
|
data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
case CURLOPT_FTP_USE_EPSV:
|
case CURLOPT_FTP_USE_EPSV:
|
||||||
data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
|
data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
|
||||||
break;
|
break;
|
||||||
@@ -711,6 +722,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
}
|
}
|
||||||
data->set.set_url = va_arg(param, char *);
|
data->set.set_url = va_arg(param, char *);
|
||||||
data->change.url = data->set.set_url;
|
data->change.url = data->set.set_url;
|
||||||
|
data->change.url_changed = TRUE;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_PORT:
|
case CURLOPT_PORT:
|
||||||
/*
|
/*
|
||||||
@@ -818,8 +830,36 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
case CURLOPT_ENCODING:
|
case CURLOPT_ENCODING:
|
||||||
/*
|
/*
|
||||||
* String to use at the value of Accept-Encoding header. 08/28/02 jhrg
|
* String to use at the value of Accept-Encoding header. 08/28/02 jhrg
|
||||||
|
*
|
||||||
|
* If the encoding is set to "" we use an Accept-Encoding header that
|
||||||
|
* encompasses all the encodings we support.
|
||||||
|
* If the encoding is set to NULL we don't send an Accept-Encoding header
|
||||||
|
* and ignore an received Content-Encoding header.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
data->set.encoding = va_arg(param, char *);
|
data->set.encoding = va_arg(param, char *);
|
||||||
|
if(data->set.encoding && !*data->set.encoding)
|
||||||
|
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURLOPT_HTTPAUTH:
|
||||||
|
/*
|
||||||
|
* Set HTTP Authentication type BITMASK.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
long auth = va_arg(param, long);
|
||||||
|
/* switch off bits we can't support */
|
||||||
|
#ifndef USE_SSLEAY
|
||||||
|
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||||
|
#endif
|
||||||
|
#ifndef GSSAPI
|
||||||
|
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
|
||||||
|
#endif
|
||||||
|
if(!auth)
|
||||||
|
return CURLE_FAILED_INIT; /* no supported types left! */
|
||||||
|
|
||||||
|
data->set.httpauth = auth;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_USERPWD:
|
case CURLOPT_USERPWD:
|
||||||
@@ -1051,6 +1091,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
*/
|
*/
|
||||||
data->set.ssl.verifyhost = va_arg(param, long);
|
data->set.ssl.verifyhost = va_arg(param, long);
|
||||||
break;
|
break;
|
||||||
|
case CURLOPT_SSL_CTX_FUNCTION:
|
||||||
|
/*
|
||||||
|
* Set a SSL_CTX callback
|
||||||
|
*/
|
||||||
|
data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
|
||||||
|
break;
|
||||||
|
case CURLOPT_SSL_CTX_DATA:
|
||||||
|
/*
|
||||||
|
* Set a SSL_CTX callback parameter pointer
|
||||||
|
*/
|
||||||
|
data->set.ssl.fsslctxp = va_arg(param, void *);
|
||||||
|
break;
|
||||||
case CURLOPT_CAINFO:
|
case CURLOPT_CAINFO:
|
||||||
/*
|
/*
|
||||||
* Set CA info for SSL connection. Specify file name of the CA certificate
|
* Set CA info for SSL connection. Specify file name of the CA certificate
|
||||||
@@ -1180,14 +1232,9 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
/* This is set if protocol-specific cleanups should be made */
|
/* This is set if protocol-specific cleanups should be made */
|
||||||
conn->curl_disconnect(conn);
|
conn->curl_disconnect(conn);
|
||||||
|
|
||||||
if(conn->proto.generic)
|
Curl_safefree(conn->proto.generic);
|
||||||
free(conn->proto.generic);
|
Curl_safefree(conn->newurl);
|
||||||
|
Curl_safefree(conn->path); /* the URL path part */
|
||||||
if(conn->newurl)
|
|
||||||
free(conn->newurl);
|
|
||||||
|
|
||||||
if(conn->path) /* the URL path part */
|
|
||||||
free(conn->path);
|
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
Curl_SSL_Close(conn);
|
Curl_SSL_Close(conn);
|
||||||
@@ -1199,25 +1246,20 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
if(-1 != conn->firstsocket)
|
if(-1 != conn->firstsocket)
|
||||||
sclose(conn->firstsocket);
|
sclose(conn->firstsocket);
|
||||||
|
|
||||||
if(conn->allocptr.proxyuserpwd)
|
Curl_safefree(conn->user);
|
||||||
free(conn->allocptr.proxyuserpwd);
|
Curl_safefree(conn->passwd);
|
||||||
if(conn->allocptr.uagent)
|
Curl_safefree(conn->proxyuser);
|
||||||
free(conn->allocptr.uagent);
|
Curl_safefree(conn->proxypasswd);
|
||||||
if(conn->allocptr.userpwd)
|
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||||
free(conn->allocptr.userpwd);
|
Curl_safefree(conn->allocptr.uagent);
|
||||||
if(conn->allocptr.accept_encoding)
|
Curl_safefree(conn->allocptr.userpwd);
|
||||||
free(conn->allocptr.accept_encoding);
|
Curl_safefree(conn->allocptr.accept_encoding);
|
||||||
if(conn->allocptr.rangeline)
|
Curl_safefree(conn->allocptr.rangeline);
|
||||||
free(conn->allocptr.rangeline);
|
Curl_safefree(conn->allocptr.ref);
|
||||||
if(conn->allocptr.ref)
|
Curl_safefree(conn->allocptr.cookie);
|
||||||
free(conn->allocptr.ref);
|
Curl_safefree(conn->allocptr.host);
|
||||||
if(conn->allocptr.cookie)
|
Curl_safefree(conn->allocptr.cookiehost);
|
||||||
free(conn->allocptr.cookie);
|
Curl_safefree(conn->proxyhost);
|
||||||
if(conn->allocptr.host)
|
|
||||||
free(conn->allocptr.host);
|
|
||||||
|
|
||||||
if(conn->proxyhost)
|
|
||||||
free(conn->proxyhost);
|
|
||||||
|
|
||||||
Curl_free_ssl_config(&conn->ssl_config);
|
Curl_free_ssl_config(&conn->ssl_config);
|
||||||
|
|
||||||
@@ -1300,11 +1342,13 @@ ConnectionExists(struct SessionHandle *data,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(needle->protocol & PROT_FTP) {
|
if((needle->protocol & PROT_FTP) ||
|
||||||
/* This is FTP, verify that we're using the same name and
|
((needle->protocol & PROT_HTTP) &&
|
||||||
password as well */
|
(needle->data->state.authwant==CURLAUTH_NTLM))) {
|
||||||
if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
|
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
||||||
!strequal(needle->data->state.passwd, check->proto.ftp->passwd)) {
|
and password as well */
|
||||||
|
if(!strequal(needle->user, check->user) ||
|
||||||
|
!strequal(needle->passwd, check->passwd)) {
|
||||||
/* one of them was different */
|
/* one of them was different */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1517,7 +1561,7 @@ static int handleSock5Proxy(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((socksreq[0] != 5) || /* version */
|
if ((socksreq[0] != 1) || /* version */
|
||||||
(socksreq[1] != 0)) { /* status */
|
(socksreq[1] != 0)) { /* status */
|
||||||
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
|
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||||
socksreq[0], socksreq[1]);
|
socksreq[0], socksreq[1]);
|
||||||
@@ -1660,8 +1704,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
||||||
return handleSock5Proxy(conn->data->state.proxyuser,
|
return handleSock5Proxy(conn->proxyuser,
|
||||||
conn->data->state.proxypasswd,
|
conn->proxypasswd,
|
||||||
conn,
|
conn,
|
||||||
conn->firstsocket) ?
|
conn->firstsocket) ?
|
||||||
CURLE_COULDNT_CONNECT : CURLE_OK;
|
CURLE_COULDNT_CONNECT : CURLE_OK;
|
||||||
@@ -1775,7 +1819,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
struct connectdata **in_connect)
|
struct connectdata **in_connect)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
char *buf;
|
|
||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
char resumerange[40]="";
|
char resumerange[40]="";
|
||||||
struct connectdata *conn;
|
struct connectdata *conn;
|
||||||
@@ -1786,6 +1829,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
unsigned int prev_alarm=0;
|
unsigned int prev_alarm=0;
|
||||||
#endif
|
#endif
|
||||||
char endbracket;
|
char endbracket;
|
||||||
|
char user[MAX_CURL_USER_LENGTH];
|
||||||
|
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||||
|
bool passwdgiven=FALSE; /* set TRUE if an application-provided password has
|
||||||
|
been set */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGACTION
|
#ifdef HAVE_SIGACTION
|
||||||
struct sigaction keep_sigact; /* store the old struct here */
|
struct sigaction keep_sigact; /* store the old struct here */
|
||||||
@@ -1921,16 +1969,20 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
/* Set default host and default path */
|
/* Set default host and default path */
|
||||||
strcpy(conn->gname, "curl.haxx.se");
|
strcpy(conn->gname, "curl.haxx.se");
|
||||||
strcpy(conn->path, "/");
|
strcpy(conn->path, "/");
|
||||||
|
/* We need to search for '/' OR '?' - whichever comes first after host
|
||||||
|
* name but before the path. We need to change that to handle things like
|
||||||
|
* http://example.com?param= (notice the missing '/'). Later we'll insert
|
||||||
|
* that missing slash at the beginning of the path.
|
||||||
|
*/
|
||||||
if (2 > sscanf(data->change.url,
|
if (2 > sscanf(data->change.url,
|
||||||
"%64[^\n:]://%512[^\n/]%[^\n]",
|
"%64[^\n:]://%512[^\n/?]%[^\n]",
|
||||||
conn->protostr, conn->gname, conn->path)) {
|
conn->protostr, conn->gname, conn->path)) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The URL was badly formatted, let's try the browser-style _without_
|
* The URL was badly formatted, let's try the browser-style _without_
|
||||||
* protocol specified like 'http://'.
|
* protocol specified like 'http://'.
|
||||||
*/
|
*/
|
||||||
if((1 > sscanf(data->change.url, "%512[^\n/]%[^\n]",
|
if((1 > sscanf(data->change.url, "%512[^\n/?]%[^\n]",
|
||||||
conn->gname, conn->path)) ) {
|
conn->gname, conn->path)) ) {
|
||||||
/*
|
/*
|
||||||
* We couldn't even get this format.
|
* We couldn't even get this format.
|
||||||
@@ -1972,7 +2024,17 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = data->state.buffer; /* this is our buffer */
|
/* If the URL is malformatted (missing a '/' after hostname before path) we
|
||||||
|
* insert a slash here. The only letter except '/' we accept to start a path
|
||||||
|
* is '?'.
|
||||||
|
*/
|
||||||
|
if(conn->path[0] == '?') {
|
||||||
|
/* We need this function to deal with overlapping memory areas. We know
|
||||||
|
that the memory area 'path' points to is 'urllen' bytes big and that
|
||||||
|
is bigger than the path. Use +1 to move the zero byte too. */
|
||||||
|
memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
|
||||||
|
conn->path[0] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* So if the URL was A://B/C,
|
* So if the URL was A://B/C,
|
||||||
@@ -1985,29 +2047,36 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
* Take care of proxy authentication stuff
|
* Take care of proxy authentication stuff
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
if(conn->bits.proxy_user_passwd) {
|
if(conn->bits.proxy_user_passwd) {
|
||||||
data->state.proxyuser[0] =0;
|
char proxyuser[MAX_CURL_USER_LENGTH]="";
|
||||||
data->state.proxypasswd[0]=0;
|
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
|
||||||
|
|
||||||
if(*data->set.proxyuserpwd != ':') {
|
if(*data->set.proxyuserpwd != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
|
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
|
||||||
data->state.proxyuser, data->state.proxypasswd);
|
proxyuser, proxypasswd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, get the password only */
|
/* no name given, get the password only */
|
||||||
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd);
|
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd);
|
||||||
|
|
||||||
/* check for password, if no ask for one */
|
/* check for password, if no ask for one */
|
||||||
if( !data->state.proxypasswd[0] ) {
|
if( !proxypasswd[0] ) {
|
||||||
if(data->set.fpasswd( data->set.passwd_client,
|
if(data->set.fpasswd( data->set.passwd_client,
|
||||||
"proxy password:",
|
"proxy password:",
|
||||||
data->state.proxypasswd,
|
proxypasswd,
|
||||||
sizeof(data->state.proxypasswd))) {
|
sizeof(proxypasswd))) {
|
||||||
failf(data, "Bad password from password callback");
|
failf(data, "Bad password from password callback");
|
||||||
return CURLE_BAD_PASSWORD_ENTERED;
|
return CURLE_BAD_PASSWORD_ENTERED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn->proxyuser = strdup(proxyuser);
|
||||||
|
if(!conn->proxyuser)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
conn->proxypasswd = strdup(proxypasswd);
|
||||||
|
if(!conn->proxypasswd)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -2017,7 +2086,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
conn->ppath = conn->path;
|
conn->ppath = conn->path;
|
||||||
conn->hostname = conn->name;
|
conn->hostname = conn->name;
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Detect what (if any) proxy to use
|
* Detect what (if any) proxy to use
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@@ -2118,6 +2186,45 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
|
|
||||||
if(proxy && *proxy) {
|
if(proxy && *proxy) {
|
||||||
/* we have a proxy here to set */
|
/* we have a proxy here to set */
|
||||||
|
char *ptr;
|
||||||
|
char user[MAX_CURL_USER_LENGTH];
|
||||||
|
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||||
|
|
||||||
|
/* skip the possible protocol piece */
|
||||||
|
ptr=strstr(proxy, "://");
|
||||||
|
if(ptr)
|
||||||
|
ptr += 3;
|
||||||
|
else
|
||||||
|
ptr = proxy;
|
||||||
|
|
||||||
|
/* check for an @-letter */
|
||||||
|
ptr = strchr(ptr, '@');
|
||||||
|
if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
|
||||||
|
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
|
||||||
|
user, passwd))) {
|
||||||
|
/* found user and password, rip them out */
|
||||||
|
if(conn->proxyuser)
|
||||||
|
free(conn->proxyuser);
|
||||||
|
conn->proxyuser = strdup(user);
|
||||||
|
|
||||||
|
if(!conn->proxyuser)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
if(conn->proxypasswd)
|
||||||
|
free(conn->proxypasswd);
|
||||||
|
conn->proxypasswd = strdup(passwd);
|
||||||
|
|
||||||
|
if(!conn->proxypasswd)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
conn->bits.proxy_user_passwd = TRUE; /* enable it */
|
||||||
|
|
||||||
|
ptr = strdup(ptr+1);
|
||||||
|
free(proxy); /* free the former data */
|
||||||
|
proxy = ptr; /* now use this instead */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
data->change.proxy = proxy;
|
data->change.proxy = proxy;
|
||||||
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
||||||
conn->bits.httpproxy = TRUE;
|
conn->bits.httpproxy = TRUE;
|
||||||
@@ -2495,8 +2602,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
*
|
*
|
||||||
* Outputs: (almost :- all currently undefined)
|
* Outputs: (almost :- all currently undefined)
|
||||||
* conn->bits.user_passwd - non-zero if non-default passwords exist
|
* conn->bits.user_passwd - non-zero if non-default passwords exist
|
||||||
* conn->state.user - non-zero length if defined
|
* conn->user - non-zero length if defined
|
||||||
* conn->state.passwd - ditto
|
* conn->passwd - ditto
|
||||||
* conn->hostname - remove user name and password
|
* conn->hostname - remove user name and password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -2507,8 +2614,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
* We need somewhere to put the embedded details, so do that first.
|
* We need somewhere to put the embedded details, so do that first.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data->state.user[0] =0; /* to make everything well-defined */
|
user[0] =0; /* to make everything well-defined */
|
||||||
data->state.passwd[0]=0;
|
passwd[0]=0;
|
||||||
|
|
||||||
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
|
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
|
||||||
/* This is a FTP or HTTP URL, we will now try to extract the possible
|
/* This is a FTP or HTTP URL, we will now try to extract the possible
|
||||||
@@ -2535,31 +2642,31 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(*userpass != ':') {
|
if(*userpass != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(userpass, "%127[^:@]:%127[^@]",
|
sscanf(userpass, "%127[^:@]:%127[^@]",
|
||||||
data->state.user, data->state.passwd);
|
user, passwd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, get the password only */
|
/* no name given, get the password only */
|
||||||
sscanf(userpass, ":%127[^@]", data->state.passwd);
|
sscanf(userpass, ":%127[^@]", passwd);
|
||||||
|
|
||||||
if(data->state.user[0]) {
|
if(user[0]) {
|
||||||
char *newname=curl_unescape(data->state.user, 0);
|
char *newname=curl_unescape(user, 0);
|
||||||
if(strlen(newname) < sizeof(data->state.user)) {
|
if(strlen(newname) < sizeof(user)) {
|
||||||
strcpy(data->state.user, newname);
|
strcpy(user, newname);
|
||||||
}
|
}
|
||||||
/* if the new name is longer than accepted, then just use
|
/* if the new name is longer than accepted, then just use
|
||||||
the unconverted name, it'll be wrong but what the heck */
|
the unconverted name, it'll be wrong but what the heck */
|
||||||
free(newname);
|
free(newname);
|
||||||
}
|
}
|
||||||
if (data->state.passwd[0]) {
|
if (passwd[0]) {
|
||||||
/* we have a password found in the URL, decode it! */
|
/* we have a password found in the URL, decode it! */
|
||||||
char *newpasswd=curl_unescape(data->state.passwd, 0);
|
char *newpasswd=curl_unescape(passwd, 0);
|
||||||
if(strlen(newpasswd) < sizeof(data->state.passwd)) {
|
if(strlen(newpasswd) < sizeof(passwd)) {
|
||||||
strcpy(data->state.passwd, newpasswd);
|
strcpy(passwd, newpasswd);
|
||||||
}
|
}
|
||||||
free(newpasswd);
|
free(newpasswd);
|
||||||
|
|
||||||
/* we have set the password */
|
/* we have set the password */
|
||||||
data->state.passwdgiven = TRUE;
|
passwdgiven = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2578,35 +2685,35 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(*data->set.userpwd != ':') {
|
if(*data->set.userpwd != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
||||||
data->state.user, data->state.passwd);
|
user, passwd);
|
||||||
if(strchr(data->set.userpwd, ':'))
|
if(strchr(data->set.userpwd, ':'))
|
||||||
/* a colon means the password was given, even if blank */
|
/* a colon means the password was given, even if blank */
|
||||||
data->state.passwdgiven = TRUE;
|
passwdgiven = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, starts with a colon, get the password only */
|
/* no name given, starts with a colon, get the password only */
|
||||||
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
|
sscanf(data->set.userpwd+1, "%127[^\n]", passwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data->set.use_netrc != CURL_NETRC_IGNORED) &&
|
if ((data->set.use_netrc != CURL_NETRC_IGNORED) &&
|
||||||
!data->state.passwdgiven) { /* need passwd */
|
!passwdgiven) { /* need passwd */
|
||||||
if(Curl_parsenetrc(conn->hostname,
|
if(Curl_parsenetrc(conn->hostname,
|
||||||
data->state.user,
|
user,
|
||||||
data->state.passwd)) {
|
passwd)) {
|
||||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||||
conn->hostname);
|
conn->hostname);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn->bits.user_passwd = 1; /* enable user+password */
|
conn->bits.user_passwd = 1; /* enable user+password */
|
||||||
data->state.passwdgiven = TRUE;
|
passwdgiven = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we have a user but no password, ask for one */
|
/* if we have a user but no password, ask for one */
|
||||||
if(conn->bits.user_passwd && !data->state.passwdgiven ) {
|
if(conn->bits.user_passwd && !passwdgiven ) {
|
||||||
if(data->set.fpasswd(data->set.passwd_client,
|
if(data->set.fpasswd(data->set.passwd_client,
|
||||||
"password:", data->state.passwd,
|
"password:", passwd,
|
||||||
sizeof(data->state.passwd)))
|
sizeof(passwd)))
|
||||||
return CURLE_BAD_PASSWORD_ENTERED;
|
return CURLE_BAD_PASSWORD_ENTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2615,14 +2722,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
/* If our protocol needs a password and we have none, use the defaults */
|
/* If our protocol needs a password and we have none, use the defaults */
|
||||||
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
||||||
!conn->bits.user_passwd &&
|
!conn->bits.user_passwd &&
|
||||||
!data->state.passwdgiven) {
|
!passwdgiven) {
|
||||||
|
|
||||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
strcpy(user, CURL_DEFAULT_USER);
|
||||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
strcpy(passwd, CURL_DEFAULT_PASSWORD);
|
||||||
|
|
||||||
/* This is the default password, so DON'T set conn->bits.user_passwd */
|
/* This is the default password, so DON'T set conn->bits.user_passwd */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* store user + password */
|
||||||
|
conn->user = strdup(user);
|
||||||
|
conn->passwd = strdup(passwd);
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Check the current list of connections to see if we can
|
* Check the current list of connections to see if we can
|
||||||
* re-use an already existing one or if we have to create a
|
* re-use an already existing one or if we have to create a
|
||||||
@@ -2682,6 +2793,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
otherwise */
|
otherwise */
|
||||||
conn->maxdownload = -1; /* might have been used previously! */
|
conn->maxdownload = -1; /* might have been used previously! */
|
||||||
|
|
||||||
|
free(old_conn->user);
|
||||||
|
free(old_conn->passwd);
|
||||||
|
|
||||||
free(old_conn); /* we don't need this anymore */
|
free(old_conn); /* we don't need this anymore */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2786,6 +2900,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(conn->bits.reuse) {
|
if(conn->bits.reuse) {
|
||||||
/* re-used connection, no resolving is necessary */
|
/* re-used connection, no resolving is necessary */
|
||||||
hostaddr = NULL;
|
hostaddr = NULL;
|
||||||
|
conn->connect_addr = NULL; /* we don't connect now so we don't have any
|
||||||
|
fresh connect_addr struct to point to */
|
||||||
}
|
}
|
||||||
else if(!data->change.proxy || !*data->change.proxy) {
|
else if(!data->change.proxy || !*data->change.proxy) {
|
||||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
/* If not connecting via a proxy, extract the port from the URL, if it is
|
||||||
@@ -2862,7 +2978,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(conn->bits.proxy_user_passwd) {
|
if(conn->bits.proxy_user_passwd) {
|
||||||
char *authorization;
|
char *authorization;
|
||||||
snprintf(data->state.buffer, BUFSIZE, "%s:%s",
|
snprintf(data->state.buffer, BUFSIZE, "%s:%s",
|
||||||
data->state.proxyuser, data->state.proxypasswd);
|
conn->proxyuser, conn->proxypasswd);
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||||
&authorization) >= 0) {
|
&authorization) >= 0) {
|
||||||
if(conn->allocptr.proxyuserpwd)
|
if(conn->allocptr.proxyuserpwd)
|
||||||
@@ -2982,7 +3098,7 @@ CURLcode Curl_done(struct connectdata *conn)
|
|||||||
if(conn->connect_addr)
|
if(conn->connect_addr)
|
||||||
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
|
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
|
||||||
|
|
||||||
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
|
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||||
/* scan for DNS cache entries still marked as in use */
|
/* scan for DNS cache entries still marked as in use */
|
||||||
Curl_hash_apply(data->hostcache,
|
Curl_hash_apply(data->hostcache,
|
||||||
NULL, Curl_scan_cache_used);
|
NULL, Curl_scan_cache_used);
|
||||||
|
@@ -42,4 +42,5 @@ bool Curl_ssl_config_matches(struct ssl_config_data* data,
|
|||||||
bool Curl_clone_ssl_config(struct ssl_config_data* source,
|
bool Curl_clone_ssl_config(struct ssl_config_data* source,
|
||||||
struct ssl_config_data* dest);
|
struct ssl_config_data* dest);
|
||||||
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
||||||
|
void Curl_safefree(void *ptr);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -83,7 +83,11 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB_H
|
#ifdef HAVE_ZLIB_H
|
||||||
#include <zlib.h> /* for content-encoding 08/28/02 jhrg */
|
#include <zlib.h> /* for content-encoding */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include <gssapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Download buffer size, keep it fairly big for speed reasons */
|
/* Download buffer size, keep it fairly big for speed reasons */
|
||||||
@@ -93,6 +97,9 @@
|
|||||||
of need. */
|
of need. */
|
||||||
#define HEADERSIZE 256
|
#define HEADERSIZE 256
|
||||||
|
|
||||||
|
/* Maximum number of dirs supported by libcurl in a FTP dir hierarchy */
|
||||||
|
#define CURL_MAX_FTP_DIRDEPTH 100
|
||||||
|
|
||||||
/* Just a convenience macro to get the larger value out of two given */
|
/* Just a convenience macro to get the larger value out of two given */
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
@@ -138,6 +145,8 @@ struct ssl_config_data {
|
|||||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||||
char *cipher_list; /* list of ciphers to use */
|
char *cipher_list; /* list of ciphers to use */
|
||||||
long numsessions; /* SSL session id cache size */
|
long numsessions; /* SSL session id cache size */
|
||||||
|
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
|
||||||
|
void *fsslctxp; /*parameter for call back */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* information stored about one single SSL session */
|
/* information stored about one single SSL session */
|
||||||
@@ -149,6 +158,36 @@ struct curl_ssl_session {
|
|||||||
struct ssl_config_data ssl_config; /* setup for this session */
|
struct ssl_config_data ssl_config; /* setup for this session */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Struct used for Digest challenge-response authentication */
|
||||||
|
struct digestdata {
|
||||||
|
char *nonce;
|
||||||
|
char *cnonce;
|
||||||
|
char *realm;
|
||||||
|
int algo;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NTLMSTATE_NONE,
|
||||||
|
NTLMSTATE_TYPE1,
|
||||||
|
NTLMSTATE_TYPE2,
|
||||||
|
NTLMSTATE_TYPE3,
|
||||||
|
NTLMSTATE_LAST
|
||||||
|
} curlntlm;
|
||||||
|
|
||||||
|
/* Struct used for Digest challenge-response authentication */
|
||||||
|
struct ntlmdata {
|
||||||
|
curlntlm state;
|
||||||
|
unsigned char nonce[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
struct negotiatedata {
|
||||||
|
OM_uint32 status;
|
||||||
|
gss_ctx_id_t context;
|
||||||
|
gss_name_t server_name;
|
||||||
|
gss_buffer_desc output_token;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* HTTP unique setup
|
* HTTP unique setup
|
||||||
@@ -193,7 +232,7 @@ struct FTP {
|
|||||||
char *user; /* user name string */
|
char *user; /* user name string */
|
||||||
char *passwd; /* password string */
|
char *passwd; /* password string */
|
||||||
char *urlpath; /* the originally given path part of the URL */
|
char *urlpath; /* the originally given path part of the URL */
|
||||||
char *dir; /* decoded directory */
|
char *dirs[CURL_MAX_FTP_DIRDEPTH]; /* path components */
|
||||||
char *file; /* decoded file */
|
char *file; /* decoded file */
|
||||||
|
|
||||||
char *entrypath; /* the PWD reply when we logged on */
|
char *entrypath; /* the PWD reply when we logged on */
|
||||||
@@ -296,14 +335,13 @@ struct Curl_transfer_keeper {
|
|||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
bool zlib_init; /* True if zlib already initialized;
|
bool zlib_init; /* True if zlib already initialized;
|
||||||
undefined if Content-Encdoing header. */
|
undefined if Content-Encoding header. */
|
||||||
z_stream z; /* State structure for zlib. */
|
z_stream z; /* State structure for zlib. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* for the low speed checks: */
|
/* for the low speed checks: */
|
||||||
time_t timeofdoc;
|
time_t timeofdoc;
|
||||||
long bodywrites;
|
long bodywrites;
|
||||||
int writetype;
|
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
char *uploadbuf;
|
char *uploadbuf;
|
||||||
@@ -322,8 +360,9 @@ struct Curl_transfer_keeper {
|
|||||||
|
|
||||||
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
|
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
|
||||||
and we're uploading the last chunk */
|
and we're uploading the last chunk */
|
||||||
};
|
|
||||||
|
|
||||||
|
bool ignorebody; /* we read a response-body but we ignore it! */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The connectdata struct contains all fields and variables that should be
|
* The connectdata struct contains all fields and variables that should be
|
||||||
@@ -374,6 +413,12 @@ struct connectdata {
|
|||||||
|
|
||||||
char *proxyhost; /* name of the http proxy host */
|
char *proxyhost; /* name of the http proxy host */
|
||||||
|
|
||||||
|
char *user; /* user name string, allocated */
|
||||||
|
char *passwd; /* password string, allocated */
|
||||||
|
|
||||||
|
char *proxyuser; /* proxy user name string, allocated */
|
||||||
|
char *proxypasswd; /* proxy password string, allocated */
|
||||||
|
|
||||||
struct timeval now; /* "current" time */
|
struct timeval now; /* "current" time */
|
||||||
struct timeval created; /* creation time */
|
struct timeval created; /* creation time */
|
||||||
int firstsocket; /* the main socket to use */
|
int firstsocket; /* the main socket to use */
|
||||||
@@ -429,12 +474,13 @@ struct connectdata {
|
|||||||
struct dynamically_allocated_data {
|
struct dynamically_allocated_data {
|
||||||
char *proxyuserpwd; /* free later if not NULL! */
|
char *proxyuserpwd; /* free later if not NULL! */
|
||||||
char *uagent; /* free later if not NULL! */
|
char *uagent; /* free later if not NULL! */
|
||||||
char *accept_encoding; /* free later if not NULL! 08/28/02 jhrg */
|
char *accept_encoding; /* free later if not NULL! */
|
||||||
char *userpwd; /* free later if not NULL! */
|
char *userpwd; /* free later if not NULL! */
|
||||||
char *rangeline; /* free later if not NULL! */
|
char *rangeline; /* free later if not NULL! */
|
||||||
char *ref; /* free later if not NULL! */
|
char *ref; /* free later if not NULL! */
|
||||||
char *cookie; /* free later if not NULL! */
|
char *cookie; /* free later if not NULL! */
|
||||||
char *host; /* free later if not NULL */
|
char *host; /* free later if not NULL */
|
||||||
|
char *cookiehost; /* free later if not NULL */
|
||||||
} allocptr;
|
} allocptr;
|
||||||
|
|
||||||
char *newurl; /* This can only be set if a Location: was in the
|
char *newurl; /* This can only be set if a Location: was in the
|
||||||
@@ -487,9 +533,14 @@ struct connectdata {
|
|||||||
|
|
||||||
curl_read_callback fread; /* function that reads the input */
|
curl_read_callback fread; /* function that reads the input */
|
||||||
void *fread_in; /* pointer to pass to the fread() above */
|
void *fread_in; /* pointer to pass to the fread() above */
|
||||||
|
|
||||||
|
struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
|
||||||
|
because it authenticates connections, not
|
||||||
|
single requests! */
|
||||||
|
struct ntlmdata proxyntlm; /* NTLM data for proxy */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The end of connectdata. 08/27/02 jhrg */
|
/* The end of connectdata. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Struct to keep statistical and informational data.
|
* Struct to keep statistical and informational data.
|
||||||
@@ -497,7 +548,7 @@ struct connectdata {
|
|||||||
struct PureInfo {
|
struct PureInfo {
|
||||||
int httpcode;
|
int httpcode;
|
||||||
int httpversion;
|
int httpversion;
|
||||||
long filetime; /* If requested, this is might get set. Set to -1 if
|
time_t filetime; /* If requested, this is might get set. Set to -1 if
|
||||||
the time was unretrievable */
|
the time was unretrievable */
|
||||||
long header_size; /* size of read header(s) in bytes */
|
long header_size; /* size of read header(s) in bytes */
|
||||||
long request_size; /* the amount of bytes sent in the request(s) */
|
long request_size; /* the amount of bytes sent in the request(s) */
|
||||||
@@ -560,6 +611,8 @@ typedef enum {
|
|||||||
* Session-data MUST be put in the connectdata struct and here. */
|
* Session-data MUST be put in the connectdata struct and here. */
|
||||||
#define MAX_CURL_USER_LENGTH 256
|
#define MAX_CURL_USER_LENGTH 256
|
||||||
#define MAX_CURL_PASSWORD_LENGTH 256
|
#define MAX_CURL_PASSWORD_LENGTH 256
|
||||||
|
#define MAX_CURL_USER_LENGTH_TXT "255"
|
||||||
|
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
|
||||||
|
|
||||||
struct UrlState {
|
struct UrlState {
|
||||||
enum {
|
enum {
|
||||||
@@ -569,14 +622,6 @@ struct UrlState {
|
|||||||
} used_interface;
|
} used_interface;
|
||||||
|
|
||||||
/* buffers to store authentication data in, as parsed from input options */
|
/* buffers to store authentication data in, as parsed from input options */
|
||||||
char user[MAX_CURL_USER_LENGTH];
|
|
||||||
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
|
||||||
char proxyuser[MAX_CURL_USER_LENGTH];
|
|
||||||
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
|
|
||||||
|
|
||||||
bool passwdgiven; /* set TRUE if an application-provided password has been
|
|
||||||
set */
|
|
||||||
|
|
||||||
struct timeval keeps_speed; /* for the progress meter really */
|
struct timeval keeps_speed; /* for the progress meter really */
|
||||||
|
|
||||||
/* 'connects' will be an allocated array with pointers. If the pointer is
|
/* 'connects' will be an allocated array with pointers. If the pointer is
|
||||||
@@ -613,6 +658,15 @@ struct UrlState {
|
|||||||
#endif
|
#endif
|
||||||
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
||||||
is always set TRUE when curl_easy_perform() is called. */
|
is always set TRUE when curl_easy_perform() is called. */
|
||||||
|
|
||||||
|
struct digestdata digest;
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
struct negotiatedata negotiate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
long authwant; /* inherited from what the user set with CURLOPT_HTTPAUTH */
|
||||||
|
long authavail; /* what the server reports */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -626,6 +680,10 @@ struct UrlState {
|
|||||||
struct DynamicStatic {
|
struct DynamicStatic {
|
||||||
char *url; /* work URL, copied from UserDefined */
|
char *url; /* work URL, copied from UserDefined */
|
||||||
bool url_alloc; /* URL string is malloc()'ed */
|
bool url_alloc; /* URL string is malloc()'ed */
|
||||||
|
bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was
|
||||||
|
changed after the connect phase, as we allow callback
|
||||||
|
to change it and if so, we reconnect to use the new
|
||||||
|
URL instead */
|
||||||
char *proxy; /* work proxy, copied from UserDefined */
|
char *proxy; /* work proxy, copied from UserDefined */
|
||||||
bool proxy_alloc; /* http proxy string is malloc()'ed */
|
bool proxy_alloc; /* http proxy string is malloc()'ed */
|
||||||
char *referer; /* referer string */
|
char *referer; /* referer string */
|
||||||
@@ -657,6 +715,7 @@ struct UserDefined {
|
|||||||
char *set_proxy; /* proxy to use */
|
char *set_proxy; /* proxy to use */
|
||||||
long use_port; /* which port to use (when not using default) */
|
long use_port; /* which port to use (when not using default) */
|
||||||
char *userpwd; /* <user:password>, if used */
|
char *userpwd; /* <user:password>, if used */
|
||||||
|
long httpauth; /* what kind of HTTP authentication to use (bitmask) */
|
||||||
char *set_range; /* range, if used. See README for detailed specification
|
char *set_range; /* range, if used. See README for detailed specification
|
||||||
on this syntax. */
|
on this syntax. */
|
||||||
long followlocation; /* as in HTTP Location: */
|
long followlocation; /* as in HTTP Location: */
|
||||||
@@ -755,6 +814,7 @@ struct UserDefined {
|
|||||||
bool reuse_fresh; /* do not re-use an existing connection */
|
bool reuse_fresh; /* do not re-use an existing connection */
|
||||||
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
||||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||||
|
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
|
||||||
bool no_signal; /* do not use any signal/alarm handler */
|
bool no_signal; /* do not use any signal/alarm handler */
|
||||||
|
|
||||||
bool global_dns_cache;
|
bool global_dns_cache;
|
||||||
|
@@ -114,6 +114,10 @@ char *curl_version(void)
|
|||||||
sprintf(ptr, " zlib/%s", zlibVersion());
|
sprintf(ptr, " zlib/%s", zlibVersion());
|
||||||
ptr += strlen(ptr);
|
ptr += strlen(ptr);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
sprintf(ptr, " GSS");
|
||||||
|
ptr += strlen(ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
@@ -168,9 +172,16 @@ static curl_version_info_data version_info = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
| CURL_VERSION_SSL
|
| CURL_VERSION_SSL
|
||||||
|
| CURL_VERSION_NTLM /* since this requires OpenSSL */
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
| CURL_VERSION_LIBZ
|
| CURL_VERSION_LIBZ
|
||||||
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
| CURL_VERSION_GSSNEGOTIATE
|
||||||
|
#endif
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
| CURL_VERSION_DEBUG
|
||||||
#endif
|
#endif
|
||||||
,
|
,
|
||||||
NULL, /* ssl_version */
|
NULL, /* ssl_version */
|
||||||
|
5
maketgz
5
maketgz
@@ -134,3 +134,8 @@ echo ""
|
|||||||
ls -l $targz $bzip2 $zip
|
ls -l $targz $bzip2 $zip
|
||||||
|
|
||||||
md5sum $targz $bzip2 $zip
|
md5sum $targz $bzip2 $zip
|
||||||
|
|
||||||
|
echo "Run these commands:"
|
||||||
|
echo "gpg -b -a $targz"
|
||||||
|
echo "gpg -b -a $bzip2"
|
||||||
|
echo "gpg -b -a $zip"
|
||||||
|
2
packages/DOS/.cvsignore
Normal file
2
packages/DOS/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Makefile
|
||||||
|
Makefile.in
|
1
packages/DOS/Makefile.am
Normal file
1
packages/DOS/Makefile.am
Normal file
@@ -0,0 +1 @@
|
|||||||
|
EXTRA_DIST = README common.dj
|
4
packages/DOS/README
Normal file
4
packages/DOS/README
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Gisle Vanem made curl build fine on DOS (and MingW) with djgpp, OpenSSL and his
|
||||||
|
Watt-32 stack.
|
||||||
|
|
||||||
|
'make djgpp' in the root curl dir should build it fine.
|
56
packages/DOS/common.dj
Normal file
56
packages/DOS/common.dj
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#
|
||||||
|
# Common defines for curl (djgpp/Watt-32)
|
||||||
|
#
|
||||||
|
# Assumes you've unpacked cURL with short-file names
|
||||||
|
# I.e use "set LFN=n" before untaring on Win9x/XP.
|
||||||
|
# Requires sed, yacc, rm and the usual stuff.
|
||||||
|
#
|
||||||
|
|
||||||
|
.SUFFIXES: .exe .y
|
||||||
|
|
||||||
|
MAKEFILE = Makefile.dj
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenSSL is available from www.openssl.org and builds okay
|
||||||
|
# with djgpp/Watt-32. Set to 0 if you don't need https URLs
|
||||||
|
# (reduces curl.exe with approx 700 kB)
|
||||||
|
#
|
||||||
|
USE_SSL = 1
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
#
|
||||||
|
# Root directory for Waterloo tcp/ip. WATT_ROOT should be set
|
||||||
|
# during Watt-32 install.
|
||||||
|
#
|
||||||
|
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
|
||||||
|
OPENSSL_ROOT = /net/openssl.098
|
||||||
|
ZLIB_ROOT = $(DJDIR)/contrib/zlib
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
YACC = bison -y
|
||||||
|
|
||||||
|
CFLAGS = -g -O2 -I. -I../include -Wall -DHAVE_CONFIG_H
|
||||||
|
|
||||||
|
ifeq ($(USE_SSL),1)
|
||||||
|
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generated dependencies; Due to some hacks in gcc 2.95+ and djgpp 2.03
|
||||||
|
# we must prevent "$(DJDIR)/bin/../include/sys/version.h" from beeing
|
||||||
|
# included in dependency output (or else this makefile cannot be used on
|
||||||
|
# another machine). We therefore use a special 'specs' file during
|
||||||
|
# pre-processing.
|
||||||
|
#
|
||||||
|
MM_SPECS = $(TMPDIR)/specs
|
||||||
|
|
||||||
|
depend: $(DEPEND_PREREQ)
|
||||||
|
@echo Generating dependencies..
|
||||||
|
@copy $(MAKEFILE) Makefile.bak
|
||||||
|
@echo "*cpp: %(cpp_cpu) %{posix:-D_POSIX_SOURCE} -remap" > $(MM_SPECS)
|
||||||
|
sed -e "/^# DO NOT DELETE THIS LINE/,$$d" < Makefile.bak > $(MAKEFILE)
|
||||||
|
echo "# DO NOT DELETE THIS LINE" >> $(MAKEFILE)
|
||||||
|
$(CC) -MM -specs=$(MM_SPECS) $(CFLAGS) $(SOURCES) >> $(MAKEFILE)
|
||||||
|
rm -f $(MM_SPECS)
|
||||||
|
|
@@ -1,3 +1,3 @@
|
|||||||
SUBDIRS = Win32 Linux Solaris EPM
|
SUBDIRS = Win32 Linux Solaris EPM DOS
|
||||||
|
|
||||||
EXTRA_DIST = README
|
EXTRA_DIST = README
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user