Compare commits
214 Commits
curl-7_21_
...
curl-7_21_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8da5da9b65 | ||
![]() |
42c6b7577f | ||
![]() |
e5010ec3ff | ||
![]() |
5c314c6bb4 | ||
![]() |
9016958aa8 | ||
![]() |
1614dc0745 | ||
![]() |
af6dcc92d5 | ||
![]() |
57064e4a0d | ||
![]() |
d9e71809cb | ||
![]() |
a7cc54a5a8 | ||
![]() |
c9a82f39e2 | ||
![]() |
e4bca6a01c | ||
![]() |
56e5302b53 | ||
![]() |
4cbc6fc6ab | ||
![]() |
c9f16e67ef | ||
![]() |
f851f76857 | ||
![]() |
0126b4a959 | ||
![]() |
49a8fe5142 | ||
![]() |
8fc4be9e7b | ||
![]() |
70eee054f2 | ||
![]() |
0aedccc18a | ||
![]() |
85881f9f35 | ||
![]() |
84e13f2e07 | ||
![]() |
832e827518 | ||
![]() |
a6fa7fc38e | ||
![]() |
b122f8be61 | ||
![]() |
950fb3efcc | ||
![]() |
ee015947d4 | ||
![]() |
a2a2863306 | ||
![]() |
b688f2c260 | ||
![]() |
c4dd8df081 | ||
![]() |
0f7bea7c3a | ||
![]() |
d5cc77b744 | ||
![]() |
36a22f9074 | ||
![]() |
6e0dd48f97 | ||
![]() |
cb2f300364 | ||
![]() |
7530a28878 | ||
![]() |
e8d73c9c2d | ||
![]() |
8a3c0fe56c | ||
![]() |
f551aa5c16 | ||
![]() |
377f88364e | ||
![]() |
c0b9dd27b5 | ||
![]() |
6aff805942 | ||
![]() |
b772f3a321 | ||
![]() |
7559b77727 | ||
![]() |
4f170ee8f9 | ||
![]() |
fba00c9f7b | ||
![]() |
10a7d05be3 | ||
![]() |
9776f3445d | ||
![]() |
adeac15d8e | ||
![]() |
5d4e5593d5 | ||
![]() |
c2eb8c932d | ||
![]() |
a6f14e17b7 | ||
![]() |
b3740f0e09 | ||
![]() |
2a31dde76c | ||
![]() |
bf749bb2c5 | ||
![]() |
65a9fa59dc | ||
![]() |
9eea43dce2 | ||
![]() |
910d7953aa | ||
![]() |
970117ef2d | ||
![]() |
aa76dec33a | ||
![]() |
d6bb8dcc23 | ||
![]() |
685359d4c3 | ||
![]() |
a689072f33 | ||
![]() |
3d64ed25df | ||
![]() |
ecfe0b5b18 | ||
![]() |
9460896cbe | ||
![]() |
a87102c792 | ||
![]() |
2e7a2027f1 | ||
![]() |
ae677edf90 | ||
![]() |
f5d78919af | ||
![]() |
f3d77f772d | ||
![]() |
7dd449d843 | ||
![]() |
f461c6e61d | ||
![]() |
3c9ff41a1f | ||
![]() |
c8c8816a97 | ||
![]() |
5d39dea3b3 | ||
![]() |
9f390a356e | ||
![]() |
017ee34bba | ||
![]() |
340228cc81 | ||
![]() |
edf282c096 | ||
![]() |
a947a9ac62 | ||
![]() |
9b5343054a | ||
![]() |
b735717606 | ||
![]() |
ec33742d1b | ||
![]() |
2ea31b0e6f | ||
![]() |
de70ddb749 | ||
![]() |
a41c7f9736 | ||
![]() |
512b2f7740 | ||
![]() |
8bdc48eddb | ||
![]() |
328600e02b | ||
![]() |
e2747ebbc0 | ||
![]() |
41ebda02b2 | ||
![]() |
30c9799f72 | ||
![]() |
bed6b89a2f | ||
![]() |
3e70c28ce5 | ||
![]() |
79cc6c244a | ||
![]() |
d30ddd9977 | ||
![]() |
8b849265d8 | ||
![]() |
fce7276f54 | ||
![]() |
004d84fcc1 | ||
![]() |
02f3ff3b0a | ||
![]() |
3f6ffcd26d | ||
![]() |
3912e7bde3 | ||
![]() |
488521427f | ||
![]() |
e83816bfcf | ||
![]() |
b578534508 | ||
![]() |
5db30a1d8c | ||
![]() |
664ff30650 | ||
![]() |
873d70a6d8 | ||
![]() |
6dfa16c3c4 | ||
![]() |
60f0ebbdc9 | ||
![]() |
b5d170b551 | ||
![]() |
d4e000906a | ||
![]() |
bb7ff942d3 | ||
![]() |
48a40f0402 | ||
![]() |
0c8e6f598a | ||
![]() |
2ef7a28a71 | ||
![]() |
2a02c07a15 | ||
![]() |
212d8c8f65 | ||
![]() |
b996b202c4 | ||
![]() |
32001ac414 | ||
![]() |
9c629e5348 | ||
![]() |
f0612f166a | ||
![]() |
e34131db78 | ||
![]() |
335dfa793c | ||
![]() |
574aecee20 | ||
![]() |
51075a6777 | ||
![]() |
4508ea103f | ||
![]() |
558f997e99 | ||
![]() |
fda0985bfd | ||
![]() |
93ec4555ff | ||
![]() |
61877b569f | ||
![]() |
dc15a88076 | ||
![]() |
adae5926dd | ||
![]() |
ade337d79e | ||
![]() |
365db94e0a | ||
![]() |
d4ebf3c6b0 | ||
![]() |
f78fa6a57d | ||
![]() |
038a631274 | ||
![]() |
7d94af497d | ||
![]() |
a490961b10 | ||
![]() |
821301de15 | ||
![]() |
3440f4d374 | ||
![]() |
f83c36934f | ||
![]() |
c4bc1d473f | ||
![]() |
5b7e1f9efe | ||
![]() |
c33aee1667 | ||
![]() |
3b1b26578f | ||
![]() |
2cbe885c1a | ||
![]() |
4a42e5cdaa | ||
![]() |
53ef3493bf | ||
![]() |
cbd98b2c28 | ||
![]() |
4685db9462 | ||
![]() |
45de057920 | ||
![]() |
aa87f0ab15 | ||
![]() |
6a6981503e | ||
![]() |
889d1e973f | ||
![]() |
1b758b01c1 | ||
![]() |
7ddcc8fea4 | ||
![]() |
068d656c6d | ||
![]() |
92f722017c | ||
![]() |
9869668884 | ||
![]() |
b903186fa0 | ||
![]() |
592eda8e3f | ||
![]() |
6d013b0aab | ||
![]() |
bcc29cda8e | ||
![]() |
4235457129 | ||
![]() |
e9542ccab6 | ||
![]() |
7de2f9271c | ||
![]() |
24d84da073 | ||
![]() |
ca015f1a45 | ||
![]() |
722f286f80 | ||
![]() |
f20b4606de | ||
![]() |
c985a8df51 | ||
![]() |
a0fad3017e | ||
![]() |
2a05025510 | ||
![]() |
d8373cb992 | ||
![]() |
17df5d8caa | ||
![]() |
210278d9a1 | ||
![]() |
5942362847 | ||
![]() |
7d86e467fa | ||
![]() |
7609b32e7c | ||
![]() |
1702a2c08d | ||
![]() |
9230be0797 | ||
![]() |
7872c8d5a2 | ||
![]() |
37b9fe104a | ||
![]() |
3242abd87a | ||
![]() |
1b6df743f6 | ||
![]() |
c2c8948190 | ||
![]() |
c6a0abdd97 | ||
![]() |
9039d19f01 | ||
![]() |
c828646f60 | ||
![]() |
eb65a49bef | ||
![]() |
b2140a09f8 | ||
![]() |
519bec7c91 | ||
![]() |
24e5a40156 | ||
![]() |
2d1b6242f2 | ||
![]() |
a5db4a46ac | ||
![]() |
65aadf2118 | ||
![]() |
24667466f0 | ||
![]() |
5aae3c13e2 | ||
![]() |
8e4fb01e64 | ||
![]() |
ebb37eac8b | ||
![]() |
9d191a6a40 | ||
![]() |
be973b6f91 | ||
![]() |
2db6f7e703 | ||
![]() |
0790b27910 | ||
![]() |
e80b957789 | ||
![]() |
213939c8ba | ||
![]() |
82ecc85d9e | ||
![]() |
84f809e7a8 | ||
![]() |
cae351e9f5 | ||
![]() |
909acfbbba |
@@ -62,8 +62,7 @@ CURL_HEADERS := \
|
||||
mprintf.h \
|
||||
multi.h \
|
||||
stdcheaders.h \
|
||||
typecheck-gcc.h \
|
||||
types.h
|
||||
typecheck-gcc.h
|
||||
|
||||
LOCAL_SRC_FILES := $(addprefix lib/,$(CSOURCES))
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/
|
||||
@@ -73,6 +72,7 @@ LOCAL_COPY_HEADERS_TO := libcurl/curl
|
||||
LOCAL_COPY_HEADERS := $(addprefix include/curl/,$(CURL_HEADERS))
|
||||
|
||||
LOCAL_MODULE:= libcurl
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
# Copy the licence to a place where Android will find it.
|
||||
# Actually, this doesn't quite work because the build system searches
|
||||
@@ -93,6 +93,7 @@ include $(LOCAL_PATH)/src/Makefile.inc
|
||||
LOCAL_SRC_FILES := $(addprefix src/,$(CURL_CFILES))
|
||||
|
||||
LOCAL_MODULE := curl
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_STATIC_LIBRARIES := libcurl
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
|
||||
|
@@ -23,7 +23,6 @@ include(Utilities)
|
||||
|
||||
project( CURL C )
|
||||
|
||||
|
||||
file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
|
||||
string (REGEX MATCH "LIBCURL_VERSION_MAJOR[ \t]+([0-9]+)"
|
||||
LIBCURL_VERSION_MJ ${CURL_VERSION_H_CONTENTS})
|
||||
@@ -191,12 +190,12 @@ if(WIN32)
|
||||
endif(WIN32)
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
# does, it appends library to the list.
|
||||
# does, it prepends library to the list.
|
||||
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} ""
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
||||
${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_LIBS ${CURL_LIBS} ${LIBRARY})
|
||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
|
||||
|
||||
@@ -224,25 +223,6 @@ check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
|
||||
# CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ)
|
||||
# ENDIF(NOT CURL_SPECIAL_LIBZ)
|
||||
|
||||
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON)
|
||||
mark_as_advanced(CMAKE_USE_OPENSSL)
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
if(WIN32)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
set(USE_SSLEAY TRUE)
|
||||
set(USE_OPENSSL TRUE)
|
||||
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES} )
|
||||
else()
|
||||
set(CMAKE_USE_OPENSSL FALSE)
|
||||
message(STATUS "OpenSSL NOT Found, disabling CMAKE_USE_OPENSSL")
|
||||
endif()
|
||||
else(WIN32)
|
||||
check_library_exists_concat("crypto" CRYPTO_lock HAVE_LIBCRYPTO)
|
||||
check_library_exists_concat("ssl" SSL_connect HAVE_LIBSSL)
|
||||
endif(WIN32)
|
||||
endif(CMAKE_USE_OPENSSL)
|
||||
|
||||
# Check for idn
|
||||
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
|
||||
|
||||
@@ -271,6 +251,25 @@ if(CURL_ZLIB) # AND CURL_CONFIG_HAS_BEEN_RUN_BEFORE
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON)
|
||||
mark_as_advanced(CMAKE_USE_OPENSSL)
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
if(WIN32)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
set(USE_SSLEAY TRUE)
|
||||
set(USE_OPENSSL TRUE)
|
||||
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES} )
|
||||
else()
|
||||
set(CMAKE_USE_OPENSSL FALSE)
|
||||
message(STATUS "OpenSSL NOT Found, disabling CMAKE_USE_OPENSSL")
|
||||
endif()
|
||||
else(WIN32)
|
||||
check_library_exists_concat("crypto" CRYPTO_lock HAVE_LIBCRYPTO)
|
||||
check_library_exists_concat("ssl" SSL_connect HAVE_LIBSSL)
|
||||
endif(WIN32)
|
||||
endif(CMAKE_USE_OPENSSL)
|
||||
|
||||
# If we have features.h, then do the _BSD_SOURCE magic
|
||||
check_include_file("features.h" HAVE_FEATURES_H)
|
||||
|
||||
@@ -852,3 +851,14 @@ endif()
|
||||
if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
|
||||
set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before")
|
||||
endif()
|
||||
|
||||
# Installation.
|
||||
# First, install generated curlbuild.h
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/curl/curlbuild.h"
|
||||
DESTINATION include/curl )
|
||||
# Next, install other headers excluding curlbuild.h
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
|
||||
DESTINATION include
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN "curlbuild.h" EXCLUDE)
|
||||
|
@@ -40,8 +40,8 @@ EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
SUBDIRS = lib src
|
||||
DIST_SUBDIRS = $(SUBDIRS) tests include packages docs
|
||||
SUBDIRS = lib src include
|
||||
DIST_SUBDIRS = $(SUBDIRS) tests packages docs
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libcurl.pc
|
||||
@@ -155,3 +155,7 @@ ca-bundle: lib/mk-ca-bundle.pl
|
||||
ca-firefox: lib/firefox-db2pem.sh
|
||||
@echo "generate a fresh ca-bundle.crt"
|
||||
./lib/firefox-db2pem.sh lib/ca-bundle.crt
|
||||
|
||||
checksrc:
|
||||
cd lib && $(MAKE) checksrc
|
||||
cd src && $(MAKE) checksrc
|
||||
|
@@ -70,30 +70,18 @@ mingw32:
|
||||
$(MAKE) -C lib -f Makefile.m32
|
||||
$(MAKE) -C src -f Makefile.m32
|
||||
|
||||
mingw32-zlib:
|
||||
$(MAKE) -C lib -f Makefile.m32 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 ZLIB=1
|
||||
|
||||
mingw32-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSL=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSL=1 ZLIB=1
|
||||
|
||||
mingw32-ssh2-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
|
||||
|
||||
mingw32-ssh2-ssl-sspi-zlib:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
|
||||
mingw32-rtmp-ssh2-ssl-sspi-zlib:
|
||||
$(MAKE) -C lib -f Makefile.m32 RTMP=1 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 RTMP=1 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
|
||||
mingw32-clean:
|
||||
$(MAKE) -C lib -f Makefile.m32 clean
|
||||
$(MAKE) -C src -f Makefile.m32 clean
|
||||
|
||||
mingw32-vclean mingw32-distclean:
|
||||
$(MAKE) -C lib -f Makefile.m32 vclean
|
||||
$(MAKE) -C src -f Makefile.m32 vclean
|
||||
|
||||
mingw32%:
|
||||
$(MAKE) -C lib -f Makefile.m32 CFG=$@
|
||||
$(MAKE) -C src -f Makefile.m32 CFG=$@
|
||||
|
||||
vc-clean: $(VC)
|
||||
cd lib
|
||||
nmake -f Makefile.$(VC) clean
|
||||
|
@@ -1,69 +1,38 @@
|
||||
Curl and libcurl 7.21.5
|
||||
Curl and libcurl 7.21.7
|
||||
|
||||
Public curl releases: 121
|
||||
Command line options: 143
|
||||
curl_easy_setopt() options: 185
|
||||
Public curl releases: 123
|
||||
Command line options: 144
|
||||
curl_easy_setopt() options: 186
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 854
|
||||
Contributors: 868
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o SOCKOPTFUNCTION: callback can say already-connected
|
||||
o Added --netrc-file
|
||||
o Added (new) support for cyassl
|
||||
o TSL-SRP: enabled with OpenSSL
|
||||
o Added CURLE_NOT_BUILT_IN and CURLE_UNKNOWN_OPTION
|
||||
o recognize the [protocol]:// prefix in proxy hosts where the protocol is one
|
||||
of socks4, socks4a, socks5 or socks5h.
|
||||
o Added CURLOPT_CLOSESOCKETFUNCTION and CURLOPT_CLOSESOCKETDATA
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o nss: avoid memory leak on SSL connection failure
|
||||
o nss: do not ignore failure of SSL handshake
|
||||
o multi: better failed connect handling when using FTP, SMTP, POP3 and IMAP
|
||||
o runtests.pl: fix pid number concatenation that prevented it from killing
|
||||
the correct process at times
|
||||
o PolarSSL: Return 0 on receiving TLS CLOSE_NOTIFY alert
|
||||
o curl_easy_setopt.3: Removed wrong reference to CURLOPT_USERPASSWORD
|
||||
o multi: close connection on timeout
|
||||
o IMAP in multi mode does SSL connections non-blocking
|
||||
o honours the --disable-ldaps configure option
|
||||
o Force setopt constants written by --libcurl to be long
|
||||
o ssh_connect: treat libssh2 return code better
|
||||
o SFTP upload could stall the state machine when the multi_socket API was
|
||||
used
|
||||
o SFTP and SCP could leak memory when used with the multi interface and
|
||||
the connection was closed
|
||||
o Added missing file to repair the MSVC makefiles
|
||||
o Fixed detection of recvfrom arguments on Android/bionic
|
||||
o GSS: handle reuse fix
|
||||
o transfer: avoid insane conversion of time_t
|
||||
o nss: do not ignore value of CURLOPT_SSL_VERIFYPEER in certain cases
|
||||
o SMTP-multi: non-blocking connect
|
||||
o SFTP-multi: set cselect for sftp and scp to fix "stall" risk
|
||||
o configure: removed wrongly claimed default paths
|
||||
o pop3: fixed torture tests to succeed
|
||||
o symbols-in-versions: many corrections
|
||||
o if a HTTP request gets retried because the connection was dead, rewind if
|
||||
any data was sent as part of it
|
||||
o only probe for working ipv6 once and then re-use that info for further
|
||||
requests
|
||||
o requests that are asked to bound to a local interface/port will no longer
|
||||
wrongly re-use connections that aren't
|
||||
o libcurl.m4: Add missing quotes in AC_LINK_IFELSE
|
||||
o progress output: don't print the last update on a separate line
|
||||
o POP3: the command to send is STLS, not STARTTLS
|
||||
o POP3: PASS command was not sent after upgrade to TLS
|
||||
o configure: fix libtool warning
|
||||
o nss: allow to use multiple client certificates for a single host
|
||||
o HTTP pipelining: Fix handling of zero-length responses
|
||||
o Don't list NTLM in curl-config when HTTP is disabled
|
||||
o curl_easy_setopt.3: CURLOPT_RESOLVE typo version
|
||||
o OpenSSL: build fine with no-sslv2 versions
|
||||
o checkconnection: don't call with NULL pointer with RTSP and multi interface
|
||||
o Borland makefile updates
|
||||
o configure: libssh2 link fix without pkg-config
|
||||
o certinfo crash
|
||||
o CCC crash
|
||||
o SECURITY ADVISORY: inappropriate GSSAPI delegation. Full details at
|
||||
http://curl.haxx.se/docs/adv_20110623.html
|
||||
o NTLM: work with unicode
|
||||
o fix connect with SOCKS proxy when using the multi interface
|
||||
o anyauthput.c: stdint.h must not be included unconditionally
|
||||
o CMake: improved build
|
||||
o SCP/SFTP enable non-blocking earlier
|
||||
o GnuTLS handshake: fix timeout
|
||||
o cyassl: build without filesystem
|
||||
o HTTPS over HTTP proxy using the multi interface
|
||||
o speedcheck: invalid timeout event on a reused handle
|
||||
o Force connection close for HTTP 200 OK when time condition matched
|
||||
o curl_formget: fix FILE * leak
|
||||
o configure: improved OpenSSL detection
|
||||
o Android build: support gingerbread
|
||||
o CURLFORM_STREAM: acknowledge CURLFORM_FILENAME
|
||||
o windows build: use correct MS CRT
|
||||
o pop3: remove extra space in LIST command
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -72,10 +41,9 @@ This release includes the following known bugs:
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Mike Crowe, Kamil Dudka, Julien Chaffraix, Hoi-Ho Chan, Ben Noordhuis,
|
||||
Dan Fandrich, Henry Ludemann, Karl M, Manuel Massing, Marcus Sundberg,
|
||||
Stefan Krause, Todd A Ouska, Saqib Ali, Andre Guibert de Bruet,
|
||||
Tor Arntsen, Vincent Torri, Dave Reisner, Chris Smowton, Tinus van den Berg,
|
||||
Hongli Lai, Gisle Vanem, Andrei Benea, Mehmet Bozkurt
|
||||
Dan Fandrich, Guenter Knauf, Vsevolod Novikov, Zmey Petroff,
|
||||
Dagobert Michelsen, Jeff Pohlmeyer, Dmitri Shubin, Matteo Rocco,
|
||||
Aaron Orenstein, Yang Tse, Kamil Dudka, Amr Shahin, Josue Andrade Gomes,
|
||||
Ori Avtalion, Richard Silverman, Julien Chaffraix
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
23
acinclude.m4
23
acinclude.m4
@@ -1663,7 +1663,7 @@ AC_DEFUN([CURL_CHECK_FUNC_RECVFROM], [
|
||||
for recvfrom_arg2 in 'char *' 'void *'; do
|
||||
for recvfrom_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do
|
||||
for recvfrom_arg4 in 'int' 'unsigned int'; do
|
||||
for recvfrom_arg5 in 'const struct sockaddr *' 'struct sockaddr *' 'void *'; do
|
||||
for recvfrom_arg5 in 'struct sockaddr *' 'void *' 'const struct sockaddr *'; do
|
||||
for recvfrom_arg6 in 'socklen_t *' 'int *' 'unsigned int *' 'size_t *' 'void *'; do
|
||||
if test "$curl_cv_func_recvfrom_args" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
@@ -1731,7 +1731,7 @@ AC_DEFUN([CURL_CHECK_FUNC_RECVFROM], [
|
||||
shift
|
||||
#
|
||||
recvfrom_ptrt_arg2=$[2]
|
||||
recvfrom_ptrt_arg5=$[5]
|
||||
recvfrom_qual_ptrt_arg5=$[5]
|
||||
recvfrom_ptrt_arg6=$[6]
|
||||
#
|
||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG1, $[1],
|
||||
@@ -1753,12 +1753,25 @@ AC_DEFUN([CURL_CHECK_FUNC_RECVFROM], [
|
||||
;;
|
||||
esac
|
||||
#
|
||||
case "$recvfrom_qual_ptrt_arg5" in
|
||||
const*)
|
||||
recvfrom_qual_arg5=const
|
||||
recvfrom_ptrt_arg5=`echo $recvfrom_qual_ptrt_arg5 | sed 's/^const //'`
|
||||
;;
|
||||
*)
|
||||
recvfrom_qual_arg5=
|
||||
recvfrom_ptrt_arg5=$recvfrom_qual_ptrt_arg5
|
||||
;;
|
||||
esac
|
||||
#
|
||||
recvfrom_type_arg2=`echo $recvfrom_ptrt_arg2 | sed 's/ \*//'`
|
||||
recvfrom_type_arg5=`echo $recvfrom_ptrt_arg5 | sed 's/ \*//'`
|
||||
recvfrom_type_arg6=`echo $recvfrom_ptrt_arg6 | sed 's/ \*//'`
|
||||
#
|
||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG2, $recvfrom_type_arg2,
|
||||
[Define to the type pointed by arg 2 for recvfrom.])
|
||||
AC_DEFINE_UNQUOTED(RECVFROM_QUAL_ARG5, $recvfrom_qual_arg5,
|
||||
[Define to the type qualifier pointed by arg 5 for recvfrom.])
|
||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG5, $recvfrom_type_arg5,
|
||||
[Define to the type pointed by arg 5 for recvfrom.])
|
||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG6, $recvfrom_type_arg6,
|
||||
@@ -2843,7 +2856,7 @@ AC_DEFUN([DO_CURL_OFF_T_CHECK], [
|
||||
tmp_includes=""
|
||||
tmp_source=""
|
||||
tmp_fmt=""
|
||||
case AS_TR_SH([$1]) in
|
||||
case XC_SH_TR_SH([$1]) in
|
||||
int64_t)
|
||||
tmp_includes="$curl_includes_inttypes"
|
||||
tmp_source="char f@<:@@:>@ = PRId64;"
|
||||
@@ -2901,7 +2914,7 @@ AC_DEFUN([DO_CURL_OFF_T_SUFFIX_CHECK], [
|
||||
curl_suffix_curl_off_t="unknown"
|
||||
curl_suffix_curl_off_tu="unknown"
|
||||
#
|
||||
case AS_TR_SH([$1]) in
|
||||
case XC_SH_TR_SH([$1]) in
|
||||
long_long | __longlong | __longlong_t)
|
||||
tst_suffixes="LL::"
|
||||
;;
|
||||
@@ -3073,7 +3086,7 @@ AC_DEFUN([CURL_CONFIGURE_CURL_OFF_T], [
|
||||
curl_format_curl_off_tu=`echo "$curl_format_curl_off_tu" | "$SED" 's/D$/U/'`
|
||||
else
|
||||
x_pull_headers="no"
|
||||
case AS_TR_SH([$curl_typeof_curl_off_t]) in
|
||||
case XC_SH_TR_SH([$curl_typeof_curl_off_t]) in
|
||||
long_long | __longlong | __longlong_t)
|
||||
curl_format_curl_off_t="lld"
|
||||
curl_format_curl_off_tu="llu"
|
||||
|
@@ -411,7 +411,7 @@ else
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Finished succesfully.
|
||||
# Finished successfully.
|
||||
#
|
||||
|
||||
echo "buildconf: OK"
|
||||
|
30
configure.ac
30
configure.ac
@@ -305,6 +305,24 @@ AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
|
||||
CURL_CHECK_CURLDEBUG
|
||||
AM_CONDITIONAL(CURLDEBUG, test x$want_curldebug = xyes)
|
||||
|
||||
supports_unittests=yes
|
||||
# cross-compilation of unit tests static library/programs fails when
|
||||
# libcurl shared library is built. This might be due to a libtool or
|
||||
# automake issue. In this case we disable unit tests.
|
||||
if test "x$cross_compiling" != "xno" &&
|
||||
test "x$enable_shared" != "xno"; then
|
||||
supports_unittests=no
|
||||
fi
|
||||
|
||||
dnl Build unit tests when option --enable-debug is given.
|
||||
if test "x$want_debug" = "xyes" &&
|
||||
test "x$supports_unittests" = "xyes"; then
|
||||
want_unittests=yes
|
||||
else
|
||||
want_unittests=no
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_UNITTESTS, test x$want_unittests = xyes)
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Compilation based checks should not be done before this point.
|
||||
dnl **********************************************************************
|
||||
@@ -1513,6 +1531,7 @@ if test X"$OPT_SSL" != Xno; then
|
||||
export LD_LIBRARY_PATH
|
||||
AC_MSG_NOTICE([Added $LIB_OPENSSL to LD_LIBRARY_PATH])
|
||||
fi
|
||||
CURL_CHECK_OPENSSL_API
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -1624,8 +1643,12 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
|
||||
[read randomness from FILE (default=/dev/urandom)]),
|
||||
[ RANDOM_FILE="$withval" ],
|
||||
[
|
||||
dnl Check for random device
|
||||
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
|
||||
if test x$cross_compiling != xyes; then
|
||||
dnl Check for random device
|
||||
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
|
||||
else
|
||||
AC_MSG_WARN([skipped the /dev/urandom detection when cross-compiling])
|
||||
fi
|
||||
]
|
||||
)
|
||||
if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
|
||||
@@ -2517,6 +2540,7 @@ CURL_CHECK_FUNC_FREEIFADDRS
|
||||
CURL_CHECK_FUNC_FSETXATTR
|
||||
CURL_CHECK_FUNC_FTRUNCATE
|
||||
CURL_CHECK_FUNC_GETADDRINFO
|
||||
CURL_CHECK_FUNC_GAI_STRERROR
|
||||
CURL_CHECK_FUNC_GETHOSTBYADDR
|
||||
CURL_CHECK_FUNC_GETHOSTBYADDR_R
|
||||
CURL_CHECK_FUNC_GETHOSTBYNAME
|
||||
@@ -2593,7 +2617,7 @@ AC_CHECK_FUNCS([fork \
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
eval "ac_cv_func_$func=yes"
|
||||
AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$func]), [1],
|
||||
AC_DEFINE_UNQUOTED(XC_SH_TR_CPP([HAVE_$func]), [1],
|
||||
[Define to 1 if you have the $func function.])
|
||||
],[
|
||||
AC_MSG_RESULT([but still no])
|
||||
|
@@ -6,7 +6,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2001 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 2001 - 2011, 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
|
||||
@@ -94,7 +94,7 @@ while test $# -gt 0; do
|
||||
;;
|
||||
|
||||
--version)
|
||||
echo libcurl @VERSION@
|
||||
echo libcurl @CURLVERSION@
|
||||
exit 0
|
||||
;;
|
||||
|
||||
@@ -113,7 +113,7 @@ while test $# -gt 0; do
|
||||
# silent success
|
||||
exit 0
|
||||
else
|
||||
echo "requested version $checkfor is newer than existing @VERSION@"
|
||||
echo "requested version $checkfor is newer than existing @CURLVERSION@"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
29
docs/FAQ
29
docs/FAQ
@@ -36,7 +36,7 @@ FAQ
|
||||
3.2 How do I tell curl to resume a transfer?
|
||||
3.3 Why doesn't my posting using -F work?
|
||||
3.4 How do I tell curl to run custom FTP commands?
|
||||
3.5 How can I disable the Pragma: nocache header?
|
||||
3.5 How can I disable the Accept: */* header?
|
||||
3.6 Does curl support ASP, XML, XHTML or HTML version Y?
|
||||
3.7 Can I use curl to delete/rename a file through FTP?
|
||||
3.8 How do I tell curl to follow HTTP redirects?
|
||||
@@ -491,7 +491,6 @@ FAQ
|
||||
3.2 How do I tell curl to resume a transfer?
|
||||
|
||||
Curl supports resumed transfers both ways on both FTP and HTTP.
|
||||
|
||||
Try the -C option.
|
||||
|
||||
3.3 Why doesn't my posting using -F work?
|
||||
@@ -517,11 +516,11 @@ FAQ
|
||||
FTP commands without transferring anything. Therefore you must always specify
|
||||
a URL to transfer to/from even when doing custom FTP commands.
|
||||
|
||||
3.5 How can I disable the Pragma: nocache header?
|
||||
3.5 How can I disable the Accept: */* header?
|
||||
|
||||
You can change all internally generated headers by adding a replacement with
|
||||
the -H/--header option. By adding a header with empty contents you safely
|
||||
disable that one. Use -H "Pragma:" to disable that specific header.
|
||||
disable that one. Use -H "Accept:" to disable that specific header.
|
||||
|
||||
3.6 Does curl support ASP, XML, XHTML or HTML version Y?
|
||||
|
||||
@@ -565,6 +564,12 @@ FAQ
|
||||
install and use them, in the libcurl section of the curl web site:
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
All the various bindings to libcurl are made by other projects and people,
|
||||
outside of the cURL project. The cURL project itself only produces libcurl
|
||||
with its plain C API. If you don't find anywhere else to ask you can ask
|
||||
about bindings on the curl-library list too, but be prepared that people on
|
||||
that list may not know anything about bindings.
|
||||
|
||||
In October 2009, there were interfaces available for the following
|
||||
languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
|
||||
Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET,
|
||||
@@ -1152,6 +1157,11 @@ FAQ
|
||||
libcurl will reuse connections for all transfers that are made using the
|
||||
same libcurl handle.
|
||||
|
||||
When you use the easy interface, the connection cache is kept within the
|
||||
easy handle. If you instead use the multi interface, the connection cache
|
||||
will be kept within the multi handle and will be shared among all the easy
|
||||
handles that are used within the same multi handle.
|
||||
|
||||
5.7 Link errors when building libcurl on Windows!
|
||||
|
||||
You need to make sure that your project, and all the libraries (both static
|
||||
@@ -1260,14 +1270,13 @@ FAQ
|
||||
With the easy interface you make sure to return the correct error code from
|
||||
one of the callbacks, but none of them are instant. There is no function you
|
||||
can call from another thread or similar that will stop it immediately.
|
||||
Instead you need to make sure that one of the callbacks you use return an
|
||||
appropriate value that will stop the transfer.
|
||||
|
||||
Suitable callbacks that you can do this with include the progress callback,
|
||||
the read callback and the write callback.
|
||||
Instead, you need to make sure that one of the callbacks you use returns an
|
||||
appropriate value that will stop the transfer. Suitable callbacks that you
|
||||
can do this with include the progress callback, the read callback and the
|
||||
write callback.
|
||||
|
||||
If you're using the multi interface, you can also stop a transfer by
|
||||
removing the particular easy handle from the multi stack. At any moment you
|
||||
removing the particular easy handle from the multi stack at any moment you
|
||||
think the transfer is done.
|
||||
|
||||
5.14 Using C++ non-static functions for callbacks?
|
||||
|
@@ -14,6 +14,12 @@ Installing Binary Packages
|
||||
binary package. This document describes how to compile, build and install
|
||||
curl and libcurl from source code.
|
||||
|
||||
Building from git
|
||||
=================
|
||||
|
||||
If you get your code off a git repository, see the GIT-INFO file in the
|
||||
root directory for specific instructions on how to proceed.
|
||||
|
||||
UNIX
|
||||
====
|
||||
A normal unix installation is made in three or four steps (after you've
|
||||
@@ -213,7 +219,7 @@ Win32
|
||||
|
||||
set ZLIB_PATH=c:\zlib-1.2.5
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8r
|
||||
set LIBSSH2_PATH=c:\libssh2-1.2.7
|
||||
set LIBSSH2_PATH=c:\libssh2-1.2.8
|
||||
|
||||
ATTENTION: if you want to build with libssh2 support you have to use latest
|
||||
version 0.17 - previous versions will NOT work with 7.17.0 and later!
|
||||
|
@@ -18,6 +18,17 @@ Building with CMake
|
||||
CMake builds can be configured either from the command line, or from one
|
||||
of CMake's GUI's.
|
||||
|
||||
Important notice
|
||||
==================
|
||||
If you got your curl sources from a distribution tarball, make sure to
|
||||
delete the generic 'include/curl/curlbuild.h' file that comes with it:
|
||||
rm -f curl/include/curl/curlbuild.h
|
||||
|
||||
The purpose of this file is to provide reasonable definitions for systems
|
||||
where autoconfiguration is not available. CMake will create its own
|
||||
version of this file in its build directory. If the "generic" version
|
||||
is not deleted, weird build errors may occur on some systems.
|
||||
|
||||
Command Line CMake
|
||||
==================
|
||||
A command line build of Curl is similar to the autotools build of Curl. It
|
||||
@@ -32,9 +43,10 @@ Command Line CMake
|
||||
# variable prior to running CMake.
|
||||
cmake ../curl
|
||||
make
|
||||
# currently make test and make install are not implemented
|
||||
# currently make test is not implemented
|
||||
#make test
|
||||
#make install
|
||||
# Install to default location:
|
||||
make install
|
||||
|
||||
ccmake
|
||||
=========
|
||||
|
14
docs/THANKS
14
docs/THANKS
@@ -78,6 +78,7 @@ Bas Mevissen
|
||||
Ben Darnell
|
||||
Ben Greear
|
||||
Ben Madsen
|
||||
Ben Noordhuis
|
||||
Ben Van Hof
|
||||
Benbuck Nason
|
||||
Benjamin Gerard
|
||||
@@ -123,6 +124,7 @@ Chris Flerackers
|
||||
Chris Gaukroger
|
||||
Chris Maltby
|
||||
Chris Mumford
|
||||
Chris Smowton
|
||||
Christian Krause
|
||||
Christian Kurz
|
||||
Christian Robottom Reis
|
||||
@@ -320,6 +322,7 @@ Heikki Korpela
|
||||
Heinrich Ko
|
||||
Hendrik Visage
|
||||
Henrik Storner
|
||||
Henry Ludemann
|
||||
Hidemoto Nakada
|
||||
Hoi-Ho Chan
|
||||
Hongli Lai
|
||||
@@ -421,6 +424,7 @@ Jose Kahan
|
||||
Josef Wolf
|
||||
Josh Kapell
|
||||
Joshua Kwan
|
||||
Josue Andrade Gomes
|
||||
Juan F. Codagnone
|
||||
Juan Ignacio Herv<72>s
|
||||
Judson Bishop
|
||||
@@ -438,6 +442,7 @@ Kai-Uwe Rommel
|
||||
Kalle Vahlman
|
||||
Kamil Dudka
|
||||
Kang-Jin Lee
|
||||
Karl M
|
||||
Karl Moerder
|
||||
Karol Pietrzak
|
||||
Kaspar Brand
|
||||
@@ -499,6 +504,7 @@ Luong Dinh Dung
|
||||
Maciej Karpiuk
|
||||
Maciej W. Rozycki
|
||||
Manfred Schwarb
|
||||
Manuel Massing
|
||||
Marc Boucher
|
||||
Marc Kleine-Budde
|
||||
Marcel Roelofs
|
||||
@@ -506,6 +512,7 @@ Marcelo Juchem
|
||||
Marcin Konicki
|
||||
Marco G. Salvagno
|
||||
Marco Maggi
|
||||
Marcus Sundberg
|
||||
Marcus Webster
|
||||
Mario Schroeder
|
||||
Mark Butler
|
||||
@@ -545,6 +552,7 @@ Mauro Iorio
|
||||
Max Katsev
|
||||
Maxim Ivanov
|
||||
Maxim Perenesenko
|
||||
Mehmet Bozkurt
|
||||
Mekonikum
|
||||
Mettgut Jamalla
|
||||
Michael Benedict
|
||||
@@ -666,6 +674,7 @@ Rafa Muyo
|
||||
Rafael Sagula
|
||||
Rainer Canavan
|
||||
Rainer Koenig
|
||||
Rajesh Naganathan
|
||||
Ralf S. Engelschall
|
||||
Ralph Beckmann
|
||||
Ralph Mitchell
|
||||
@@ -720,6 +729,7 @@ Ruslan Gazizov
|
||||
Rutger Hofman
|
||||
Ryan Chan
|
||||
Ryan Nelson
|
||||
Ryan Schmidt
|
||||
S. Moonesamy
|
||||
Salvador D<>vila
|
||||
Salvatore Sorrentino
|
||||
@@ -730,6 +740,7 @@ Samuel Listopad
|
||||
Samuel Thibault
|
||||
Sander Gates
|
||||
Sandor Feldi
|
||||
Saqib Ali
|
||||
Saul good
|
||||
Scott Barrett
|
||||
Scott Cantor
|
||||
@@ -796,8 +807,10 @@ Tim Chen
|
||||
Tim Costello
|
||||
Tim Newsome
|
||||
Tim Sneddon
|
||||
Tinus van den Berg
|
||||
Tobias Rundstr<74>m
|
||||
Toby Peterson
|
||||
Todd A Ouska
|
||||
Todd Kulesza
|
||||
Todd Vierling
|
||||
Tom Benoist
|
||||
@@ -833,6 +846,7 @@ Vincent Bronner
|
||||
Vincent Le Normand
|
||||
Vincent Penquerc'h
|
||||
Vincent Sanders
|
||||
Vincent Torri
|
||||
Vlad Grachov
|
||||
Vlad Ureche
|
||||
Vladimir Lazarenko
|
||||
|
920
docs/curl.1
920
docs/curl.1
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,6 @@
|
||||
#else
|
||||
# ifdef __VMS
|
||||
typedef int intptr_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, 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
|
||||
@@ -31,8 +31,8 @@ curl_easy_escape - URL encodes the given string
|
||||
.SH DESCRIPTION
|
||||
This function converts the given input string to an URL encoded string and
|
||||
returns that as a new allocated string. All input characters that are not a-z,
|
||||
A-Z or 0-9 are converted to their "URL escaped" version (%NN where NN is a
|
||||
two-digit hexadecimal number).
|
||||
A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" version
|
||||
(%NN where NN is a two-digit hexadecimal number).
|
||||
|
||||
If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_escape(3)\fP
|
||||
uses strlen() on the input \fBurl\fP to find out the size.
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, 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
|
||||
@@ -80,12 +80,13 @@ waits in line for the pipeline and more. (Added in 7.19.0)
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the file transfer is just about to begin. This includes all
|
||||
pre-transfer commands and negotiations that are specific to the particular
|
||||
protocol(s) involved.
|
||||
protocol(s) involved. It does \fInot\fP involve the sending of the protocol-
|
||||
specific request that triggers a transfer.
|
||||
.IP CURLINFO_STARTTRANSFER_TIME
|
||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||
start until the first byte is just about to be transferred. This includes
|
||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
||||
the result.
|
||||
start until the first byte is received by libcurl. This includes
|
||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate the
|
||||
result.
|
||||
.IP CURLINFO_REDIRECT_TIME
|
||||
Pass a pointer to a double to receive the total time, in seconds, it took for
|
||||
all redirection steps include name lookup, connect, pretransfer and transfer
|
||||
@@ -275,7 +276,7 @@ file transfer is just about to begin. This includes all pre-transfer commands
|
||||
and negotiations that are specific to the particular protocol(s) involved.
|
||||
.IP STARTTRANSFER
|
||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
||||
first byte is just about to be transferred.
|
||||
first byte is received by libcurl.
|
||||
.IP TOTAL
|
||||
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
||||
.IP REDIRECT
|
||||
|
@@ -68,8 +68,9 @@ A parameter set to 1 tells the library to include the header in the body
|
||||
output. This is only relevant for protocols that actually have headers
|
||||
preceding the data (like HTTP).
|
||||
.IP CURLOPT_NOPROGRESS
|
||||
A parameter set to 1 tells the library to shut off the built-in progress meter
|
||||
completely.
|
||||
Pass a long. If set to 1, it tells the library to shut off the progress meter
|
||||
completely. It will also present the \fICURLOPT_PROGRESSFUNCTION\fP from
|
||||
getting called.
|
||||
|
||||
Future versions of libcurl are likely to not have any built-in progress meter
|
||||
at all.
|
||||
@@ -105,18 +106,18 @@ This feature is only supported by the FTP download for now.
|
||||
|
||||
A brief introduction of its syntax follows:
|
||||
.RS
|
||||
.IP "\fB*\fP - ASTERISK"
|
||||
.IP "* - ASTERISK"
|
||||
\&ftp://example.com/some/path/\fB*.txt\fP (for all txt's from the root
|
||||
directory)
|
||||
.RE
|
||||
.RS
|
||||
.IP "\fB?\fP - QUESTION MARK"
|
||||
.IP "? - QUESTION MARK"
|
||||
Question mark matches any (exactly one) character.
|
||||
|
||||
\&ftp://example.com/some/path/\fBphoto?.jpeg\fP
|
||||
.RE
|
||||
.RS
|
||||
.IP "\fB[\fP - BRACKET EXPRESSION"
|
||||
.IP "[ - BRACKET EXPRESSION"
|
||||
The left bracket opens a bracket expression. The question mark and asterisk have
|
||||
no special meaning in a bracket expression. Each bracket expression ends by the
|
||||
right bracket and matches exactly one character. Some examples follow:
|
||||
@@ -145,7 +146,7 @@ Using the rules above, a file name pattern can be constructed:
|
||||
.SH CALLBACK OPTIONS
|
||||
.IP CURLOPT_WRITEFUNCTION
|
||||
Function pointer that should match the following prototype: \fBsize_t
|
||||
function( void *ptr, size_t size, size_t nmemb, void *userdata);\fP This
|
||||
function( char *ptr, size_t size, size_t nmemb, void *userdata);\fP This
|
||||
function gets called by libcurl as soon as there is data received that needs
|
||||
to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
||||
multiplied with \fInmemb\fP, it will not be zero terminated. Return the number
|
||||
@@ -307,6 +308,17 @@ address blacklisting. The default behavior is:
|
||||
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||
argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP.
|
||||
(Option added in 7.17.1.)
|
||||
.IP CURLOPT_CLOSESOCKETFUNCTION
|
||||
Function pointer that should match the \fIcurl_closesocket_callback\fP
|
||||
prototype found in \fI<curl/curl.h>\fP. This function gets called by libcurl
|
||||
instead of the \fIclose(3)\fP or \fIclosesocket(3)\fP call when sockets are
|
||||
closed (not for any other file descriptors). This is pretty much the reverse
|
||||
to the \fICURLOPT_OPENSOCKETFUNCTION\fP option. Return 0 to signal success and
|
||||
1 if there was an error. (Option added in 7.21.7)
|
||||
.IP CURLOPT_CLOSESOCKETDATA
|
||||
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||
argument in the opensocket callback set with
|
||||
\fICURLOPT_CLOSESOCKETFUNCTION\fP. (Option added in 7.21.7)
|
||||
.IP CURLOPT_PROGRESSFUNCTION
|
||||
Function pointer that should match the \fIcurl_progress_callback\fP prototype
|
||||
found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of
|
||||
@@ -331,10 +343,10 @@ Function pointer that should match the following prototype: \fIsize_t
|
||||
function( void *ptr, size_t size, size_t nmemb, void *userdata);\fP. This
|
||||
function gets called by libcurl as soon as it has received header data. The
|
||||
header callback will be called once for each header and only complete header
|
||||
lines are passed on to the callback. Parsing headers should be easy enough
|
||||
using this. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
||||
multiplied with \fInmemb\fP. Do not assume that the header line is zero
|
||||
terminated! The pointer named \fIuserdata\fP is the one you set with the
|
||||
lines are passed on to the callback. Parsing headers is very easy using
|
||||
this. The size of the data pointed to by \fIptr\fP is \fIsize\fP multiplied
|
||||
with \fInmemb\fP. Do not assume that the header line is zero terminated! The
|
||||
pointer named \fIuserdata\fP is the one you set with the
|
||||
\fICURLOPT_WRITEHEADER\fP option. The callback function must return the number
|
||||
of bytes actually taken care of. If that amount differs from the amount passed
|
||||
to your function, it'll signal an error to the library. This will abort the
|
||||
@@ -353,19 +365,20 @@ negotiation. If you need to operate on only the headers from the final
|
||||
response, you will need to collect headers in the callback yourself and use
|
||||
HTTP status lines, for example, to delimit response boundaries.
|
||||
|
||||
Since 7.14.1: When a server sends a chunked encoded transfer, it may contain a
|
||||
trailer. That trailer is identical to a HTTP header and if such a trailer is
|
||||
received it is passed to the application using this callback as well. There
|
||||
are several ways to detect it being a trailer and not an ordinary header: 1)
|
||||
it comes after the response-body. 2) it comes after the final header line (CR
|
||||
LF) 3) a Trailer: header among the response-headers mention what header to
|
||||
expect in the trailer.
|
||||
When a server sends a chunked encoded transfer, it may contain a trailer. That
|
||||
trailer is identical to a HTTP header and if such a trailer is received it is
|
||||
passed to the application using this callback as well. There are several ways
|
||||
to detect it being a trailer and not an ordinary header: 1) it comes after the
|
||||
response-body. 2) it comes after the final header line (CR LF) 3) a Trailer:
|
||||
header among the regular response-headers mention what header(s) to expect in
|
||||
the trailer.
|
||||
.IP CURLOPT_WRITEHEADER
|
||||
(This option is also known as \fBCURLOPT_HEADERDATA\fP) Pass a pointer to be
|
||||
used to write the header part of the received data to. If you don't use your
|
||||
own callback to take care of the writing, this must be a valid FILE *. See
|
||||
also the \fICURLOPT_HEADERFUNCTION\fP option above on how to set a custom
|
||||
get-all-headers callback.
|
||||
used to write the header part of the received data to. If you don't use
|
||||
\fICURLOPT_WRITEFUNCTION\fP or \fICURLOPT_HEADERFUNCTION\fP to take care of
|
||||
the writing, this must be a valid FILE * as the internal default will then be
|
||||
a plain fwrite(). See also the \fICURLOPT_HEADERFUNCTION\fP option above on
|
||||
how to set a custom get-all-headers callback.
|
||||
.IP CURLOPT_DEBUGFUNCTION
|
||||
Function pointer that should match the following prototype: \fIint
|
||||
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
||||
@@ -632,6 +645,13 @@ use of a proxy, even if there is an environment variable set for it.
|
||||
Since 7.14.1, the proxy host string given in environment variables can be
|
||||
specified the exact same way as the proxy can be set with \fICURLOPT_PROXY\fP,
|
||||
include protocol prefix (http://) and embedded user + password.
|
||||
|
||||
Since 7.21.7, the proxy string may be specified with a protocol:// prefix to
|
||||
specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or
|
||||
socks5h:// (the last one to enable socks5 and asking the proxy to do the
|
||||
resolving, also known as CURLPROXY_SOCKS5_HOSTNAME type) to request the
|
||||
specific SOCKS version to be used. No protocol specified, http:// and all
|
||||
others will be treated as HTTP proxies.
|
||||
.IP CURLOPT_PROXYPORT
|
||||
Pass a long with this option to set the proxy port to connect to unless it is
|
||||
specified in the proxy string \fICURLOPT_PROXY\fP.
|
||||
@@ -641,6 +661,11 @@ this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP (added in 7.19.4),
|
||||
\fICURLPROXY_SOCKS4\fP (added in 7.15.2), \fICURLPROXY_SOCKS5\fP,
|
||||
\fICURLPROXY_SOCKS4A\fP (added in 7.18.0) and \fICURLPROXY_SOCKS5_HOSTNAME\fP
|
||||
(added in 7.18.0). The HTTP type is default. (Added in 7.10)
|
||||
|
||||
If you set \fBCURLOPT_PROXYTYPE\fP to \fICURLPROXY_HTTP_1_0\fP, it will only
|
||||
affect how libcurl speaks to a proxy when CONNECT is used. The HTTP version
|
||||
used for "regular" HTTP requests is instead controled with
|
||||
\fICURLOPT_HTTP_VERSION\fP.
|
||||
.IP CURLOPT_NOPROXY
|
||||
Pass a pointer to a zero terminated string. The should be a comma- separated
|
||||
list of hosts which do not use a proxy, if one is specified. The only
|
||||
@@ -916,7 +941,7 @@ work. (Added in 7.10.7)
|
||||
Pass a parameter set to 1 to enable this. When enabled, libcurl will
|
||||
automatically set the Referer: field in requests where it follows a Location:
|
||||
redirect.
|
||||
.IP CURLOPT_ENCODING
|
||||
.IP CURLOPT_ACCEPT_ENCODING
|
||||
Sets the contents of the Accept-Encoding: header sent in an HTTP request, and
|
||||
enables decoding of a response when a Content-Encoding: header is received.
|
||||
Three encodings are supported: \fIidentity\fP, which does nothing,
|
||||
@@ -928,6 +953,21 @@ 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.
|
||||
|
||||
(This option was called CURLOPT_ENCODING before 7.21.6)
|
||||
.IP CURLOPT_TRANSFER_ENCODING
|
||||
Adds a request for compressed Transfer Encoding in the outgoing HTTP
|
||||
request. If the server supports this and so desires, it can respond with the
|
||||
HTTP resonse sent using a compressed Transfer-Encoding that will be
|
||||
automatically uncompressed by libcurl on receival.
|
||||
|
||||
Transfer-Encoding differs slightly from the Content-Encoding you ask for with
|
||||
\fBCURLOPT_ACCEPT_ENCODING\fP in that a Transfer-Encoding is strictly meant to
|
||||
be for the transfer and thus MUST be decoded before the data arrives in the
|
||||
client. Traditionally, Transfer-Encoding has been much less used and supported
|
||||
by both HTTP clients and HTTP servers.
|
||||
|
||||
(Added in 7.21.6)
|
||||
.IP CURLOPT_FOLLOWLOCATION
|
||||
A parameter set to 1 tells the library to follow any Location: header that the
|
||||
server sends as part of an HTTP header.
|
||||
@@ -2078,13 +2118,15 @@ libcurl will reject the connection to the host unless the md5sums match. This
|
||||
option is only for SCP and SFTP transfers. (Added in 7.17.1)
|
||||
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
||||
Pass a char * pointing to a file name for your public key. If not used,
|
||||
libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
|
||||
(Added in 7.16.1)
|
||||
libcurl defaults to \fB$HOME/.ssh/id_dsa.pub\fP if the HOME environment
|
||||
variable is set, and just "id_dsa.pub" in the current directory if HOME is not
|
||||
set. (Added in 7.16.1)
|
||||
.IP CURLOPT_SSH_PRIVATE_KEYFILE
|
||||
Pass a char * pointing to a file name for your private key. If not used,
|
||||
libcurl defaults to using \fB~/.ssh/id_dsa\fP. If the file is
|
||||
password-protected, set the password with \fICURLOPT_KEYPASSWD\fP. (Added in
|
||||
7.16.1)
|
||||
libcurl defaults to \fB$HOME/.ssh/id_dsa\fP if the HOME environment variable
|
||||
is set, and just "id_dsa" in the current directory if HOME is not set. If the
|
||||
file is password-protected, set the password with
|
||||
\fICURLOPT_KEYPASSWD\fP. (Added in 7.16.1)
|
||||
.IP CURLOPT_SSH_KNOWNHOSTS
|
||||
Pass a pointer to a zero terminated string holding the file name of the
|
||||
known_host file to use. The known_hosts file should use the OpenSSH file
|
||||
|
@@ -30,18 +30,19 @@ curl_formadd - add a section to a multipart/formdata HTTP POST
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
curl_formadd() is used to append sections when building a multipart/formdata
|
||||
HTTP POST (sometimes referred to as RFC2388-style posts). Append one section at
|
||||
a time until you've added all the sections you want included and then you pass
|
||||
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
||||
left as set to allow repeated invokes to find the end of the list faster.
|
||||
HTTP POST (sometimes referred to as RFC2388-style posts). Append one section
|
||||
at a time until you've added all the sections you want included and then you
|
||||
pass the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||
\fIlastitem\fP is set after each \fIcurl_formadd(3)\fP call and on repeated
|
||||
invokes it should be left as set to allow repeated invokes to find the end of
|
||||
the list faster.
|
||||
|
||||
After the \fIlastitem\fP pointer follow the real arguments.
|
||||
|
||||
The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to
|
||||
The pointers \fIfirstitem\fP and \fIlastitem\fP should both be pointing to
|
||||
NULL in the first call to this function. All list-data will be allocated by
|
||||
the function itself. You must call \fIcurl_formfree(3)\fP after the form post
|
||||
has been done to free the resources.
|
||||
the function itself. You must call \fIcurl_formfree(3)\fP on the
|
||||
\fIfirstitem\P after the form post has been done to free the resources.
|
||||
|
||||
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
|
||||
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
|
||||
|
@@ -31,6 +31,13 @@ curl_formfree - free a previously build multipart/formdata HTTP POST chain
|
||||
curl_formfree() is used to clean up data previously built/appended with
|
||||
\fIcurl_formadd(3)\fP. This must be called when the data has been used, which
|
||||
typically means after \fIcurl_easy_perform(3)\fP has been called.
|
||||
|
||||
The pointer to free is the same pointer you passed to the
|
||||
\fBCURLOPT_HTTPPOST\fP option, which is the \fIfirstitem\fP pointer from the
|
||||
\fIcurl_formadd(3)\fP invoke(s).
|
||||
|
||||
\fBform\fP is the pointer as returned from a previous call to
|
||||
\fIcurl_formadd(3)\fP and may be NULL.
|
||||
.SH RETURN VALUE
|
||||
None
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -23,24 +23,27 @@
|
||||
.SH NAME
|
||||
curl_formget - serialize a previously built multipart/formdata HTTP POST chain
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "void curl_formget(struct curl_httppost *" form, " void *" arg,
|
||||
.BI " curl_formget_callback " append ");"
|
||||
.ad
|
||||
|
||||
void curl_formget(struct curl_httppost * form, void *userp,
|
||||
curl_formget_callback append );
|
||||
.SH DESCRIPTION
|
||||
curl_formget() is used to serialize data previously built/appended with
|
||||
\fIcurl_formadd(3)\fP. Accepts a void pointer as second argument which will be
|
||||
passed to the curl_formget_callback function.
|
||||
\fIcurl_formadd(3)\fP. Accepts a void pointer as second argument named
|
||||
\fIuserp\fP which will be passed as the first argument to the
|
||||
curl_formget_callback function.
|
||||
|
||||
.BI "typedef size_t (*curl_formget_callback)(void *" arg, " const char *" buf,
|
||||
.BI "typedef size_t (*curl_formget_callback)(void *" userp, " const char *" buf,
|
||||
.BI " size_t " len ");"
|
||||
.nf
|
||||
|
||||
The curl_formget_callback will be executed for each part of the HTTP POST
|
||||
chain. The void *arg pointer will be the one passed as second argument to
|
||||
curl_formget(). The character buffer passed to it must not be freed. The
|
||||
chain. The character buffer passed to the callback must not be freed. The
|
||||
callback should return the buffer length passed to it on success.
|
||||
|
||||
If the \fBCURLFORM_STREAM\fP option is used in the formpost, it will prevent
|
||||
\fIcurl_formget(3)\fP from working until you've performed the actual HTTP
|
||||
request as only then will libcurl get the actual read callback to use!
|
||||
.SH RETURN VALUE
|
||||
0 means everything was ok, non-zero means an error occurred
|
||||
.SH EXAMPLE
|
||||
@@ -52,6 +55,7 @@ callback should return the buffer length passed to it on success.
|
||||
(*(size_t *) arg) += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t print_httppost(struct curl_httppost *post)
|
||||
{
|
||||
size_t total_size = 0;
|
||||
|
@@ -282,6 +282,7 @@ CURLOPTTYPE_FUNCTIONPOINT 7.1
|
||||
CURLOPTTYPE_LONG 7.1
|
||||
CURLOPTTYPE_OBJECTPOINT 7.1
|
||||
CURLOPTTYPE_OFF_T 7.11.0
|
||||
CURLOPT_ACCEPT_ENCODING 7.21.6
|
||||
CURLOPT_ADDRESS_SCOPE 7.19.0
|
||||
CURLOPT_APPEND 7.17.0
|
||||
CURLOPT_AUTOREFERER 7.1
|
||||
@@ -294,6 +295,8 @@ CURLOPT_CHUNK_DATA 7.21.0
|
||||
CURLOPT_CHUNK_END_FUNCTION 7.21.0
|
||||
CURLOPT_CLOSEFUNCTION 7.7 7.11.1 7.15.5
|
||||
CURLOPT_CLOSEPOLICY 7.7 7.16.1
|
||||
CURLOPT_CLOSESOCKETDATA 7.21.7
|
||||
CURLOPT_CLOSESOCKETFUNCTION 7.21.7
|
||||
CURLOPT_CONNECTTIMEOUT 7.7
|
||||
CURLOPT_CONNECTTIMEOUT_MS 7.16.2
|
||||
CURLOPT_CONNECT_ONLY 7.15.2
|
||||
@@ -485,6 +488,7 @@ CURLOPT_TLSAUTH_PASSWORD 7.21.4
|
||||
CURLOPT_TLSAUTH_TYPE 7.21.4
|
||||
CURLOPT_TLSAUTH_USERNAME 7.21.4
|
||||
CURLOPT_TRANSFERTEXT 7.1.1
|
||||
CURLOPT_TRANSFER_ENCODING 7.21.6
|
||||
CURLOPT_UNRESTRICTED_AUTH 7.10.4
|
||||
CURLOPT_UPLOAD 7.1
|
||||
CURLOPT_URL 7.1
|
||||
|
@@ -36,7 +36,7 @@ The following notes apply to libcurl version 7.19.0 and later.
|
||||
* If you intend to distribute an already compiled libcurl library you _MUST_
|
||||
also distribute along with it the generated curl/curlbuild.h which has been
|
||||
used to compile it. Otherwise the library will be of no use for the users of
|
||||
the library that you have built. It is _your_ responsability to provide this
|
||||
the library that you have built. It is _your_ responsibility to provide this
|
||||
file. No one at the cURL project can know how you have built the library.
|
||||
|
||||
* File curl/curlbuild.h includes platform and configuration dependent info,
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#
|
||||
###########################################################################
|
||||
pkginclude_HEADERS = \
|
||||
curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h \
|
||||
curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
|
||||
typecheck-gcc.h curlbuild.h curlrules.h
|
||||
|
||||
pkgincludedir= $(includedir)/curl
|
||||
@@ -44,3 +44,10 @@ EXTRA_DIST = curlbuild.h.in
|
||||
|
||||
DISTCLEANFILES = curlbuild.h
|
||||
|
||||
checksrc:
|
||||
@@PERL@ $(top_srcdir)/lib/checksrc.pl -Wcurlbuild.h -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) $(EXTRA_DIST)
|
||||
|
||||
if CURLDEBUG
|
||||
# for debug builds, we scan the sources on all regular make invokes
|
||||
all-local: checksrc
|
||||
endif
|
||||
|
@@ -341,6 +341,9 @@ typedef curl_socket_t
|
||||
curlsocktype purpose,
|
||||
struct curl_sockaddr *address);
|
||||
|
||||
typedef int
|
||||
(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
|
||||
|
||||
typedef enum {
|
||||
CURLIOE_OK, /* I/O operation successful */
|
||||
CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
|
||||
@@ -467,7 +470,7 @@ typedef enum {
|
||||
CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
|
||||
CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
|
||||
CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
|
||||
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */
|
||||
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
|
||||
CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
|
||||
CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
|
||||
CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||
@@ -507,7 +510,7 @@ typedef enum {
|
||||
7.19.0) */
|
||||
CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
||||
CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
|
||||
CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Identifiers */
|
||||
CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
|
||||
CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
|
||||
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||
|
||||
@@ -517,7 +520,8 @@ typedef enum {
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
/* Backwards compatibility with older names */
|
||||
/* compatibility with older names */
|
||||
#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
|
||||
|
||||
/* The following were added in 7.21.5, April 2011 */
|
||||
#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
|
||||
@@ -528,7 +532,7 @@ typedef enum {
|
||||
|
||||
/* The following were added in 7.17.0 */
|
||||
/* These are scheduled to disappear by 2009 */
|
||||
#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */
|
||||
#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
|
||||
#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
|
||||
#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
|
||||
#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
|
||||
@@ -754,7 +758,7 @@ typedef enum {
|
||||
#endif
|
||||
|
||||
#ifdef CURL_ISOCPP
|
||||
#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
|
||||
#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
|
||||
#else
|
||||
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
||||
#define LONG CURLOPTTYPE_LONG
|
||||
@@ -923,7 +927,7 @@ typedef enum {
|
||||
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
|
||||
CINIT(UPLOAD, LONG, 46), /* this is an upload */
|
||||
CINIT(POST, LONG, 47), /* HTTP POST method */
|
||||
CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */
|
||||
CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */
|
||||
|
||||
CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */
|
||||
|
||||
@@ -990,8 +994,7 @@ typedef enum {
|
||||
/* Max amount of cached alive connections */
|
||||
CINIT(MAXCONNECTS, LONG, 71),
|
||||
|
||||
/* What policy to use when closing connections when the cache is filled
|
||||
up */
|
||||
/* 72 - DEPRECATED */
|
||||
CINIT(CLOSEPOLICY, LONG, 72),
|
||||
|
||||
/* 73 = OBSOLETE */
|
||||
@@ -1103,8 +1106,9 @@ typedef enum {
|
||||
CINIT(PROXYTYPE, LONG, 101),
|
||||
|
||||
/* Set the Accept-Encoding string. Use this to tell a server you would like
|
||||
the response to be compressed. */
|
||||
CINIT(ENCODING, OBJECTPOINT, 102),
|
||||
the response to be compressed. Before 7.21.6, this was known as
|
||||
CURLOPT_ENCODING */
|
||||
CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),
|
||||
|
||||
/* Set pointer to private data */
|
||||
CINIT(PRIVATE, OBJECTPOINT, 103),
|
||||
@@ -1117,8 +1121,8 @@ typedef enum {
|
||||
and password to whatever host the server decides. */
|
||||
CINIT(UNRESTRICTED_AUTH, LONG, 105),
|
||||
|
||||
/* Specifically 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
|
||||
/* Specifically 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),
|
||||
|
||||
@@ -1462,6 +1466,23 @@ typedef enum {
|
||||
/* Set authentication type for authenticated TLS */
|
||||
CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206),
|
||||
|
||||
/* Set to 1 to enable the "TE:" header in HTTP requests to ask for
|
||||
compressed transfer-encoded responses. Set to 0 to disable the use of TE:
|
||||
in outgoing requests. The current default is 0, but it might change in a
|
||||
future libcurl release.
|
||||
|
||||
libcurl will ask for the compressed methods it knows of, and if that
|
||||
isn't any, it will not ask for transfer-encoding at all even if this
|
||||
option is set to 1.
|
||||
|
||||
*/
|
||||
CINIT(TRANSFER_ENCODING, LONG, 207),
|
||||
|
||||
/* Callback function for closing socket (instead of close(2)). The callback
|
||||
should have type curl_closesocket_callback */
|
||||
CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
|
||||
CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1690,7 +1711,8 @@ CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
* Should return the buffer length passed to it as the argument "len" on
|
||||
* success.
|
||||
*/
|
||||
typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len);
|
||||
typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
|
||||
size_t len);
|
||||
|
||||
/*
|
||||
* NAME curl_formget()
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -58,52 +58,52 @@
|
||||
/* ================================================================ */
|
||||
|
||||
#ifdef CURL_SIZEOF_LONG
|
||||
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
||||
#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_CURL_OFF_T
|
||||
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_CURL_OFF_TU
|
||||
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_OFF_T
|
||||
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SIZEOF_CURL_OFF_T
|
||||
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SUFFIX_CURL_OFF_T
|
||||
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
||||
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
||||
#endif
|
||||
|
||||
|
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.21.5-DEV"
|
||||
#define LIBCURL_VERSION "7.21.7-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 21
|
||||
#define LIBCURL_VERSION_PATCH 5
|
||||
#define LIBCURL_VERSION_PATCH 7
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -53,7 +53,7 @@
|
||||
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 0x071505
|
||||
#define LIBCURL_VERSION_NUM 0x071507
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@@ -53,8 +53,8 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
||||
*
|
||||
* Creates a new curl session handle with the same options set for the handle
|
||||
* passed in. Duplicating a handle could only be a matter of cloning data and
|
||||
* options, internal state info and things like persistant connections cannot
|
||||
* be transfered. It is useful in multithreaded applications when you can run
|
||||
* options, internal state info and things like persistent connections cannot
|
||||
* be transferred. It is useful in multithreaded applications when you can run
|
||||
* curl_easy_duphandle() for each new thread to avoid a series of identical
|
||||
* curl_easy_setopt() invokes in every thread.
|
||||
*/
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -41,66 +41,66 @@
|
||||
#define curl_easy_setopt(handle, option, value) \
|
||||
__extension__ ({ \
|
||||
__typeof__ (option) _curl_opt = option; \
|
||||
if (__builtin_constant_p(_curl_opt)) { \
|
||||
if (_curl_is_long_option(_curl_opt)) \
|
||||
if (!_curl_is_long(value)) \
|
||||
if(__builtin_constant_p(_curl_opt)) { \
|
||||
if(_curl_is_long_option(_curl_opt)) \
|
||||
if(!_curl_is_long(value)) \
|
||||
_curl_easy_setopt_err_long(); \
|
||||
if (_curl_is_off_t_option(_curl_opt)) \
|
||||
if (!_curl_is_off_t(value)) \
|
||||
if(_curl_is_off_t_option(_curl_opt)) \
|
||||
if(!_curl_is_off_t(value)) \
|
||||
_curl_easy_setopt_err_curl_off_t(); \
|
||||
if (_curl_is_string_option(_curl_opt)) \
|
||||
if (!_curl_is_string(value)) \
|
||||
if(_curl_is_string_option(_curl_opt)) \
|
||||
if(!_curl_is_string(value)) \
|
||||
_curl_easy_setopt_err_string(); \
|
||||
if (_curl_is_write_cb_option(_curl_opt)) \
|
||||
if (!_curl_is_write_cb(value)) \
|
||||
if(_curl_is_write_cb_option(_curl_opt)) \
|
||||
if(!_curl_is_write_cb(value)) \
|
||||
_curl_easy_setopt_err_write_callback(); \
|
||||
if ((_curl_opt) == CURLOPT_READFUNCTION) \
|
||||
if (!_curl_is_read_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_READFUNCTION) \
|
||||
if(!_curl_is_read_cb(value)) \
|
||||
_curl_easy_setopt_err_read_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
||||
if (!_curl_is_ioctl_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
||||
if(!_curl_is_ioctl_cb(value)) \
|
||||
_curl_easy_setopt_err_ioctl_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
||||
if (!_curl_is_sockopt_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
||||
if(!_curl_is_sockopt_cb(value)) \
|
||||
_curl_easy_setopt_err_sockopt_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||
if (!_curl_is_opensocket_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||
if(!_curl_is_opensocket_cb(value)) \
|
||||
_curl_easy_setopt_err_opensocket_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
||||
if (!_curl_is_progress_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
||||
if(!_curl_is_progress_cb(value)) \
|
||||
_curl_easy_setopt_err_progress_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
||||
if (!_curl_is_debug_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
||||
if(!_curl_is_debug_cb(value)) \
|
||||
_curl_easy_setopt_err_debug_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||
if (!_curl_is_ssl_ctx_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||
if(!_curl_is_ssl_ctx_cb(value)) \
|
||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
||||
if (_curl_is_conv_cb_option(_curl_opt)) \
|
||||
if (!_curl_is_conv_cb(value)) \
|
||||
if(_curl_is_conv_cb_option(_curl_opt)) \
|
||||
if(!_curl_is_conv_cb(value)) \
|
||||
_curl_easy_setopt_err_conv_cb(); \
|
||||
if ((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
||||
if (!_curl_is_seek_cb(value)) \
|
||||
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
||||
if(!_curl_is_seek_cb(value)) \
|
||||
_curl_easy_setopt_err_seek_cb(); \
|
||||
if (_curl_is_cb_data_option(_curl_opt)) \
|
||||
if (!_curl_is_cb_data(value)) \
|
||||
if(_curl_is_cb_data_option(_curl_opt)) \
|
||||
if(!_curl_is_cb_data(value)) \
|
||||
_curl_easy_setopt_err_cb_data(); \
|
||||
if ((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
||||
if (!_curl_is_error_buffer(value)) \
|
||||
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
||||
if(!_curl_is_error_buffer(value)) \
|
||||
_curl_easy_setopt_err_error_buffer(); \
|
||||
if ((_curl_opt) == CURLOPT_STDERR) \
|
||||
if (!_curl_is_FILE(value)) \
|
||||
if((_curl_opt) == CURLOPT_STDERR) \
|
||||
if(!_curl_is_FILE(value)) \
|
||||
_curl_easy_setopt_err_FILE(); \
|
||||
if (_curl_is_postfields_option(_curl_opt)) \
|
||||
if (!_curl_is_postfields(value)) \
|
||||
if(_curl_is_postfields_option(_curl_opt)) \
|
||||
if(!_curl_is_postfields(value)) \
|
||||
_curl_easy_setopt_err_postfields(); \
|
||||
if ((_curl_opt) == CURLOPT_HTTPPOST) \
|
||||
if (!_curl_is_arr((value), struct curl_httppost)) \
|
||||
if((_curl_opt) == CURLOPT_HTTPPOST) \
|
||||
if(!_curl_is_arr((value), struct curl_httppost)) \
|
||||
_curl_easy_setopt_err_curl_httpost(); \
|
||||
if (_curl_is_slist_option(_curl_opt)) \
|
||||
if (!_curl_is_arr((value), struct curl_slist)) \
|
||||
if(_curl_is_slist_option(_curl_opt)) \
|
||||
if(!_curl_is_arr((value), struct curl_slist)) \
|
||||
_curl_easy_setopt_err_curl_slist(); \
|
||||
if ((_curl_opt) == CURLOPT_SHARE) \
|
||||
if (!_curl_is_ptr((value), CURLSH)) \
|
||||
if((_curl_opt) == CURLOPT_SHARE) \
|
||||
if(!_curl_is_ptr((value), CURLSH)) \
|
||||
_curl_easy_setopt_err_CURLSH(); \
|
||||
} \
|
||||
curl_easy_setopt(handle, _curl_opt, value); \
|
||||
@@ -111,18 +111,18 @@ __extension__ ({ \
|
||||
#define curl_easy_getinfo(handle, info, arg) \
|
||||
__extension__ ({ \
|
||||
__typeof__ (info) _curl_info = info; \
|
||||
if (__builtin_constant_p(_curl_info)) { \
|
||||
if (_curl_is_string_info(_curl_info)) \
|
||||
if (!_curl_is_arr((arg), char *)) \
|
||||
if(__builtin_constant_p(_curl_info)) { \
|
||||
if(_curl_is_string_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), char *)) \
|
||||
_curl_easy_getinfo_err_string(); \
|
||||
if (_curl_is_long_info(_curl_info)) \
|
||||
if (!_curl_is_arr((arg), long)) \
|
||||
if(_curl_is_long_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), long)) \
|
||||
_curl_easy_getinfo_err_long(); \
|
||||
if (_curl_is_double_info(_curl_info)) \
|
||||
if (!_curl_is_arr((arg), double)) \
|
||||
if(_curl_is_double_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), double)) \
|
||||
_curl_easy_getinfo_err_double(); \
|
||||
if (_curl_is_slist_info(_curl_info)) \
|
||||
if (!_curl_is_arr((arg), struct curl_slist *)) \
|
||||
if(_curl_is_slist_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), struct curl_slist *)) \
|
||||
_curl_easy_getinfo_err_curl_slist(); \
|
||||
} \
|
||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
||||
@@ -149,7 +149,8 @@ _CURL_WARNING(_curl_easy_setopt_err_long,
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
|
||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_string,
|
||||
"curl_easy_setopt expects a string (char* or char[]) argument for this option"
|
||||
"curl_easy_setopt expects a "
|
||||
"string (char* or char[]) argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_write_callback,
|
||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
||||
@@ -160,7 +161,8 @@ _CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
|
||||
_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
|
||||
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
|
||||
"curl_easy_setopt expects a curl_opensocket_callback argument for this option"
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_opensocket_callback argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
|
||||
"curl_easy_setopt expects a curl_progress_callback argument for this option")
|
||||
@@ -173,9 +175,11 @@ _CURL_WARNING(_curl_easy_setopt_err_conv_cb,
|
||||
_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
|
||||
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_cb_data,
|
||||
"curl_easy_setopt expects a private data pointer as argument for this option")
|
||||
"curl_easy_setopt expects a "
|
||||
"private data pointer as argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
|
||||
"curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")
|
||||
"curl_easy_setopt expects a "
|
||||
"char buffer of CURL_ERROR_SIZE as argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_FILE,
|
||||
"curl_easy_setopt expects a FILE* argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_postfields,
|
||||
@@ -224,7 +228,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
(option) == CURLOPT_PROXYUSERNAME || \
|
||||
(option) == CURLOPT_PROXYPASSWORD || \
|
||||
(option) == CURLOPT_NOPROXY || \
|
||||
(option) == CURLOPT_ENCODING || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_REFERER || \
|
||||
(option) == CURLOPT_USERAGENT || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
@@ -481,7 +485,8 @@ typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
||||
typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
|
||||
curlsocktype);
|
||||
|
||||
/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
|
||||
/* evaluates to true if expr is of type curl_opensocket_callback or
|
||||
"similar" */
|
||||
#define _curl_is_opensocket_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
|
||||
@@ -550,7 +555,8 @@ typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
|
||||
typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
|
||||
typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
|
||||
typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
|
||||
typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
|
||||
typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
|
||||
const void *);
|
||||
#else
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
|
||||
|
@@ -1 +0,0 @@
|
||||
/* not used */
|
@@ -122,3 +122,5 @@ if(WIN32)
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS ${LIB_NAME} DESTINATION lib)
|
||||
|
@@ -70,6 +70,13 @@ CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
|
||||
CFLAGS += -dUSE_WINDOWS_SSPI
|
||||
!endif
|
||||
|
||||
!ifdef %use_winidn
|
||||
CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN
|
||||
! if $(__VERSION__) <= 1290
|
||||
CFLAGS += -dWANT_IDN_PROTOTYPES
|
||||
! endif
|
||||
!endif
|
||||
|
||||
#
|
||||
# Change to suite.
|
||||
#
|
||||
@@ -82,7 +89,7 @@ ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.5
|
||||
!ifdef %libssh2_root
|
||||
LIBSSH2_ROOT = $(%libssh2_root)
|
||||
!else
|
||||
LIBSSH2_ROOT = ..$(DS)..$(DS)libssh2-1.2.7
|
||||
LIBSSH2_ROOT = ..$(DS)..$(DS)libssh2-1.2.8
|
||||
!endif
|
||||
|
||||
!ifdef %librtmp_root
|
||||
@@ -229,6 +236,14 @@ $(LINK_ARG): $(__MAKEFILES__)
|
||||
!ifdef %use_ares
|
||||
@%append $^@ library $(ARES_ROOT)$(DS)cares.lib
|
||||
!endif
|
||||
!ifdef %use_winidn
|
||||
! if $(__VERSION__) > 1290
|
||||
@%append $^@ library normaliz.lib
|
||||
! else
|
||||
@%append $^@ import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii'
|
||||
@%append $^@ import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode'
|
||||
! endif
|
||||
!endif
|
||||
|
||||
$(LIB_ARG): $(__MAKEFILES__)
|
||||
%create $^@
|
||||
|
@@ -38,7 +38,7 @@ EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 $(DSP) \
|
||||
config-win32ce.h config-os400.h setup-os400.h config-symbian.h \
|
||||
Makefile.Watcom config-tpf.h $(DOCS) $(VCPROJ) mk-ca-bundle.pl \
|
||||
mk-ca-bundle.vbs firefox-db2pem.sh $(CMAKE_DIST) config-vxworks.h \
|
||||
Makefile.vxworks config-vms.h
|
||||
Makefile.vxworks config-vms.h checksrc.pl
|
||||
|
||||
CLEANFILES = $(DSP) $(VCPROJ)
|
||||
|
||||
@@ -46,7 +46,7 @@ lib_LTLIBRARIES = libcurl.la
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
|
||||
# This might hold -Werror
|
||||
libcurl_la_CFLAGS = $(CFLAGS) @CURL_CFLAG_EXTRAS@
|
||||
CFLAGS += @CURL_CFLAG_EXTRAS@
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
@@ -106,7 +106,7 @@ endif
|
||||
# For the full guide on libcurl ABI rules, see docs/libcurl/ABI
|
||||
|
||||
if NO_UNDEFINED
|
||||
# The -no-undefined flag is CRUCIAL for this to build fine on Cygwin.
|
||||
# The -no-undefined flag is crucial to build fine on some platforms
|
||||
UNDEF = -no-undefined
|
||||
endif
|
||||
|
||||
@@ -116,18 +116,18 @@ if MIMPURE
|
||||
MIMPURE = -mimpure-text
|
||||
endif
|
||||
|
||||
LINKFLAGS=$(UNDEF) $(MIMPURE) $(LIBCURL_LIBS)
|
||||
libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(LIBCURL_LIBS)
|
||||
|
||||
libcurl_la_LDFLAGS = $(LINKFLAGS) $(VERSIONINFO)
|
||||
|
||||
# as unit testing will compile and link everything an extra time, we only
|
||||
# do it if debug is enabled
|
||||
if CURLDEBUG
|
||||
# unit testing static library built only along with unit tests
|
||||
if BUILD_UNITTESTS
|
||||
noinst_LTLIBRARIES = libcurlu.la
|
||||
libcurlu_la_CFLAGS = -DUNITTESTS
|
||||
libcurlu_la_LDFLAGS = -static $(LINKFLAGS)
|
||||
else
|
||||
noinst_LTLIBRARIES =
|
||||
endif
|
||||
|
||||
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DUNITTESTS
|
||||
libcurlu_la_LDFLAGS = -static $(LIBCURL_LIBS)
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
@@ -184,3 +184,12 @@ $(VCPROJ): vc8proj.head vc8proj.foot Makefile.am
|
||||
echo "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
|
||||
done; \
|
||||
cat $(srcdir)/vc8proj.foot $(VCPROJOUT) )
|
||||
|
||||
|
||||
checksrc:
|
||||
@@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/lib $(CSOURCES) $(HHEADERS)
|
||||
|
||||
if CURLDEBUG
|
||||
# for debug builds, we scan the sources on all regular make invokes
|
||||
all-local: checksrc
|
||||
endif
|
||||
|
@@ -15,13 +15,14 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \
|
||||
content_encoding.c share.c http_digest.c md4.c md5.c curl_rand.c \
|
||||
http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \
|
||||
hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \
|
||||
inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \
|
||||
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \
|
||||
socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c \
|
||||
curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c \
|
||||
warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c\
|
||||
gopher.c axtls.c idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c
|
||||
hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \
|
||||
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \
|
||||
qssl.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \
|
||||
curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \
|
||||
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
|
||||
asyn-ares.c asyn-thread.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -35,6 +36,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \
|
||||
curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h \
|
||||
curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h \
|
||||
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
|
||||
gopher.h axtls.h cyassl.h http_proxy.h
|
||||
|
||||
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
|
||||
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#########################################################################
|
||||
#
|
||||
## Makefile for building libcurl.a with MingW32 (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.2), zlib (1.2.5)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.2), zlib (1.2.5), librtmp (2.3)
|
||||
##
|
||||
## Usage:
|
||||
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [IDN=1] [SSPI=1] [IPV6=1] [LDAPS=1] [RTMP=1] [DYN=1]
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.5
|
||||
@@ -24,15 +24,21 @@ OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.7
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.8
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../librtmp-2.3
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.18
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../librtmp-2.3
|
||||
# Edit the path below to point to the base of your MS idndlpackage.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815
|
||||
ifndef WINIDN_PATH
|
||||
WINIDN_PATH = ../../Microsoft IDN Mitigation APIs
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
@@ -45,9 +51,10 @@ LIBCARES_PATH = ../ares
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -g -O2 -Wall
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
RC = windres
|
||||
RCFLAGS = --include-dir=../include -DDEBUGBUILD=0 -O COFF -i
|
||||
@@ -57,8 +64,46 @@ STRIP = strip -g
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
ifeq ($(findstring -dyn,$(CFG)),-dyn)
|
||||
DYN = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
RTMP = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
SSH2 = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
SSL = 1
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -winidn,$(CFG)),-winidn)
|
||||
WINIDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -sspi,$(CFG)),-sspi)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
|
||||
LDAPS = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
IPV6 = 1
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I../include
|
||||
CFLAGS = -g -O2 -DBUILDING_LIBCURL
|
||||
CFLAGS += -DBUILDING_LIBCURL
|
||||
ifdef ARES
|
||||
INCLUDES += -I$(LIBCARES_PATH)
|
||||
CFLAGS += -DUSE_ARES
|
||||
@@ -91,6 +136,13 @@ ifdef IDN
|
||||
INCLUDES += -I"$(LIBIDN_PATH)/include"
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
INCLUDES += -I"$(WINIDN_PATH)/include"
|
||||
CFLAGS += -DHAVE_NORMALIZATION_H
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
|
@@ -24,7 +24,7 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.7
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.8
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
|
@@ -101,7 +101,7 @@ CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
@@ -457,6 +457,8 @@ clean:
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
@@ -479,17 +481,15 @@ X_OBJS= \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostares.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\hostthre.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#Description: makefile to be used in order to compile libcurl for VxWoorks 6.3.
|
||||
#
|
||||
#How to use:
|
||||
# 1. Adjust environment variables at the file begining
|
||||
# 1. Adjust environment variables at the file beginning
|
||||
# 2. Open the Command Prompt window and change directory ('cd')
|
||||
# into the 'lib' folder
|
||||
# 3. Add <CYGWIN>/bin folder to the PATH environment variable
|
||||
|
@@ -33,21 +33,21 @@ Gallagher, and support for the 'gzip' encoding was added by Dan Fandrich.
|
||||
|
||||
To cause libcurl to request a content encoding use:
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_ENCODING, <string>)
|
||||
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, <string>)
|
||||
|
||||
where <string> is the intended value of the Accept-Encoding header.
|
||||
|
||||
Currently, libcurl only understands how to process responses that use the
|
||||
"deflate" or "gzip" Content-Encoding, so the only values for CURLOPT_ENCODING
|
||||
that will work (besides "identity," which does nothing) are "deflate" and
|
||||
"gzip" If a response is encoded using the "compress" or methods, libcurl will
|
||||
return an error indicating that the response could not be decoded. If
|
||||
<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.
|
||||
"deflate" or "gzip" Content-Encoding, so the only values for
|
||||
CURLOPT_ACCEPT_ENCODING that will work (besides "identity," which does
|
||||
nothing) are "deflate" and "gzip" If a response is encoded using the
|
||||
"compress" or methods, libcurl will return an error indicating that the
|
||||
response could not be decoded. If <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
|
||||
The CURLOPT_ACCEPT_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.
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
* Telnet option defines. Add more here if in need.
|
||||
*/
|
||||
#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
|
||||
#define CURL_TELOPT_SGA 3 /* Supress Go Ahead */
|
||||
#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
|
||||
#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
|
||||
#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
|
||||
#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
|
||||
|
@@ -60,6 +60,14 @@
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ares-enabled builds
|
||||
* And only for functions that fulfill the asynch resolver backend API
|
||||
* as defined in asyn.h, nothing else belongs in this file!
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
@@ -76,18 +84,140 @@
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
(defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
|
||||
# define CARES_STATICLIB
|
||||
# endif
|
||||
# include <ares.h>
|
||||
|
||||
#if ARES_VERSION >= 0x010500
|
||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
||||
#endif
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ares-enabled builds
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
struct ResolverResults {
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||
int last_status;
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_resolv_fdset() is called when someone from the outside world (using
|
||||
* Curl_resolver_global_init() - the generic low-level asynchronous name
|
||||
* resolve API. Called from curl_global_init() to initialize global resolver
|
||||
* environment. Initializes ares library.
|
||||
*/
|
||||
int Curl_resolver_global_init(void)
|
||||
{
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
||||
if(ares_library_init(ARES_LIB_INIT_ALL)) {
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
*
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
* Deinitializes ares library.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void)
|
||||
{
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
|
||||
ares_library_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
*
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Fills the passed pointer by the initialized ares_channel.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver)
|
||||
{
|
||||
int status = ares_init((ares_channel*)resolver);
|
||||
if(status != ARES_SUCCESS) {
|
||||
if(status == ARES_ENOMEM)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
return CURLE_OK;
|
||||
/* make sure that all other returns from this function should destroy the
|
||||
ares channel before returning error! */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
*
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Destroys the ares channel.
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver)
|
||||
{
|
||||
ares_destroy((ares_channel)resolver);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
*
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
||||
* environment ('resolver' member of the UrlState structure). Duplicates the
|
||||
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from)
|
||||
{
|
||||
/* Clone the ares channel for the new handle */
|
||||
if(ARES_SUCCESS != ares_dup((ares_channel*)to,(ares_channel)from))
|
||||
return CURLE_FAILED_INIT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void destroy_async_data (struct Curl_async *async);
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn)
|
||||
{
|
||||
if(conn && conn->data && conn->data->state.resolver)
|
||||
ares_cancel((ares_channel)conn->data->state.resolver);
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy_async_data() cleans up async resolver data.
|
||||
*/
|
||||
static void destroy_async_data (struct Curl_async *async)
|
||||
{
|
||||
if(async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if(async->os_specific) {
|
||||
struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
|
||||
if(res) {
|
||||
if(res->temp_ai) {
|
||||
Curl_freeaddrinfo(res->temp_ai);
|
||||
res->temp_ai = NULL;
|
||||
}
|
||||
free(res);
|
||||
}
|
||||
async->os_specific = NULL;
|
||||
}
|
||||
|
||||
async->hostname = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_fdset() is called when someone from the outside world (using
|
||||
* curl_multi_fdset()) wants to get our fd_set setup and we're talking with
|
||||
* ares. The caller must make sure that this function is only called when we
|
||||
* have a working ares channel.
|
||||
@@ -95,22 +225,23 @@
|
||||
* Returns: CURLE_OK always!
|
||||
*/
|
||||
|
||||
int Curl_resolv_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
int Curl_resolver_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
|
||||
{
|
||||
struct timeval maxtime;
|
||||
struct timeval timebuf;
|
||||
struct timeval *timeout;
|
||||
int max = ares_getsock(conn->data->state.areschannel,
|
||||
int max = ares_getsock((ares_channel)conn->data->state.resolver,
|
||||
(ares_socket_t *)socks, numsocks);
|
||||
|
||||
|
||||
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
||||
maxtime.tv_usec = 0;
|
||||
|
||||
timeout = ares_timeout(conn->data->state.areschannel, &maxtime, &timebuf);
|
||||
timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
|
||||
&timebuf);
|
||||
|
||||
Curl_expire(conn->data,
|
||||
(timeout->tv_sec * 1000) + (timeout->tv_usec/1000));
|
||||
@@ -138,7 +269,8 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
int i;
|
||||
int num = 0;
|
||||
|
||||
bitmask = ares_getsock(data->state.areschannel, socks, ARES_GETSOCK_MAXNUM);
|
||||
bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
|
||||
ARES_GETSOCK_MAXNUM);
|
||||
|
||||
for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||
pfd[i].events = 0;
|
||||
@@ -165,11 +297,12 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
if(!nfds)
|
||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve won't timeout! */
|
||||
ares_process_fd(data->state.areschannel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||
ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
|
||||
ARES_SOCKET_BAD);
|
||||
else {
|
||||
/* move through the descriptors and ask for processing on them */
|
||||
for(i=0; i < num; i++)
|
||||
ares_process_fd(data->state.areschannel,
|
||||
ares_process_fd((ares_channel)data->state.resolver,
|
||||
pfd[i].revents & (POLLRDNORM|POLLIN)?
|
||||
pfd[i].fd:ARES_SOCKET_BAD,
|
||||
pfd[i].revents & (POLLWRNORM|POLLOUT)?
|
||||
@@ -179,23 +312,29 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||
* request has completed. It should also make sure to time-out if the
|
||||
* operation seems to take too long.
|
||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||
* name resolve request has completed. It should also make sure to time-out if
|
||||
* the operation seems to take too long.
|
||||
*
|
||||
* Returns normal CURLcode errors.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ResolverResults *res = (struct ResolverResults *)
|
||||
conn->async.os_specific;
|
||||
|
||||
*dns = NULL;
|
||||
|
||||
waitperform(conn, 0);
|
||||
|
||||
if(conn->async.done) {
|
||||
/* we're done, kill the ares handle */
|
||||
if(res && !res->num_pending) {
|
||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||
them */
|
||||
res->temp_ai = NULL;
|
||||
destroy_async_data(&conn->async);
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
|
||||
ares_strerror(conn->async.status));
|
||||
@@ -208,21 +347,24 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||
* be avoided since using this risk getting the multi interface to "hang".
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode rc=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout;
|
||||
struct timeval now = Curl_tvnow();
|
||||
struct Curl_dns_entry *temp_entry;
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(!timeout)
|
||||
@@ -240,7 +382,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
store.tv_sec = itimeout/1000;
|
||||
store.tv_usec = (itimeout%1000)*1000;
|
||||
|
||||
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
||||
tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
|
||||
|
||||
/* use the timeout period ares returned to us above if less than one
|
||||
second is left, otherwise just use 1000ms to make sure the progress
|
||||
@@ -251,6 +393,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
timeout_ms = 1000;
|
||||
|
||||
waitperform(conn, timeout_ms);
|
||||
Curl_resolver_is_resolved(conn,&temp_entry);
|
||||
|
||||
if(conn->async.done)
|
||||
break;
|
||||
@@ -267,7 +410,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
}
|
||||
if(timeout < 0) {
|
||||
/* our timeout, so we cancel the ares operation */
|
||||
ares_cancel(data->state.areschannel);
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -281,7 +424,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
if(!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
|
||||
if (conn->bits.httpproxy) {
|
||||
if(conn->bits.httpproxy) {
|
||||
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
|
||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
@@ -291,7 +434,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else if(conn->async.done) {
|
||||
if (conn->bits.httpproxy) {
|
||||
if(conn->bits.httpproxy) {
|
||||
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
|
||||
ares_strerror(conn->async.status));
|
||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
@@ -313,53 +456,73 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Connects results to the list */
|
||||
static void compound_results(struct ResolverResults *res,
|
||||
Curl_addrinfo *ai)
|
||||
{
|
||||
Curl_addrinfo *ai_tail;
|
||||
if(!ai)
|
||||
return;
|
||||
ai_tail = ai;
|
||||
|
||||
while(ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = res->temp_ai;
|
||||
res->temp_ai = ai;
|
||||
}
|
||||
|
||||
/*
|
||||
* ares_query_completed_cb() is the callback that ares will call when
|
||||
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
||||
* when using ares, is completed either successfully or with failure.
|
||||
*/
|
||||
static void ares_query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
int status,
|
||||
static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
int status,
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
int timeouts,
|
||||
int timeouts,
|
||||
#endif
|
||||
struct hostent *hostent)
|
||||
struct hostent *hostent)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)arg;
|
||||
struct Curl_addrinfo * ai = NULL;
|
||||
struct ResolverResults *res;
|
||||
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
(void)timeouts; /* ignored */
|
||||
#endif
|
||||
|
||||
switch(status) {
|
||||
case CURL_ASYNC_SUCCESS:
|
||||
ai = Curl_he2ai(hostent, conn->async.port);
|
||||
break;
|
||||
case ARES_EDESTRUCTION:
|
||||
/* this ares handle is getting destroyed, the 'arg' pointer may not be
|
||||
valid! */
|
||||
if(ARES_EDESTRUCTION == status)
|
||||
/* when this ares handle is getting destroyed, the 'arg' pointer may not
|
||||
be valid so only defer it when we know the 'status' says its fine! */
|
||||
return;
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
(void)Curl_addrinfo_callback(arg, status, ai);
|
||||
res = (struct ResolverResults *)conn->async.os_specific;
|
||||
res->num_pending--;
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
|
||||
if(ai) {
|
||||
compound_results(res, ai);
|
||||
}
|
||||
}
|
||||
/* A successful result overwrites any previous error */
|
||||
if(res->last_status != ARES_SUCCESS)
|
||||
res->last_status = status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - when using ares
|
||||
* Curl_resolver_getaddrinfo() - when using ares
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
char *bufp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
@@ -379,10 +542,9 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
/* Otherwise, check if this is an IPv6 address string */
|
||||
if (Curl_inet_pton (AF_INET6, hostname, &in6) > 0) {
|
||||
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
|
||||
/* This must be an IPv6 address literal. */
|
||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
}
|
||||
|
||||
switch(conn->ip_version) {
|
||||
default:
|
||||
@@ -402,34 +564,42 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
bufp = strdup(hostname);
|
||||
|
||||
if(bufp) {
|
||||
struct ResolverResults *res = NULL;
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = bufp;
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
conn->async.temp_ai = NULL; /* clear */
|
||||
res = calloc(sizeof(struct ResolverResults),1);
|
||||
if(!res) {
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = NULL;
|
||||
return NULL;
|
||||
}
|
||||
conn->async.os_specific = res;
|
||||
|
||||
/* initial status - failed */
|
||||
res->last_status = ARES_ENOTFOUND;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
if(family == PF_UNSPEC) {
|
||||
conn->async.num_pending = 2;
|
||||
res->num_pending = 2;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
||||
ares_query_completed_cb, conn);
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET6,
|
||||
ares_query_completed_cb, conn);
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||
PF_INET, query_completed_cb, conn);
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||
PF_INET6, query_completed_cb, conn);
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
{
|
||||
conn->async.num_pending = 1;
|
||||
res->num_pending = 1;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||
ares_query_completed_cb, conn);
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
|
||||
query_completed_cb, conn);
|
||||
}
|
||||
|
||||
*waitp = 1; /* expect asynchronous response */
|
@@ -64,6 +64,12 @@
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
# define RESOLVER_ENOMEM EAI_MEMORY
|
||||
#else
|
||||
# define RESOLVER_ENOMEM ENOMEM
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
@@ -88,6 +94,71 @@
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_THREADED
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init()
|
||||
* Called from curl_global_init() to initialize global resolver environment.
|
||||
* Does nothing here.
|
||||
*/
|
||||
int Curl_resolver_global_init(void)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
* Does nothing here.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Does nothing here.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver)
|
||||
{
|
||||
(void)resolver;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Does nothing here.
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver)
|
||||
{
|
||||
(void)resolver;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
|
||||
* environment ('resolver' member of the UrlState structure). Does nothing
|
||||
* here.
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from)
|
||||
{
|
||||
(void)to;
|
||||
(void)from;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void destroy_async_data(struct Curl_async *);
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn)
|
||||
{
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
/* This function is used to init a threaded resolve */
|
||||
static bool init_resolve_thread(struct connectdata *conn,
|
||||
const char *hostname, int port,
|
||||
@@ -117,7 +188,7 @@ struct thread_data {
|
||||
struct thread_sync_data tsd;
|
||||
};
|
||||
|
||||
static struct thread_sync_data * conn_thread_sync_data(struct connectdata *conn)
|
||||
static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
|
||||
{
|
||||
return &(((struct thread_data *)conn->async.os_specific)->tsd);
|
||||
}
|
||||
@@ -128,7 +199,7 @@ static struct thread_sync_data * conn_thread_sync_data(struct connectdata *conn)
|
||||
static
|
||||
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
{
|
||||
if (tsd->mtx) {
|
||||
if(tsd->mtx) {
|
||||
Curl_mutex_destroy(tsd->mtx);
|
||||
free(tsd->mtx);
|
||||
}
|
||||
@@ -136,7 +207,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
if(tsd->hostname)
|
||||
free(tsd->hostname);
|
||||
|
||||
if (tsd->res)
|
||||
if(tsd->res)
|
||||
Curl_freeaddrinfo(tsd->res);
|
||||
|
||||
memset(tsd,0,sizeof(*tsd));
|
||||
@@ -160,7 +231,8 @@ int init_thread_sync_data(struct thread_sync_data * tsd,
|
||||
#endif
|
||||
|
||||
tsd->mtx = malloc(sizeof(curl_mutex_t));
|
||||
if (tsd->mtx == NULL) goto err_exit;
|
||||
if(tsd->mtx == NULL)
|
||||
goto err_exit;
|
||||
|
||||
Curl_mutex_init(tsd->mtx);
|
||||
|
||||
@@ -170,7 +242,8 @@ int init_thread_sync_data(struct thread_sync_data * tsd,
|
||||
* thread during gethostbyname execution.
|
||||
*/
|
||||
tsd->hostname = strdup(hostname);
|
||||
if (!tsd->hostname) goto err_exit;
|
||||
if(!tsd->hostname)
|
||||
goto err_exit;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -186,9 +259,9 @@ static int getaddrinfo_complete(struct connectdata *conn)
|
||||
int rc;
|
||||
|
||||
rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
|
||||
/* The tsd->res structure has been copied to async.dns and perhaps the DNS cache.
|
||||
Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
||||
*/
|
||||
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
||||
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
||||
*/
|
||||
tsd->res = NULL;
|
||||
|
||||
return rc;
|
||||
@@ -213,10 +286,10 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
|
||||
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
|
||||
|
||||
if (rc != 0) {
|
||||
tsd->sock_error = SOCKERRNO;
|
||||
if (tsd->sock_error == 0)
|
||||
tsd->sock_error = ENOMEM;
|
||||
if(rc != 0) {
|
||||
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
|
||||
if(tsd->sock_error == 0)
|
||||
tsd->sock_error = RESOLVER_ENOMEM;
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
@@ -237,10 +310,10 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
|
||||
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
||||
|
||||
if (!tsd->res) {
|
||||
if(!tsd->res) {
|
||||
tsd->sock_error = SOCKERRNO;
|
||||
if (tsd->sock_error == 0)
|
||||
tsd->sock_error = ENOMEM;
|
||||
if(tsd->sock_error == 0)
|
||||
tsd->sock_error = RESOLVER_ENOMEM;
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
@@ -253,10 +326,9 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
/*
|
||||
* Curl_destroy_thread_data() cleans up async resolver data and thread handle.
|
||||
* Complementary of ares_destroy.
|
||||
* destroy_async_data() cleans up async resolver data and thread handle.
|
||||
*/
|
||||
void Curl_destroy_thread_data (struct Curl_async *async)
|
||||
static void destroy_async_data (struct Curl_async *async)
|
||||
{
|
||||
if(async->hostname)
|
||||
free(async->hostname);
|
||||
@@ -264,10 +336,10 @@ void Curl_destroy_thread_data (struct Curl_async *async)
|
||||
if(async->os_specific) {
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
|
||||
if (td->dummy_sock != CURL_SOCKET_BAD)
|
||||
if(td->dummy_sock != CURL_SOCKET_BAD)
|
||||
sclose(td->dummy_sock);
|
||||
|
||||
if (td->thread_hnd != curl_thread_t_null)
|
||||
if(td->thread_hnd != curl_thread_t_null)
|
||||
Curl_thread_join(&td->thread_hnd);
|
||||
|
||||
destroy_thread_sync_data(&td->tsd);
|
||||
@@ -289,7 +361,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
||||
int err = ENOMEM;
|
||||
int err = RESOLVER_ENOMEM;
|
||||
|
||||
conn->async.os_specific = (void*) td;
|
||||
if(!td)
|
||||
@@ -302,7 +374,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
td->dummy_sock = CURL_SOCKET_BAD;
|
||||
td->thread_hnd = curl_thread_t_null;
|
||||
|
||||
if (!init_thread_sync_data(&td->tsd, hostname, port, hints))
|
||||
if(!init_thread_sync_data(&td->tsd, hostname, port, hints))
|
||||
goto err_exit;
|
||||
|
||||
Curl_safefree(conn->async.hostname);
|
||||
@@ -311,12 +383,12 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
goto err_exit;
|
||||
|
||||
#ifdef WIN32
|
||||
/* This socket is only to keep Curl_resolv_fdset() and select() happy;
|
||||
/* This socket is only to keep Curl_resolver_fdset() and select() happy;
|
||||
* should never become signalled for read since it's unbound but
|
||||
* Windows needs at least 1 socket in select().
|
||||
*/
|
||||
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (td->dummy_sock == CURL_SOCKET_BAD)
|
||||
if(td->dummy_sock == CURL_SOCKET_BAD)
|
||||
goto err_exit;
|
||||
#endif
|
||||
|
||||
@@ -336,37 +408,93 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
return TRUE;
|
||||
|
||||
err_exit:
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
SET_ERRNO(err);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GETADDRINFO) && !defined(HAVE_GAI_STRERROR) && !defined(WIN32)
|
||||
/* NetWare has getaddrinfo but lacks gai_strerror.
|
||||
Windows has a gai_strerror but it is bad (not thread-safe) and the generic
|
||||
socket error string function can be used for this pupose. */
|
||||
static const char *gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode){
|
||||
case EAI_AGAIN:
|
||||
return "The name could not be resolved at this time";
|
||||
case EAI_BADFLAGS:
|
||||
return "The flags parameter had an invalid value";
|
||||
case EAI_FAIL:
|
||||
return "A non-recoverable error occurred when attempting to "
|
||||
"resolve the name";
|
||||
case EAI_FAMILY:
|
||||
return "The address family was not recognized";
|
||||
case EAI_MEMORY:
|
||||
return "Out of memory";
|
||||
case EAI_NONAME:
|
||||
return "The name does not resolve for the supplied parameters";
|
||||
case EAI_SERVICE:
|
||||
return "The service passed was not recognized for the "
|
||||
"specified socket type"
|
||||
case EAI_SOCKTYPE:
|
||||
return "The intended socket type was not recognized"
|
||||
case EAI_SYSTEM:
|
||||
return "A system error occurred";
|
||||
case EAI_OVERFLOW:
|
||||
return "An argument buffer overflowed";
|
||||
default:
|
||||
return "Unknown error";
|
||||
|
||||
/* define this now as this is a private implementation of said function */
|
||||
#define HAVE_GAI_STRERROR
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||
* be avoided since using this risk getting the multi interface to "hang".
|
||||
* resolver_error() calls failf() with the appropriate message after a resolve
|
||||
* error
|
||||
*/
|
||||
|
||||
static void resolver_error(struct connectdata *conn, const char *host_or_proxy)
|
||||
{
|
||||
failf(conn->data, "Could not resolve %s: %s; %s", host_or_proxy,
|
||||
conn->async.hostname,
|
||||
#ifdef HAVE_GAI_STRERROR
|
||||
/* NetWare doesn't have gai_strerror and on Windows it isn't deemed
|
||||
thread-safe */
|
||||
gai_strerror(conn->async.status)
|
||||
#else
|
||||
Curl_strerror(conn, conn->async.status)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* This is the version for resolves-in-a-thread.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode rc = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(conn && td);
|
||||
|
||||
/* wait for the thread to resolve the name */
|
||||
if (Curl_thread_join(&td->thread_hnd)) {
|
||||
if(Curl_thread_join(&td->thread_hnd))
|
||||
rc = getaddrinfo_complete(conn);
|
||||
} else {
|
||||
else
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
|
||||
conn->async.done = TRUE;
|
||||
|
||||
@@ -375,18 +503,17 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
|
||||
if(!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
if (conn->bits.httpproxy) {
|
||||
failf(data, "Could not resolve proxy: %s; %s",
|
||||
conn->async.hostname, Curl_strerror(conn, conn->async.status));
|
||||
if(conn->bits.httpproxy) {
|
||||
resolver_error(conn, "proxy");
|
||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
} else {
|
||||
failf(data, "Could not resolve host: %s; %s",
|
||||
conn->async.hostname, Curl_strerror(conn, conn->async.status));
|
||||
}
|
||||
else {
|
||||
resolver_error(conn, "host");
|
||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
}
|
||||
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
if(!conn->async.dns)
|
||||
conn->bits.close = TRUE;
|
||||
@@ -395,12 +522,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||
* request has completed. It should also make sure to time-out if the
|
||||
* operation seems to take too long.
|
||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||
* name resolve request has completed. It should also make sure to time-out if
|
||||
* the operation seems to take too long.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
@@ -408,7 +535,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
if (!td) {
|
||||
if(!td) {
|
||||
DEBUGASSERT(td);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
@@ -417,30 +544,30 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
done = td->tsd.done;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if (done) {
|
||||
if(done) {
|
||||
getaddrinfo_complete(conn);
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve host: %s; %s",
|
||||
conn->host.name, Curl_strerror(conn, conn->async.status));
|
||||
resolver_error(conn, "host");
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
*entry = conn->async.dns;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||
int elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||
if (elapsed < 0)
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
if (td->poll_interval == 0)
|
||||
if(td->poll_interval == 0)
|
||||
/* Start at 1ms poll interval */
|
||||
td->poll_interval = 1;
|
||||
else if (elapsed >= td->interval_end)
|
||||
else if(elapsed >= td->interval_end)
|
||||
/* Back-off exponentially if last interval expired */
|
||||
td->poll_interval *= 2;
|
||||
|
||||
if (td->poll_interval > 250)
|
||||
if(td->poll_interval > 250)
|
||||
td->poll_interval = 250;
|
||||
|
||||
td->interval_end = elapsed + td->poll_interval;
|
||||
@@ -450,9 +577,9 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
int Curl_resolv_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
int Curl_resolver_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
const struct thread_data *td =
|
||||
(const struct thread_data *) conn->async.os_specific;
|
||||
@@ -472,10 +599,10 @@ int Curl_resolv_getsock(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct in_addr in;
|
||||
|
||||
@@ -498,19 +625,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
#else /* !HAVE_GETADDRINFO */
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - for getaddrinfo
|
||||
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
Curl_addrinfo *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
int pf = PF_INET;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
@@ -549,12 +675,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* fall-back to blocking version */
|
||||
infof(data, "init_resolve_thread() failed for %s; %s\n",
|
||||
infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
|
||||
hostname, Curl_strerror(conn, ERRNO));
|
||||
|
||||
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
|
||||
if(error) {
|
||||
infof(data, "getaddrinfo() failed for %s:%d; %s\n",
|
||||
infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n",
|
||||
hostname, port, Curl_strerror(conn, SOCKERRNO));
|
||||
return NULL;
|
||||
}
|
168
lib/asyn.h
Normal file
168
lib/asyn.h
Normal file
@@ -0,0 +1,168 @@
|
||||
#ifndef HEADER_CURL_ASYN_H
|
||||
#define HEADER_CURL_ASYN_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
struct connectdata;
|
||||
struct Curl_dns_entry;
|
||||
|
||||
/*
|
||||
* This header defines all functions in the internal asynch resolver interface.
|
||||
* All asynch resolvers need to provide these functions.
|
||||
* asyn-ares.c and asyn-thread.c are the current implementations of asynch
|
||||
* resolver backends.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init()
|
||||
*
|
||||
* Called from curl_global_init() to initialize global resolver environment.
|
||||
* Returning anything else than CURLE_OK fails curl_global_init().
|
||||
*/
|
||||
int Curl_resolver_global_init(void);
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void);
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Should fill the passed pointer by the initialized handler.
|
||||
* Returning anything else than CURLE_OK fails curl_easy_init() with the
|
||||
* correspondent code.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Should destroy the handler and free all resources connected to
|
||||
* it.
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver);
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
||||
* environment ('resolver' member of the UrlState structure). Should
|
||||
* duplicate the 'from' handle and pass the resulting handle to the 'to'
|
||||
* pointer. Returning anything else than CURLE_OK causes failed
|
||||
* curl_easy_duphandle() call.
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cancel().
|
||||
*
|
||||
* It is called from inside other functions to cancel currently performing
|
||||
* resolver request. Should also free any temporary resources allocated to
|
||||
* perform a request.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn);
|
||||
|
||||
/* Curl_resolver_getsock()
|
||||
*
|
||||
* This function is called from the multi_getsock() function. 'sock' is a
|
||||
* pointer to an array to hold the file descriptors, with 'numsock' being the
|
||||
* size of that array (in number of entries). This function is supposed to
|
||||
* return bitmask indicating what file descriptors (referring to array indexes
|
||||
* in the 'sock' array) to wait for, read/write.
|
||||
*/
|
||||
int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
|
||||
int numsocks);
|
||||
|
||||
/*
|
||||
* Curl_resolver_is_resolved()
|
||||
*
|
||||
* Called repeatedly to check if a previous name resolve request has
|
||||
* completed. It should also make sure to time-out if the operation seems to
|
||||
* take too long.
|
||||
*
|
||||
* Returns normal CURLcode errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns);
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - when using this resolver
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*
|
||||
* Each resolver backend must of course make sure to return data in the
|
||||
* correct format to comply with this.
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
/* convert these functions if an asynch resolver isn't used */
|
||||
#define Curl_resolver_cancel(x)
|
||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_getsock(x,y,z) 0
|
||||
#define Curl_resolver_duphandle(x,y) CURLE_OK
|
||||
#define Curl_resolver_init(x) CURLE_OK
|
||||
#define Curl_resolver_global_init() CURLE_OK
|
||||
#define Curl_resolver_global_cleanup()
|
||||
#define Curl_resolver_cleanup(x)
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
#define Curl_resolver_asynch() 1
|
||||
#else
|
||||
#define Curl_resolver_asynch() 0
|
||||
#endif
|
||||
|
||||
|
||||
/********** end of generic resolver interface functions *****************/
|
||||
#endif /* HEADER_CURL_ASYN_H */
|
@@ -82,8 +82,7 @@ int Curl_axtls_cleanup(void)
|
||||
|
||||
static CURLcode map_error_to_curl(int axtls_err)
|
||||
{
|
||||
switch (axtls_err)
|
||||
{
|
||||
switch (axtls_err) {
|
||||
case SSL_ERROR_NOT_SUPPORTED:
|
||||
case SSL_ERROR_INVALID_VERSION:
|
||||
case -70: /* protocol version alert from server */
|
||||
@@ -296,7 +295,7 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
else
|
||||
infof(data, "\t server certificate verification SKIPPED\n");
|
||||
|
||||
/* Here, gtls.c does issuer verfication. axTLS has no straightforward
|
||||
/* Here, gtls.c does issuer verification. axTLS has no straightforward
|
||||
* equivalent, so omitting for now.*/
|
||||
|
||||
/* See if common name was set in server certificate */
|
||||
@@ -416,7 +415,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
||||
sizeof(buf));
|
||||
|
||||
if (nread < SSL_OK){
|
||||
if(nread < SSL_OK){
|
||||
failf(data, "close notify alert not received during shutdown");
|
||||
retval = -1;
|
||||
}
|
||||
|
39
lib/base64.c
39
lib/base64.c
@@ -31,10 +31,10 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "urldata.h" /* for the SessionHandle definition */
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_memory.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
/* include memdebug.h last */
|
||||
#include "memdebug.h"
|
||||
@@ -73,6 +73,8 @@ static void decodeQuantum(unsigned char *dest, const char *src)
|
||||
*
|
||||
* Given a base64 string at src, decode it and return an allocated memory in
|
||||
* the *outptr. Returns the length of the decoded data.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
{
|
||||
@@ -135,20 +137,20 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
* is a pointer to an allocated area holding the base64 data. If something
|
||||
* went wrong, 0 is returned.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr)
|
||||
{
|
||||
CURLcode res;
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
int i;
|
||||
int inputparts;
|
||||
char *output;
|
||||
char *base64data;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char *convbuf = NULL;
|
||||
#endif
|
||||
|
||||
const char *indata = inputbuff;
|
||||
|
||||
@@ -161,32 +163,22 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
if(NULL == output)
|
||||
return 0;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* The base64 data needs to be created using the network encoding
|
||||
* not the host encoding. And we can't change the actual input
|
||||
* so we copy it to a buffer, translate it, and use that instead.
|
||||
*/
|
||||
if(data) {
|
||||
convbuf = malloc(insize);
|
||||
if(!convbuf) {
|
||||
free(output);
|
||||
return 0;
|
||||
}
|
||||
memcpy(convbuf, indata, insize);
|
||||
if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
|
||||
free(convbuf);
|
||||
free(output);
|
||||
return 0;
|
||||
}
|
||||
indata = convbuf; /* switch to the converted buffer */
|
||||
res = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||
if(res) {
|
||||
free(output);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
if(convbuf)
|
||||
indata = (char *)convbuf;
|
||||
|
||||
while(insize > 0) {
|
||||
for (i = inputparts = 0; i < 3; i++) {
|
||||
for(i = inputparts = 0; i < 3; i++) {
|
||||
if(insize > 0) {
|
||||
inputparts++;
|
||||
ibuf[i] = (unsigned char) *indata;
|
||||
@@ -229,10 +221,9 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
*output=0;
|
||||
*outptr = base64data; /* make it return the actual data memory */
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(data)
|
||||
if(convbuf)
|
||||
free(convbuf);
|
||||
#endif
|
||||
|
||||
return strlen(base64data); /* return the length of the new data */
|
||||
}
|
||||
/* ---- End of Base64 Encoding ---- */
|
||||
|
193
lib/checksrc.pl
Executable file
193
lib/checksrc.pl
Executable file
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/perl
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2011, 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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
my $max_column = 79;
|
||||
my $indent = 2;
|
||||
|
||||
my $warnings;
|
||||
my $errors;
|
||||
my $file;
|
||||
my $dir=".";
|
||||
my $wlist;
|
||||
|
||||
sub checkwarn {
|
||||
my ($num, $col, $file, $line, $msg, $error) = @_;
|
||||
|
||||
my $w=$error?"error":"warning";
|
||||
|
||||
if($w) {
|
||||
$warnings++;
|
||||
}
|
||||
else {
|
||||
$errors++;
|
||||
}
|
||||
|
||||
$col++;
|
||||
print "$file:$num:$col: $w: $msg\n";
|
||||
print " $line\n";
|
||||
|
||||
if($col < 80) {
|
||||
my $pref = (' ' x $col);
|
||||
print "${pref}^\n";
|
||||
}
|
||||
}
|
||||
|
||||
$file = shift @ARGV;
|
||||
|
||||
while(1) {
|
||||
|
||||
if($file =~ /-D(.*)/) {
|
||||
$dir = $1;
|
||||
$file = shift @ARGV;
|
||||
next;
|
||||
}
|
||||
elsif($file =~ /-W(.*)/) {
|
||||
$wlist = $1;
|
||||
$file = shift @ARGV;
|
||||
next;
|
||||
}
|
||||
|
||||
last;
|
||||
}
|
||||
|
||||
if(!$file) {
|
||||
print "checksrc.pl [option] <file1> [file2] ...\n";
|
||||
print " Options:\n";
|
||||
print " -D[DIR] Directory to prepend file names\n";
|
||||
print " -W[file] Whitelist the given file - ignore all its flaws\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
do {
|
||||
if($file ne "$wlist") {
|
||||
my $fullname = $file;
|
||||
$fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/');
|
||||
scanfile($fullname);
|
||||
}
|
||||
$file = shift @ARGV;
|
||||
|
||||
} while($file);
|
||||
|
||||
|
||||
sub scanfile {
|
||||
my ($file) = @_;
|
||||
|
||||
my $line = 1;
|
||||
my $prevl;
|
||||
my $l;
|
||||
open(R, "<$file") || die "failed to open $file";
|
||||
|
||||
my $copyright=0;
|
||||
|
||||
while(<R>) {
|
||||
chomp;
|
||||
my $l = $_;
|
||||
my $column = 0;
|
||||
|
||||
# check for a copyright statement
|
||||
if(!$copyright && ($l =~ /copyright .* \d\d\d\d/i)) {
|
||||
$copyright=1;
|
||||
}
|
||||
|
||||
# detect long lines
|
||||
if(length($l) > $max_column) {
|
||||
checkwarn($line, length($l), $file, $l, "Longer than $max_column columns");
|
||||
}
|
||||
# detect TAB characters
|
||||
if($l =~ /^(.*)\t/) {
|
||||
checkwarn($line, length($1), $file, $l, "Contains TAB character", 1);
|
||||
}
|
||||
# detect trailing white space
|
||||
if($l =~ /^(.*)[ \t]+\z/) {
|
||||
checkwarn($line, length($1), $file, $l, "Trailing whitespace");
|
||||
}
|
||||
|
||||
# check spaces after for/if/while
|
||||
if($l =~ /^(.*)(for|if|while) \(/) {
|
||||
if($1 =~ / *\#/) {
|
||||
# this is a #if, treat it differently
|
||||
}
|
||||
else {
|
||||
checkwarn($line, length($1)+length($2), $file, $l,
|
||||
"$2 with space");
|
||||
}
|
||||
}
|
||||
|
||||
# check spaces after open paren after for/if/while
|
||||
if($l =~ /^(.*)(for|if|while)\( /) {
|
||||
if($1 =~ / *\#/) {
|
||||
# this is a #if, treat it differently
|
||||
}
|
||||
else {
|
||||
checkwarn($line, length($1)+length($2)+1, $file, $l,
|
||||
"$2 with space first in condition");
|
||||
}
|
||||
}
|
||||
|
||||
# check for "} else"
|
||||
if($l =~ /^(.*)\} else/) {
|
||||
checkwarn($line, length($1), $file, $l, "else after closing brace on same line");
|
||||
}
|
||||
# check for open brace first on line but not first column
|
||||
# only alert if previous line ended with a close paren and wasn't a cpp
|
||||
# line
|
||||
if((($prevl =~ /\)\z/) && ($prevl !~ /^ *#/)) && ($l =~ /^( +)\{/)) {
|
||||
checkwarn($line, length($1), $file, $l, "badly placed open brace");
|
||||
}
|
||||
|
||||
# if the previous line starts with if/while/for AND ends with an open
|
||||
# brace, check that this line is indented $indent more steps, if not
|
||||
# a cpp line
|
||||
if($prevl =~ /^( *)(if|while|for)\(.*\{\z/) {
|
||||
my $first = length($1);
|
||||
|
||||
# this line has some character besides spaces
|
||||
if(($l !~ /^ *#/) && ($l =~ /^( *)[^ ]/)) {
|
||||
my $second = length($1);
|
||||
my $expect = $first+$indent;
|
||||
if($expect != $second) {
|
||||
my $diff = $second - $first;
|
||||
checkwarn($line, length($1), $file, $l,
|
||||
"not indented $indent steps, uses $diff)");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$line++;
|
||||
$prevl = $l;
|
||||
}
|
||||
|
||||
if(!$copyright) {
|
||||
checkwarn(1, 0, $file, "", "Missing copyright statement", 1);
|
||||
}
|
||||
|
||||
close(R);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if($errors || $warnings) {
|
||||
printf "checksrc: %d errors and %d warnings\n", $errors, $warnings;
|
||||
exit 5; # return failure
|
||||
}
|
@@ -89,6 +89,7 @@
|
||||
#include "inet_pton.h"
|
||||
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
|
||||
#include "progress.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@@ -130,6 +131,8 @@ singleipconnect(struct connectdata *conn,
|
||||
* If 'nowp' is non-NULL, it points to the current time.
|
||||
* 'duringconnect' is FALSE if not during a connect, as then of course the
|
||||
* connect timeout is not taken into account!
|
||||
*
|
||||
* @unittest: 1303
|
||||
*/
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
struct timeval *nowp,
|
||||
@@ -174,7 +177,7 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
nowp = &now;
|
||||
}
|
||||
|
||||
/* substract elapsed time */
|
||||
/* subtract elapsed time */
|
||||
timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
|
||||
if(!timeout_ms)
|
||||
/* avoid returning 0 as that means no timeout! */
|
||||
@@ -210,8 +213,8 @@ int waitconnect(struct connectdata *conn,
|
||||
for(;;) {
|
||||
|
||||
/* now select() until we get connect or timeout */
|
||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, (int)(timeout_msec>1000?
|
||||
1000:timeout_msec));
|
||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, timeout_msec>1000?
|
||||
1000:timeout_msec);
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return WAITCONN_ABORTED;
|
||||
|
||||
@@ -263,7 +266,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
/*************************************************************
|
||||
* Select device to bind socket to
|
||||
*************************************************************/
|
||||
if ( !dev && !port )
|
||||
if(!dev && !port)
|
||||
/* no local kind of binding was requested */
|
||||
return CURLE_OK;
|
||||
|
||||
@@ -315,16 +318,16 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
long ipver = conn->ip_version;
|
||||
int rc;
|
||||
|
||||
if (af == AF_INET)
|
||||
if(af == AF_INET)
|
||||
conn->ip_version = CURL_IPRESOLVE_V4;
|
||||
#ifdef ENABLE_IPV6
|
||||
else if (af == AF_INET6)
|
||||
else if(af == AF_INET6)
|
||||
conn->ip_version = CURL_IPRESOLVE_V6;
|
||||
#endif
|
||||
|
||||
rc = Curl_resolv(conn, dev, 0, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_wait_for_resolv(conn, &h);
|
||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||
conn->ip_version = ipver;
|
||||
|
||||
if(h) {
|
||||
@@ -372,14 +375,14 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
else {
|
||||
/* no device was given, prepare sa to match af's needs */
|
||||
#ifdef ENABLE_IPV6
|
||||
if ( af == AF_INET6 ) {
|
||||
if(af == AF_INET6) {
|
||||
si6->sin6_family = AF_INET6;
|
||||
si6->sin6_port = htons(port);
|
||||
sizeof_sa = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( af == AF_INET ) {
|
||||
if(af == AF_INET) {
|
||||
si4->sin_family = AF_INET;
|
||||
si4->sin_port = htons(port);
|
||||
sizeof_sa = sizeof(struct sockaddr_in);
|
||||
@@ -387,8 +390,8 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
if( bind(sockfd, sock, sizeof_sa) >= 0) {
|
||||
/* we succeeded to bind */
|
||||
if(bind(sockfd, sock, sizeof_sa) >= 0) {
|
||||
/* we succeeded to bind */
|
||||
struct Curl_sockaddr_storage add;
|
||||
curl_socklen_t size = sizeof(add);
|
||||
memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
|
||||
@@ -510,7 +513,7 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
*connected = FALSE;
|
||||
|
||||
if(sockindex != FIRSTSOCKET) {
|
||||
sclose(fd_to_close);
|
||||
Curl_closesocket(conn, fd_to_close);
|
||||
return CURLE_COULDNT_CONNECT; /* no next */
|
||||
}
|
||||
|
||||
@@ -525,12 +528,12 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
/* store the new socket descriptor */
|
||||
conn->sock[sockindex] = sockfd;
|
||||
conn->ip_addr = ai;
|
||||
sclose(fd_to_close);
|
||||
Curl_closesocket(conn, fd_to_close);
|
||||
return CURLE_OK;
|
||||
}
|
||||
ai = ai->ai_next;
|
||||
}
|
||||
sclose(fd_to_close);
|
||||
Curl_closesocket(conn, fd_to_close);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
@@ -698,7 +701,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
if(WAITCONN_CONNECTED == rc) {
|
||||
if(verifyconnect(sockfd, &error)) {
|
||||
/* we are connected, awesome! */
|
||||
/* we are connected with TCP, awesome! */
|
||||
|
||||
/* see if we need to do any proxy magic first once we connected */
|
||||
code = Curl_connected_proxy(conn);
|
||||
if(code)
|
||||
return code;
|
||||
|
||||
conn->bits.tcpconnect = TRUE;
|
||||
*connected = TRUE;
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||
@@ -809,8 +818,8 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
int curval = 0;
|
||||
int curlen = sizeof(curval);
|
||||
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
|
||||
if (curval > val)
|
||||
if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
|
||||
if(curval > val)
|
||||
return;
|
||||
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
|
||||
@@ -888,7 +897,7 @@ singleipconnect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
if (conn->scope && (addr.family == AF_INET6))
|
||||
if(conn->scope && (addr.family == AF_INET6))
|
||||
sa6->sin6_scope_id = conn->scope;
|
||||
#endif
|
||||
|
||||
@@ -899,7 +908,7 @@ singleipconnect(struct connectdata *conn,
|
||||
error = ERRNO;
|
||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
sclose(sockfd);
|
||||
Curl_closesocket(conn, sockfd);
|
||||
return CURLE_OK;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
@@ -928,7 +937,7 @@ singleipconnect(struct connectdata *conn,
|
||||
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
|
||||
isconnected = TRUE;
|
||||
else if(error) {
|
||||
sclose(sockfd); /* close the socket and bail out */
|
||||
Curl_closesocket(conn, sockfd); /* close the socket and bail out */
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
@@ -936,7 +945,7 @@ singleipconnect(struct connectdata *conn,
|
||||
/* possibly bind the local end to an IP, interface or port */
|
||||
res = bindlocal(conn, sockfd, addr.family);
|
||||
if(res) {
|
||||
sclose(sockfd); /* close socket and bail out */
|
||||
Curl_closesocket(conn, sockfd); /* close socket and bail out */
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -970,7 +979,7 @@ singleipconnect(struct connectdata *conn,
|
||||
#endif
|
||||
rc = waitconnect(conn, sockfd, timeout_ms);
|
||||
if(WAITCONN_ABORTED == rc) {
|
||||
sclose(sockfd);
|
||||
Curl_closesocket(conn, sockfd);
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
break;
|
||||
@@ -1011,7 +1020,7 @@ singleipconnect(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* connect failed or timed out */
|
||||
sclose(sockfd);
|
||||
Curl_closesocket(conn, sockfd);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1067,8 +1076,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/*
|
||||
* Connecting with a Curl_addrinfo chain
|
||||
*/
|
||||
for (curr_addr = ai, aliasindex=0; curr_addr;
|
||||
curr_addr = curr_addr->ai_next, aliasindex++) {
|
||||
for(curr_addr = ai, aliasindex=0; curr_addr;
|
||||
curr_addr = curr_addr->ai_next, aliasindex++) {
|
||||
|
||||
/* start connecting to the IP curr_addr points to */
|
||||
CURLcode res =
|
||||
@@ -1157,3 +1166,17 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a socket.
|
||||
*
|
||||
* 'conn' can be NULL, beware!
|
||||
*/
|
||||
int Curl_closesocket(struct connectdata *conn,
|
||||
curl_socket_t sock)
|
||||
{
|
||||
if(conn && conn->fclosesocket)
|
||||
return conn->fclosesocket(conn->closesocket_client, sock);
|
||||
else
|
||||
return sclose(sock);
|
||||
}
|
||||
|
@@ -68,7 +68,6 @@ void Curl_sndbufset(curl_socket_t sockfd);
|
||||
#endif
|
||||
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
void Curl_persistconninfo(struct connectdata *conn);
|
||||
|
||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||
#endif
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -95,7 +95,7 @@ inflate_stream(struct connectdata *conn,
|
||||
|
||||
/* because the buffer size is fixed, iteratively decompress and transfer to
|
||||
the client via client_write. */
|
||||
for (;;) {
|
||||
for(;;) {
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *)decomp;
|
||||
z->avail_out = DSIZ;
|
||||
|
35
lib/cookie.c
35
lib/cookie.c
@@ -84,7 +84,7 @@ Example set of cookies:
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* without this on windows OS we get undefined reference to snprintf */
|
||||
#define _MPRINTF_REPLACE
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "urldata.h"
|
||||
@@ -101,7 +101,6 @@ Example set of cookies:
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
static void freecookie(struct Cookie *co)
|
||||
{
|
||||
if(co->expirestr)
|
||||
@@ -266,7 +265,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("domain", name)) {
|
||||
/* note that this name may or may not have a preceeding dot, but
|
||||
/* note that this name may or may not have a preceding dot, but
|
||||
we don't care about that, we treat the names the same anyway */
|
||||
|
||||
const char *domptr=whatptr;
|
||||
@@ -307,7 +306,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
or the given domain is not valid and thus cannot be set. */
|
||||
|
||||
if('.' == whatptr[0])
|
||||
whatptr++; /* ignore preceeding dot */
|
||||
whatptr++; /* ignore preceding dot */
|
||||
|
||||
if(!domain || tailmatch(whatptr, domain)) {
|
||||
const char *tailptr=whatptr;
|
||||
@@ -371,10 +370,10 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* Session cookies have expires set to 0 so if we get that back
|
||||
from the date parser let's add a second to make it a
|
||||
non-session cookie */
|
||||
if (co->expires == 0)
|
||||
if(co->expires == 0)
|
||||
co->expires = 1;
|
||||
else if( co->expires < 0 )
|
||||
co->expires = 0;
|
||||
else if(co->expires < 0)
|
||||
co->expires = 0;
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
@@ -398,7 +397,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if(Curl_raw_equal("secure", what)) {
|
||||
co->secure = TRUE;
|
||||
}
|
||||
else if (Curl_raw_equal("httponly", what)) {
|
||||
else if(Curl_raw_equal("httponly", what)) {
|
||||
co->httponly = TRUE;
|
||||
}
|
||||
/* else,
|
||||
@@ -479,10 +478,10 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
marked with httpOnly after the domain name are not accessible
|
||||
from javascripts, but since curl does not operate at javascript
|
||||
level, we include them anyway. In Firefox's cookie files, these
|
||||
lines are preceeded with #HttpOnly_ and then everything is
|
||||
lines are preceded with #HttpOnly_ and then everything is
|
||||
as usual, so we skip 10 characters of the line..
|
||||
*/
|
||||
if (strncmp(lineptr, "#HttpOnly_", 10) == 0) {
|
||||
if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
|
||||
lineptr += 10;
|
||||
co->httponly = TRUE;
|
||||
}
|
||||
@@ -514,7 +513,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
|
||||
switch(fields) {
|
||||
case 0:
|
||||
if(ptr[0]=='.') /* skip preceeding dots */
|
||||
if(ptr[0]=='.') /* skip preceding dots */
|
||||
ptr++;
|
||||
co->domain = strdup(ptr);
|
||||
if(!co->domain)
|
||||
@@ -531,7 +530,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
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
|
||||
*/
|
||||
co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE"); /* store information */
|
||||
co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE");
|
||||
break;
|
||||
case 2:
|
||||
/* It turns out, that sometimes the file format allows the path
|
||||
@@ -819,8 +818,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* only process this cookie if it is not expired or had no expire
|
||||
date AND that if the cookie requires we're secure we must only
|
||||
continue if we are! */
|
||||
if( (!co->expires || (co->expires > now)) &&
|
||||
(co->secure?secure:TRUE) ) {
|
||||
if((!co->expires || (co->expires > now)) &&
|
||||
(co->secure?secure:TRUE)) {
|
||||
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
@@ -877,7 +876,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
size_t i;
|
||||
|
||||
/* alloc an array and store all cookie pointers */
|
||||
array = (struct Cookie **)malloc(sizeof(struct Cookie *) * matches);
|
||||
array = malloc(sizeof(struct Cookie *) * matches);
|
||||
if(!array)
|
||||
goto fail;
|
||||
|
||||
@@ -1040,14 +1039,14 @@ static char *get_netscape_format(const struct Cookie *co)
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_cookie_output()
|
||||
* cookie_output()
|
||||
*
|
||||
* Writes all internally known cookies to the specified file. Specify
|
||||
* "-" as file name to write to stdout.
|
||||
*
|
||||
* The function returns non-zero on write failure.
|
||||
*/
|
||||
int Curl_cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
{
|
||||
struct Cookie *co;
|
||||
FILE *out;
|
||||
@@ -1147,7 +1146,7 @@ void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
/* if we have a destination file for all the cookies to get dumped to */
|
||||
if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
|
||||
if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
|
||||
infof(data, "WARNING: failed to save cookies in %s\n",
|
||||
data->set.str[STRING_COOKIEJAR]);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __COOKIE_H
|
||||
#define __COOKIE_H
|
||||
#ifndef HEADER_CURL_COOKIE_H
|
||||
#define HEADER_CURL_COOKIE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -92,13 +92,12 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
int Curl_cookie_output(struct CookieInfo *, const char *);
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||
#define Curl_cookie_list(x) NULL
|
||||
#define Curl_cookie_loadfiles(x) do { } while (0)
|
||||
#define Curl_cookie_init(x,y,z,w) NULL
|
||||
#define Curl_cookie_cleanup(x)
|
||||
#define Curl_cookie_cleanup(x) do { } while (0)
|
||||
#define Curl_flush_cookies(x,y)
|
||||
#else
|
||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
@@ -109,4 +108,4 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -294,7 +295,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
|
||||
size_t ss_size;
|
||||
#ifdef ENABLE_IPV6
|
||||
if (he->h_addrtype == AF_INET6)
|
||||
if(he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof (struct sockaddr_in6);
|
||||
else
|
||||
#endif
|
||||
@@ -486,7 +487,7 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't wanna include in memdebug.c
|
||||
* require a bunch of structs I didn't want to include in memdebug.c
|
||||
*/
|
||||
|
||||
void
|
||||
@@ -506,7 +507,7 @@ curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't wanna include in memdebug.c
|
||||
* require a bunch of structs I didn't want to include in memdebug.c
|
||||
*/
|
||||
|
||||
int
|
||||
|
@@ -1,8 +1,5 @@
|
||||
/* lib/curl_config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the $func function. */
|
||||
#cmakedefine AS_TR_CPP ${AS_TR_CPP}
|
||||
|
||||
/* when building libcurl itself */
|
||||
#cmakedefine BUILDING_LIBCURL ${BUILDING_LIBCURL}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -317,7 +317,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string)
|
||||
unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
|
||||
int rc = 0;
|
||||
|
||||
for (;;) {
|
||||
for(;;) {
|
||||
switch(state) {
|
||||
case CURLFNM_LOOP_DEFAULT:
|
||||
if(*p == '*') {
|
||||
@@ -413,6 +413,9 @@ static int loop(const unsigned char *pattern, const unsigned char *string)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @unittest: 1307
|
||||
*/
|
||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
{
|
||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -50,8 +50,8 @@ Curl_memrchr(const void *s, int c, size_t n)
|
||||
|
||||
p += n - 1;
|
||||
|
||||
while (p >= q) {
|
||||
if (*p == (unsigned char)c)
|
||||
while(p >= q) {
|
||||
if(*p == (unsigned char)c)
|
||||
return (void *)p;
|
||||
p--;
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ static CURLcode rtmp_setup(struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead_connection);
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv rtmp_recv;
|
||||
static Curl_send rtmp_send;
|
||||
@@ -73,6 +73,7 @@ const struct Curl_handler Curl_handler_rtmp = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMP, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
@@ -91,6 +92,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPT, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
@@ -109,6 +111,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMPE, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
@@ -127,6 +130,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPTE, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
@@ -145,10 +149,12 @@ const struct Curl_handler Curl_handler_rtmps = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPS, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpts = {
|
||||
"RTMPTS", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
@@ -162,6 +168,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPTS, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
@@ -171,12 +178,12 @@ static CURLcode rtmp_setup(struct connectdata *conn)
|
||||
{
|
||||
RTMP *r = RTMP_Alloc();
|
||||
|
||||
if (!r)
|
||||
if(!r)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
RTMP_Init(r);
|
||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||
if (!RTMP_SetupURL(r, conn->data->change.url)) {
|
||||
if(!RTMP_SetupURL(r, conn->data->change.url)) {
|
||||
RTMP_Free(r);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
@@ -194,17 +201,19 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
/* We have to know if it's a write before we send the
|
||||
* connect request packet
|
||||
*/
|
||||
if (conn->data->set.upload)
|
||||
if(conn->data->set.upload)
|
||||
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
||||
|
||||
/* For plain streams, use the buffer toggle trick to keep data flowing */
|
||||
if (!(r->Link.lFlags & RTMP_LF_LIVE) && !(r->Link.protocol & RTMP_FEATURE_HTTP))
|
||||
if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
|
||||
!(r->Link.protocol & RTMP_FEATURE_HTTP))
|
||||
r->Link.lFlags |= RTMP_LF_BUFX;
|
||||
|
||||
curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
||||
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
|
||||
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(char *)&tv, sizeof(tv));
|
||||
|
||||
if (!RTMP_Connect1(r, NULL))
|
||||
if(!RTMP_Connect1(r, NULL))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Clients must send a periodic BytesReceived report to the server */
|
||||
@@ -220,13 +229,14 @@ static CURLcode rtmp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
|
||||
if (!RTMP_ConnectStream(r, 0))
|
||||
if(!RTMP_ConnectStream(r, 0))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if (conn->data->set.upload) {
|
||||
if(conn->data->set.upload) {
|
||||
Curl_pgrsSetUploadSize(conn->data, conn->data->set.infilesize);
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||
} else
|
||||
}
|
||||
else
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
@@ -247,7 +257,7 @@ static CURLcode rtmp_disconnect(struct connectdata *conn,
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
(void)dead_connection;
|
||||
if (r) {
|
||||
if(r) {
|
||||
conn->proto.generic = NULL;
|
||||
RTMP_Close(r);
|
||||
RTMP_Free(r);
|
||||
@@ -264,12 +274,13 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
nread = RTMP_Read(r, buf, len);
|
||||
if (nread < 0) {
|
||||
if (r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
if(nread < 0) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
conn->data->req.size = conn->data->req.bytecount;
|
||||
nread = 0;
|
||||
} else
|
||||
}
|
||||
else
|
||||
*err = CURLE_RECV_ERROR;
|
||||
}
|
||||
return nread;
|
||||
@@ -284,9 +295,9 @@ static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
num = RTMP_Write(r, (char *)buf, len);
|
||||
if (num < 0) {
|
||||
if(num < 0)
|
||||
*err = CURLE_SEND_ERROR;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
#endif /* USE_LIBRTMP */
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* When including the folowing three headers, it is mandatory to define either
|
||||
* When including the following three headers, it is mandatory to define either
|
||||
* SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
|
||||
*/
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -95,7 +95,8 @@ int Curl_thread_join(curl_thread_t *hnd)
|
||||
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), void *arg)
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
|
||||
void *arg)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||
|
45
lib/cyassl.c
45
lib/cyassl.c
@@ -122,12 +122,13 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* load trusted cacert */
|
||||
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||
if (!SSL_CTX_load_verify_locations(conssl->ctx,
|
||||
data->set.str[STRING_SSL_CAFILE],
|
||||
data->set.str[STRING_SSL_CAPATH])) {
|
||||
if (data->set.ssl.verifypeer) {
|
||||
if(!SSL_CTX_load_verify_locations(conssl->ctx,
|
||||
data->set.str[STRING_SSL_CAFILE],
|
||||
data->set.str[STRING_SSL_CAPATH])) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* Fail if we insiste on successfully verifying the server. */
|
||||
failf(data,"error setting certificate verify locations:\n"
|
||||
" CAfile: %s\n CApath: %s\n",
|
||||
@@ -161,7 +162,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
|
||||
int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
|
||||
|
||||
if (SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
|
||||
if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to use client certificate (no key or wrong pass"
|
||||
" phrase?)");
|
||||
@@ -169,12 +170,17 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
|
||||
if (SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
|
||||
if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to set private key");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(CyaSSL_no_filesystem_verify(conssl->ctx)!= SSL_SUCCESS) {
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
#endif /* NO_FILESYSTEM */
|
||||
|
||||
/* SSL always tries to verify the peer, this only says whether it should
|
||||
* fail to connect if the verification fails, or if it should continue
|
||||
@@ -185,10 +191,10 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
NULL);
|
||||
|
||||
/* Let's make an SSL structure */
|
||||
if (conssl->handle)
|
||||
if(conssl->handle)
|
||||
SSL_free(conssl->handle);
|
||||
conssl->handle = SSL_new(conssl->ctx);
|
||||
if (!conssl->handle) {
|
||||
if(!conssl->handle) {
|
||||
failf(data, "SSL: couldn't create a context (handle)!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -206,7 +212,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* pass the raw socket into the SSL layer */
|
||||
if (!SSL_set_fd(conssl->handle, (int)sockfd)) {
|
||||
if(!SSL_set_fd(conssl->handle, (int)sockfd)) {
|
||||
failf(data, "SSL: SSL_set_fd failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@@ -231,16 +237,16 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
conn->send[sockindex] = cyassl_send;
|
||||
|
||||
ret = SSL_connect(conssl->handle);
|
||||
if (ret != 1) {
|
||||
if(ret != 1) {
|
||||
char error_buffer[80];
|
||||
int detail = SSL_get_error(conssl->handle, ret);
|
||||
|
||||
if (SSL_ERROR_WANT_READ == detail) {
|
||||
if(SSL_ERROR_WANT_READ == detail) {
|
||||
conssl->connecting_state = ssl_connect_2_reading;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if (SSL_ERROR_WANT_WRITE == detail) {
|
||||
if(SSL_ERROR_WANT_WRITE == detail) {
|
||||
conssl->connecting_state = ssl_connect_2_writing;
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -273,14 +279,14 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
our_ssl_sessionid = SSL_get_session(connssl->handle);
|
||||
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||
if (incache) {
|
||||
if (old_ssl_sessionid != our_ssl_sessionid) {
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||
incache = FALSE;
|
||||
}
|
||||
}
|
||||
if (!incache) {
|
||||
if(!incache) {
|
||||
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
||||
0 /* unknown size */);
|
||||
if(retcode) {
|
||||
@@ -305,7 +311,7 @@ static ssize_t cyassl_send(struct connectdata *conn,
|
||||
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||
int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
|
||||
|
||||
if (rc < 0) {
|
||||
if(rc < 0) {
|
||||
int err = SSL_get_error(conn->ssl[sockindex].handle, rc);
|
||||
|
||||
switch(err) {
|
||||
@@ -355,7 +361,7 @@ static ssize_t cyassl_recv(struct connectdata *conn,
|
||||
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
|
||||
int nread = SSL_read(conn->ssl[num].handle, buf, buffsize);
|
||||
|
||||
if (nread < 0) {
|
||||
if(nread < 0) {
|
||||
int err = SSL_get_error(conn->ssl[num].handle, nread);
|
||||
|
||||
switch(err) {
|
||||
@@ -405,7 +411,7 @@ int Curl_cyassl_init(void)
|
||||
|
||||
bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex)
|
||||
{
|
||||
if (conn->ssl[connindex].handle) /* SSL is in use */
|
||||
if(conn->ssl[connindex].handle) /* SSL is in use */
|
||||
return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
|
||||
else
|
||||
return FALSE;
|
||||
@@ -484,8 +490,7 @@ cyassl_connect_common(struct connectdata *conn,
|
||||
curl_socket_t readfd = ssl_connect_2_reading==
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd,
|
||||
nonblocking?0:(int)timeout_ms);
|
||||
what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
|
@@ -107,6 +107,7 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_DICT, /* defport */
|
||||
CURLPROTO_DICT, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -279,7 +280,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
int i;
|
||||
|
||||
ppath++;
|
||||
for (i = 0; ppath[i]; i++) {
|
||||
for(i = 0; ppath[i]; i++) {
|
||||
if(ppath[i] == ':')
|
||||
ppath[i] = ' ';
|
||||
}
|
||||
|
245
lib/easy.c
245
lib/easy.c
@@ -85,22 +85,12 @@
|
||||
#include "connect.h" /* for Curl_getconnectinfo */
|
||||
#include "slist.h"
|
||||
#include "curl_rand.h"
|
||||
#include "non-ascii.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||
#include <iconv.h>
|
||||
/* set default codesets for iconv */
|
||||
#ifndef CURL_ICONV_CODESET_OF_NETWORK
|
||||
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||
#endif
|
||||
#ifndef CURL_ICONV_CODESET_FOR_UTF8
|
||||
#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||
#endif
|
||||
#define ICONV_ERROR (size_t)-1
|
||||
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -144,8 +134,8 @@ static CURLcode win32_init(void)
|
||||
/* wVersionRequested in wVersion. wHighVersion contains the */
|
||||
/* highest supported version. */
|
||||
|
||||
if( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
||||
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
||||
if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
||||
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
||||
/* Tell the user that we couldn't find a useable */
|
||||
|
||||
/* winsock.dll. */
|
||||
@@ -158,7 +148,7 @@ static CURLcode win32_init(void)
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
{
|
||||
CURLcode err = Curl_sspi_global_init();
|
||||
if (err != CURLE_OK)
|
||||
if(err != CURLE_OK)
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@@ -280,12 +270,10 @@ CURLcode curl_global_init(long flags)
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
||||
if(ares_library_init(ARES_LIB_INIT_ALL)) {
|
||||
DEBUGF(fprintf(stderr, "Error: ares_library_init failed\n"));
|
||||
if(Curl_resolver_global_init() != CURLE_OK) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
|
||||
if(libssh2_init(0)) {
|
||||
@@ -318,7 +306,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Already initialized, don't do it again */
|
||||
if( initialized )
|
||||
if(initialized)
|
||||
return CURLE_OK;
|
||||
|
||||
/* Call the actual init function first */
|
||||
@@ -351,9 +339,7 @@ void curl_global_cleanup(void)
|
||||
if(init_flags & CURL_GLOBAL_SSL)
|
||||
Curl_ssl_cleanup();
|
||||
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
|
||||
ares_library_cleanup();
|
||||
#endif
|
||||
Curl_resolver_global_cleanup();
|
||||
|
||||
if(init_flags & CURL_GLOBAL_WIN32)
|
||||
win32_cleanup();
|
||||
@@ -521,7 +507,7 @@ CURLcode curl_easy_perform(CURL *curl)
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
if( ! (data->share && data->share->hostcache) ) {
|
||||
if(! (data->share && data->share->hostcache)) {
|
||||
/* this handle is not using a shared dns cache */
|
||||
|
||||
if(data->set.global_dns_cache &&
|
||||
@@ -687,21 +673,12 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
outcurl->change.referer_alloc = TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_ARES
|
||||
/* If we use ares, we clone the ares channel for the new handle */
|
||||
if(ARES_SUCCESS != ares_dup(&outcurl->state.areschannel,
|
||||
data->state.areschannel))
|
||||
/* Clone the resolver handle, if present, for the new handle */
|
||||
if(Curl_resolver_duphandle(&outcurl->state.resolver,
|
||||
data->state.resolver) != CURLE_OK)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||
outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
#endif
|
||||
Curl_convert_setup(outcurl);
|
||||
|
||||
Curl_easy_initHandleData(outcurl);
|
||||
|
||||
@@ -788,8 +765,8 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
k->keepon = newstate;
|
||||
|
||||
if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
|
||||
/* we have a buffer for sending that we now seem to be able to deliver since
|
||||
the receive pausing is lifted! */
|
||||
/* we have a buffer for sending that we now seem to be able to deliver
|
||||
since the receive pausing is lifted! */
|
||||
|
||||
/* get the pointer, type and length in local copies since the function may
|
||||
return PAUSE again and then we'll get a new copy allocted and stored in
|
||||
@@ -863,196 +840,6 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* Curl_convert_to_network() is an internal function
|
||||
* for performing ASCII conversions on non-ASCII platforms.
|
||||
*/
|
||||
CURLcode Curl_convert_to_network(struct SessionHandle *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
CURLcode rc;
|
||||
|
||||
if(data->set.convtonetwork) {
|
||||
/* use translation callback */
|
||||
rc = data->set.convtonetwork(buffer, length);
|
||||
if(rc != CURLE_OK) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)rc, curl_easy_strerror(rc));
|
||||
}
|
||||
return(rc);
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->outbound_cd == (iconv_t)-1) {
|
||||
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
if(data->outbound_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The Curl_convert_to_network iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_network() is an internal function
|
||||
* for performing ASCII conversions on non-ASCII platforms.
|
||||
*/
|
||||
CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
CURLcode rc;
|
||||
|
||||
if(data->set.convfromnetwork) {
|
||||
/* use translation callback */
|
||||
rc = data->set.convfromnetwork(buffer, length);
|
||||
if(rc != CURLE_OK) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)rc, curl_easy_strerror(rc));
|
||||
}
|
||||
return(rc);
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->inbound_cd == (iconv_t)-1) {
|
||||
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
if(data->inbound_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_utf8() is an internal function
|
||||
* for performing UTF-8 conversions on non-ASCII platforms.
|
||||
*/
|
||||
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
CURLcode rc;
|
||||
|
||||
if(data->set.convfromutf8) {
|
||||
/* use translation callback */
|
||||
rc = data->set.convfromutf8(buffer, length);
|
||||
if(rc != CURLE_OK) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
|
||||
(int)rc, curl_easy_strerror(rc));
|
||||
}
|
||||
return(rc);
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
const char *input_ptr;
|
||||
char *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
int error;
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data->utf8_cd == (iconv_t)-1) {
|
||||
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
if(data->utf8_cd == (iconv_t)-1) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8,
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||
error = ERRNO;
|
||||
failf(data,
|
||||
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
|
||||
error, strerror(error));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
if(output_ptr < input_ptr) {
|
||||
/* null terminate the now shorter output string */
|
||||
*output_ptr = 0x00;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
static CURLcode easy_connection(struct SessionHandle *data,
|
||||
curl_socket_t *sfd,
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -29,11 +29,4 @@ void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
|
||||
|
||||
void Curl_easy_initHandleData(struct SessionHandle *data);
|
||||
|
||||
CURLcode Curl_convert_to_network(struct SessionHandle *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
||||
char *buffer, size_t length);
|
||||
|
||||
#endif /* __EASYIF_H */
|
||||
|
34
lib/escape.c
34
lib/escape.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -31,10 +31,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "curl_memory.h"
|
||||
/* urldata.h and easyif.h are included for Curl_convert_... prototypes */
|
||||
#include "urldata.h"
|
||||
#include "easyif.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -90,11 +89,8 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
size_t newlen = alloc;
|
||||
int strindex=0;
|
||||
size_t length;
|
||||
CURLcode res;
|
||||
|
||||
#ifndef CURL_DOES_CONVERSIONS
|
||||
/* avoid compiler warnings */
|
||||
(void)handle;
|
||||
#endif
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
@@ -103,10 +99,9 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
while(length--) {
|
||||
in = *string;
|
||||
|
||||
if (Curl_isunreserved(in)) {
|
||||
if(Curl_isunreserved(in))
|
||||
/* just copy this */
|
||||
ns[strindex++]=in;
|
||||
}
|
||||
else {
|
||||
/* encode it */
|
||||
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
||||
@@ -122,15 +117,12 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
|
||||
if(!handle ||
|
||||
(Curl_convert_to_network(handle, &in, 1) != CURLE_OK)) {
|
||||
res = Curl_convert_to_network(handle, &in, 1);
|
||||
if(res) {
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
snprintf(&ns[strindex], 4, "%%%02X", in);
|
||||
|
||||
@@ -156,12 +148,9 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
unsigned char in;
|
||||
int strindex=0;
|
||||
unsigned long hex;
|
||||
CURLcode res;
|
||||
|
||||
#ifndef CURL_DOES_CONVERSIONS
|
||||
/* avoid compiler warnings */
|
||||
(void)handle;
|
||||
#endif
|
||||
if( !ns )
|
||||
if(!ns)
|
||||
return NULL;
|
||||
|
||||
while(--alloc > 0) {
|
||||
@@ -178,15 +167,12 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
|
||||
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
|
||||
if(!handle ||
|
||||
(Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) {
|
||||
res = Curl_convert_from_network(handle, &in, 1);
|
||||
if(res) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
string+=2;
|
||||
alloc-=2;
|
||||
|
23
lib/file.c
23
lib/file.c
@@ -90,7 +90,8 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || defined(__SYMBIAN32__)
|
||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
|
||||
defined(__SYMBIAN32__)
|
||||
#define DOS_FILESYSTEM 1
|
||||
#endif
|
||||
|
||||
@@ -126,9 +127,10 @@ const struct Curl_handler Curl_handler_file = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
0, /* defport */
|
||||
CURLPROTO_FILE, /* protocol */
|
||||
PROTOPT_BANPROXY /* flags */
|
||||
PROTOPT_NONETWORK /* flags */
|
||||
};
|
||||
|
||||
|
||||
@@ -245,18 +247,17 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
actual_path = real_path;
|
||||
if((actual_path[0] == '/') &&
|
||||
actual_path[1] &&
|
||||
(actual_path[2] == ':' || actual_path[2] == '|'))
|
||||
{
|
||||
(actual_path[2] == ':' || actual_path[2] == '|')) {
|
||||
actual_path[2] = ':';
|
||||
actual_path++;
|
||||
}
|
||||
|
||||
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
|
||||
for (i=0; actual_path[i] != '\0'; ++i)
|
||||
for(i=0; actual_path[i] != '\0'; ++i)
|
||||
if(actual_path[i] == '/')
|
||||
actual_path[i] = '\\';
|
||||
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY); /* no CR/LF translation */
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
@@ -377,7 +378,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
|
||||
/*skip bytes before resume point*/
|
||||
if(data->state.resume_from) {
|
||||
if( (curl_off_t)nread <= data->state.resume_from ) {
|
||||
if((curl_off_t)nread <= data->state.resume_from ) {
|
||||
data->state.resume_from -= nread;
|
||||
nread = 0;
|
||||
buf2 = buf;
|
||||
@@ -456,7 +457,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
fd = conn->data->state.proto.file->fd;
|
||||
|
||||
/* VMS: This only works reliable for STREAMLF files */
|
||||
if( -1 != fstat(fd, &statbuf)) {
|
||||
if(-1 != fstat(fd, &statbuf)) {
|
||||
/* we could stat it, then read out the size */
|
||||
expected_size = statbuf.st_size;
|
||||
/* and store the modification time */
|
||||
@@ -536,7 +537,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* A high water mark has been specified so we obey... */
|
||||
if (data->req.maxdownload > 0)
|
||||
if(data->req.maxdownload > 0)
|
||||
expected_size = data->req.maxdownload;
|
||||
|
||||
if(fstated && (expected_size == 0))
|
||||
@@ -562,10 +563,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
bytestoread = (expected_size < BUFSIZE-1)?(size_t)expected_size:BUFSIZE-1;
|
||||
nread = read(fd, buf, bytestoread);
|
||||
|
||||
if( nread > 0)
|
||||
if(nread > 0)
|
||||
buf[nread] = 0;
|
||||
|
||||
if (nread <= 0 || expected_size == 0)
|
||||
if(nread <= 0 || expected_size == 0)
|
||||
break;
|
||||
|
||||
bytecount += nread;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010-2011, 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
|
||||
@@ -55,21 +55,3 @@ void Curl_fileinfo_dtor(void *user, void *element)
|
||||
|
||||
free(finfo);
|
||||
}
|
||||
|
||||
struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src)
|
||||
{
|
||||
struct curl_fileinfo *ptr = malloc(sizeof(struct curl_fileinfo));
|
||||
if(!ptr)
|
||||
return NULL;
|
||||
*ptr = *src;
|
||||
|
||||
ptr->b_data = malloc(src->b_size);
|
||||
if(!ptr->b_data) {
|
||||
free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
memcpy(ptr->b_data, src->b_data, src->b_size);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
381
lib/formdata.c
381
lib/formdata.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -20,87 +20,6 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
Debug the form generator stand-alone by compiling this source file with:
|
||||
|
||||
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata \
|
||||
-I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c
|
||||
|
||||
(depending on circumstances you may need further externals added)
|
||||
|
||||
run the 'formdata' executable the output should end with:
|
||||
All Tests seem to have worked ...
|
||||
and the following parts should be there:
|
||||
|
||||
Content-Disposition: form-data; name="simple_COPYCONTENTS"
|
||||
value for simple COPYCONTENTS
|
||||
|
||||
Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE"
|
||||
Content-Type: image/gif
|
||||
value for COPYCONTENTS + CONTENTTYPE
|
||||
|
||||
Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"
|
||||
vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH
|
||||
(or you might see P^@RNAME and v^@lue at the start)
|
||||
|
||||
Content-Disposition: form-data; name="simple_PTRCONTENTS"
|
||||
value for simple PTRCONTENTS
|
||||
|
||||
Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH"
|
||||
vlue for PTRCONTENTS + CONTENTSLENGTH
|
||||
(or you might see v^@lue at the start)
|
||||
|
||||
Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"
|
||||
Content-Type: application/octet-stream
|
||||
vlue for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE
|
||||
(or you might see v^@lue at the start)
|
||||
|
||||
Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="formdata.h"
|
||||
Content-Type: text/html
|
||||
...
|
||||
|
||||
Content-Disposition: form-data; name="FILE1_+_FILE2"
|
||||
Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
|
||||
...
|
||||
Content-Disposition: attachment; filename="formdata.h"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
|
||||
Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3"
|
||||
Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
|
||||
...
|
||||
Content-Disposition: attachment; filename="formdata.h"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
Content-Disposition: attachment; filename="formdata.h"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
|
||||
|
||||
Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3"
|
||||
Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
|
||||
...
|
||||
Content-Disposition: attachment; filename="formdata.h"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
Content-Disposition: attachment; filename="formdata.h"
|
||||
Content-Type: application/octet-stream
|
||||
...
|
||||
|
||||
Content-Disposition: form-data; name="FILECONTENT"
|
||||
...
|
||||
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -118,7 +37,6 @@ Content-Disposition: form-data; name="FILECONTENT"
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#include "urldata.h" /* for struct SessionHandle */
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "formdata.h"
|
||||
#include "curl_rand.h"
|
||||
#include "strequal.h"
|
||||
@@ -383,7 +301,7 @@ static char *memdup(const char *src, size_t buffer_length)
|
||||
* CURL_FORMADD_NULL if a null pointer was given for a char
|
||||
* CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
||||
* CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
|
||||
* CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
|
||||
* CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
|
||||
* CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
|
||||
* CURL_FORMADD_MEMORY if some allocation for string copying failed.
|
||||
* CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
||||
@@ -423,7 +341,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
while(return_value == CURL_FORMADD_OK) {
|
||||
|
||||
/* first see if we have more parts of the array param */
|
||||
if( array_state && forms ) {
|
||||
if(array_state && forms) {
|
||||
/* get the upcoming option from the given array */
|
||||
option = forms->option;
|
||||
array_value = (char *)forms->value;
|
||||
@@ -461,8 +379,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
*/
|
||||
case CURLFORM_PTRNAME:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
|
||||
have safe memory for the eventual conversion */
|
||||
/* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
|
||||
* the data in all cases so that we'll have safe memory for the eventual
|
||||
* conversion.
|
||||
*/
|
||||
#else
|
||||
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
#endif
|
||||
@@ -678,7 +598,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
(struct curl_slist*)array_value:
|
||||
va_arg(params, struct curl_slist*);
|
||||
|
||||
if( current_form->contentheader )
|
||||
if(current_form->contentheader)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->contentheader = list;
|
||||
@@ -689,7 +609,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
{
|
||||
const char *filename = array_state?array_value:
|
||||
va_arg(params, char *);
|
||||
if( current_form->showfilename )
|
||||
if(current_form->showfilename)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
current_form->showfilename = strdup(filename);
|
||||
@@ -713,26 +633,26 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
for(form = first_form;
|
||||
form != NULL;
|
||||
form = form->more) {
|
||||
if( ((!form->name || !form->value) && !post) ||
|
||||
( (form->contentslength) &&
|
||||
(form->flags & HTTPPOST_FILENAME) ) ||
|
||||
( (form->flags & HTTPPOST_FILENAME) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
|
||||
if(((!form->name || !form->value) && !post) ||
|
||||
( (form->contentslength) &&
|
||||
(form->flags & HTTPPOST_FILENAME) ) ||
|
||||
( (form->flags & HTTPPOST_FILENAME) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
|
||||
|
||||
( (!form->buffer) &&
|
||||
(form->flags & HTTPPOST_BUFFER) &&
|
||||
(form->flags & HTTPPOST_PTRBUFFER) ) ||
|
||||
( (!form->buffer) &&
|
||||
(form->flags & HTTPPOST_BUFFER) &&
|
||||
(form->flags & HTTPPOST_PTRBUFFER) ) ||
|
||||
|
||||
( (form->flags & HTTPPOST_READFILE) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) )
|
||||
( (form->flags & HTTPPOST_READFILE) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) )
|
||||
) {
|
||||
return_value = CURL_FORMADD_INCOMPLETE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if( ((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype ) {
|
||||
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype ) {
|
||||
/* our contenttype is missing */
|
||||
form->contenttype
|
||||
= strdup(ContentTypeForFilename(form->value, prevtype));
|
||||
@@ -742,8 +662,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
}
|
||||
form->contenttype_alloc = TRUE;
|
||||
}
|
||||
if( !(form->flags & HTTPPOST_PTRNAME) &&
|
||||
(form == first_form) ) {
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) &&
|
||||
(form == first_form) ) {
|
||||
/* Note that there's small risk that form->name is NULL here if the
|
||||
app passed in a bad combo, so we better check for that first. */
|
||||
if(form->name)
|
||||
@@ -755,9 +675,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
}
|
||||
form->name_alloc = TRUE;
|
||||
}
|
||||
if( !(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) ) {
|
||||
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) ) {
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
form->value = memdup(form->value, form->contentslength);
|
||||
if(!form->value) {
|
||||
@@ -817,6 +737,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
|
||||
/*
|
||||
* curl_formadd() is a public API to add a section to the multipart formpost.
|
||||
*
|
||||
* @unittest: 1308
|
||||
*/
|
||||
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
@@ -934,40 +856,12 @@ void Curl_formclean(struct FormData **form_ptr)
|
||||
*form_ptr = NULL;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* Curl_formcovert() is used from http.c, this converts any
|
||||
form items that need to be sent in the network encoding.
|
||||
Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
|
||||
{
|
||||
struct FormData *next;
|
||||
CURLcode rc;
|
||||
|
||||
if(!form)
|
||||
return CURLE_OK;
|
||||
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
do {
|
||||
next=form->next; /* the following form line */
|
||||
if(form->type == FORM_DATA) {
|
||||
rc = Curl_convert_to_network(data, form->line, form->length);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(rc != CURLE_OK)
|
||||
return rc;
|
||||
}
|
||||
} while((form = next) != NULL); /* continue */
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
/*
|
||||
* curl_formget()
|
||||
* Serialize a curl_httppost struct.
|
||||
* Returns 0 on success.
|
||||
*
|
||||
* @unittest: 1308
|
||||
*/
|
||||
int curl_formget(struct curl_httppost *form, void *arg,
|
||||
curl_formget_callback append)
|
||||
@@ -980,8 +874,8 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
||||
if(rc != CURLE_OK)
|
||||
return (int)rc;
|
||||
|
||||
for (ptr = data; ptr; ptr = ptr->next) {
|
||||
if(ptr->type == FORM_FILE) {
|
||||
for(ptr = data; ptr; ptr = ptr->next) {
|
||||
if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
|
||||
char buffer[8192];
|
||||
size_t nread;
|
||||
struct Form temp;
|
||||
@@ -997,7 +891,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
||||
Curl_formclean(&data);
|
||||
return -1;
|
||||
}
|
||||
} while(nread == sizeof(buffer));
|
||||
} while(nread);
|
||||
}
|
||||
else {
|
||||
if(ptr->length != append(arg, ptr->line, ptr->length)) {
|
||||
@@ -1029,10 +923,10 @@ void curl_formfree(struct curl_httppost *form)
|
||||
if(form->more)
|
||||
curl_formfree(form->more);
|
||||
|
||||
if( !(form->flags & HTTPPOST_PTRNAME) && form->name)
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
|
||||
free(form->name); /* free the name */
|
||||
if( !(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
|
||||
form->contents)
|
||||
if(!(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
|
||||
form->contents)
|
||||
free(form->contents); /* free the contents */
|
||||
if(form->contenttype)
|
||||
free(form->contenttype); /* free the content type */
|
||||
@@ -1240,15 +1134,17 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
/* it should be noted that for the HTTPPOST_FILENAME and
|
||||
HTTPPOST_CALLBACK cases the ->showfilename struct member is always
|
||||
assigned at this point */
|
||||
char *filebasename=
|
||||
(!post->showfilename)?strippath(post->contents):NULL;
|
||||
if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
|
||||
char *filebasename=
|
||||
(!post->showfilename)?strippath(post->contents):NULL;
|
||||
|
||||
result = AddFormDataf(&form, &size,
|
||||
"; filename=\"%s\"",
|
||||
(post->showfilename?post->showfilename:
|
||||
filebasename));
|
||||
if(filebasename)
|
||||
free(filebasename);
|
||||
result = AddFormDataf(&form, &size,
|
||||
"; filename=\"%s\"",
|
||||
(post->showfilename?post->showfilename:
|
||||
filebasename));
|
||||
if(filebasename)
|
||||
free(filebasename);
|
||||
}
|
||||
|
||||
if(result)
|
||||
break;
|
||||
@@ -1264,7 +1160,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
curList = file->contentheader;
|
||||
while( curList ) {
|
||||
while(curList) {
|
||||
/* Process the additional headers specified for this form */
|
||||
result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
|
||||
if(result)
|
||||
@@ -1407,8 +1303,17 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
||||
size_t nread;
|
||||
bool callback = (bool)(form->data->type == FORM_CALLBACK);
|
||||
|
||||
if(callback)
|
||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
||||
if(callback) {
|
||||
if(form->fread_func == ZERO_NULL)
|
||||
return 0;
|
||||
else
|
||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
||||
|
||||
if(nread > size)
|
||||
/* the read callback can return a value larger than the buffer but
|
||||
treat any such as no data in this case */
|
||||
nread = 0;
|
||||
}
|
||||
else {
|
||||
if(!form->fp) {
|
||||
/* this file hasn't yet been opened */
|
||||
@@ -1418,9 +1323,9 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
||||
}
|
||||
nread = fread(buffer, 1, size, form->fp);
|
||||
}
|
||||
if(!nread || nread > size) {
|
||||
if(!nread) {
|
||||
/* this is the last chunk from the file, move on */
|
||||
if(!callback) {
|
||||
if(form->fp) {
|
||||
fclose(form->fp);
|
||||
form->fp = NULL;
|
||||
}
|
||||
@@ -1460,7 +1365,7 @@ size_t Curl_FormReader(char *buffer,
|
||||
}
|
||||
do {
|
||||
|
||||
if( (form->data->length - form->sent ) > wantedsize - gotsize) {
|
||||
if((form->data->length - form->sent ) > wantedsize - gotsize) {
|
||||
|
||||
memcpy(buffer + gotsize , form->data->line + form->sent,
|
||||
wantedsize - gotsize);
|
||||
@@ -1507,168 +1412,6 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _FORM_DEBUG
|
||||
int FormAddTest(const char * errormsg,
|
||||
struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...)
|
||||
{
|
||||
int result;
|
||||
va_list arg;
|
||||
va_start(arg, last_post);
|
||||
if((result = FormAdd(httppost, last_post, arg)))
|
||||
fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result,
|
||||
errormsg);
|
||||
va_end(arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, argv_item_t argv[])
|
||||
{
|
||||
char name1[] = "simple_COPYCONTENTS";
|
||||
char name2[] = "COPYCONTENTS_+_CONTENTTYPE";
|
||||
char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH";
|
||||
char name4[] = "simple_PTRCONTENTS";
|
||||
char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH";
|
||||
char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE";
|
||||
char name7[] = "FILE1_+_CONTENTTYPE";
|
||||
char name8[] = "FILE1_+_FILE2";
|
||||
char name9[] = "FILE1_+_FILE2_+_FILE3";
|
||||
char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3";
|
||||
char name11[] = "FILECONTENT";
|
||||
char value1[] = "value for simple COPYCONTENTS";
|
||||
char value2[] = "value for COPYCONTENTS + CONTENTTYPE";
|
||||
char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH";
|
||||
char value4[] = "value for simple PTRCONTENTS";
|
||||
char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
|
||||
char value6[] = "value for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE";
|
||||
char value7[] = "formdata.h";
|
||||
char value8[] = "Makefile.b32";
|
||||
char type2[] = "image/gif";
|
||||
char type6[] = "text/plain";
|
||||
char type7[] = "text/html";
|
||||
int name3length = strlen(name3);
|
||||
int value3length = strlen(value3);
|
||||
int value5length = strlen(value5);
|
||||
int value6length = strlen(value6);
|
||||
int errors = 0;
|
||||
CURLcode rc;
|
||||
curl_off_t size;
|
||||
size_t nread;
|
||||
char buffer[4096];
|
||||
struct curl_httppost *httppost=NULL;
|
||||
struct curl_httppost *last_post=NULL;
|
||||
struct curl_forms forms[4];
|
||||
|
||||
struct FormData *form;
|
||||
struct Form formread;
|
||||
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
Curl_srand(); /* Because we do not call curl_global_init() here. */
|
||||
|
||||
if(FormAddTest("simple COPYCONTENTS test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1,
|
||||
CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2,
|
||||
CURLFORM_CONTENTTYPE, type2, CURLFORM_END))
|
||||
++errors;
|
||||
/* make null character at start to check that contentslength works
|
||||
correctly */
|
||||
name3[1] = '\0';
|
||||
value3[1] = '\0';
|
||||
if(FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test",
|
||||
&httppost, &last_post,
|
||||
CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3,
|
||||
CURLFORM_CONTENTSLENGTH, value3length,
|
||||
CURLFORM_NAMELENGTH, name3length, CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("simple PTRCONTENTS test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4,
|
||||
CURLFORM_END))
|
||||
++errors;
|
||||
/* make null character at start to check that contentslength works
|
||||
correctly */
|
||||
value5[1] = '\0';
|
||||
if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5,
|
||||
CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END))
|
||||
++errors;
|
||||
/* make null character at start to check that contentslength works
|
||||
correctly */
|
||||
value6[1] = '\0';
|
||||
if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test",
|
||||
&httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6,
|
||||
CURLFORM_CONTENTSLENGTH, value6length,
|
||||
CURLFORM_CONTENTTYPE, type6, CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7,
|
||||
CURLFORM_CONTENTTYPE, type7, CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("FILE1 + FILE2 test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7,
|
||||
CURLFORM_FILE, value8, CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7,
|
||||
CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END))
|
||||
++errors;
|
||||
forms[0].option = CURLFORM_FILE;
|
||||
forms[0].value = value7;
|
||||
forms[1].option = CURLFORM_FILE;
|
||||
forms[1].value = value8;
|
||||
forms[2].option = CURLFORM_FILE;
|
||||
forms[2].value = value7;
|
||||
forms[3].option = CURLFORM_END;
|
||||
if(FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms,
|
||||
CURLFORM_END))
|
||||
++errors;
|
||||
if(FormAddTest("FILECONTENT test", &httppost, &last_post,
|
||||
CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7,
|
||||
CURLFORM_END))
|
||||
++errors;
|
||||
|
||||
rc = Curl_getformdata(NULL, &form, httppost, NULL, &size);
|
||||
if(rc != CURLE_OK) {
|
||||
if(rc != CURLE_READ_ERROR) {
|
||||
const char *errortext = curl_easy_strerror(rc);
|
||||
fprintf(stdout, "\n==> Curl_getformdata error: %s\n", errortext);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Curl_FormInit(&formread, form);
|
||||
|
||||
for(;;) {
|
||||
nread = Curl_FormReader(buffer, 1, sizeof(buffer),
|
||||
(FILE *)&formread);
|
||||
|
||||
if(nread < 1)
|
||||
break;
|
||||
fwrite(buffer, nread, 1, stdout);
|
||||
}
|
||||
|
||||
fprintf(stdout, "size: ");
|
||||
fprintf(stdout, "%" FORMAT_OFF_T, size);
|
||||
fprintf(stdout, "\n");
|
||||
if(errors)
|
||||
fprintf(stdout, "\n==> %d Test(s) failed!\n", errors);
|
||||
else
|
||||
fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _FORM_DEBUG */
|
||||
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
|
149
lib/ftp.c
149
lib/ftp.c
@@ -61,8 +61,6 @@
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
|
||||
#include "if2ip.h"
|
||||
#include "hostip.h"
|
||||
#include "progress.h"
|
||||
@@ -94,6 +92,7 @@
|
||||
#include "speedcheck.h"
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -179,9 +178,10 @@ const struct Curl_handler Curl_handler_ftp = {
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_FTP, /* defport */
|
||||
CURLPROTO_FTP, /* protocol */
|
||||
PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
|
||||
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
|
||||
};
|
||||
|
||||
|
||||
@@ -203,9 +203,11 @@ const struct Curl_handler Curl_handler_ftps = {
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_FTPS, /* defport */
|
||||
CURLPROTO_FTP | CURLPROTO_FTPS, /* protocol */
|
||||
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
|
||||
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
|
||||
PROTOPT_NEEDSPWD /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -227,6 +229,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_FTP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -251,6 +254,7 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_FTPS, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -275,7 +279,7 @@ static void freedirs(struct ftp_conn *ftpc)
|
||||
{
|
||||
int i;
|
||||
if(ftpc->dirs) {
|
||||
for (i=0; i < ftpc->dirdepth; i++){
|
||||
for(i=0; i < ftpc->dirdepth; i++){
|
||||
if(ftpc->dirs[i]) {
|
||||
free(ftpc->dirs[i]);
|
||||
ftpc->dirs[i]=NULL;
|
||||
@@ -339,7 +343,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
if(timeout_ms < interval_ms)
|
||||
interval_ms = timeout_ms;
|
||||
|
||||
switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, (int)interval_ms)) {
|
||||
switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, interval_ms)) {
|
||||
case -1: /* error */
|
||||
/* let's die here */
|
||||
failf(data, "Error while waiting for server connect");
|
||||
@@ -353,7 +357,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
|
||||
s=accept(sock, (struct sockaddr *) &add, &size);
|
||||
}
|
||||
sclose(sock); /* close the first socket */
|
||||
Curl_closesocket(conn, sock); /* close the first socket */
|
||||
|
||||
if(CURL_SOCKET_BAD == s) {
|
||||
failf(data, "Error accept()ing server connect");
|
||||
@@ -513,7 +517,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
*/
|
||||
}
|
||||
else {
|
||||
switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, (int)interval_ms)) {
|
||||
switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
failf(data, "FTP response aborted due to select/poll error: %d",
|
||||
SOCKERRNO);
|
||||
@@ -742,7 +746,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
char *port_sep = NULL;
|
||||
|
||||
addr = calloc(addrlen+1, 1);
|
||||
if (!addr)
|
||||
if(!addr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
@@ -754,11 +758,11 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( *string_ftpport == ':') {
|
||||
if(*string_ftpport == ':') {
|
||||
/* :port */
|
||||
ip_end = string_ftpport;
|
||||
}
|
||||
else if( (ip_end = strchr(string_ftpport, ':')) != NULL) {
|
||||
else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
|
||||
/* either ipv6 or (ipv4|domain|interface):port(-range) */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
|
||||
@@ -766,19 +770,18 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
port_min = port_max = 0;
|
||||
strcpy(addr, string_ftpport);
|
||||
ip_end = NULL; /* this got no port ! */
|
||||
} else
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* (ipv4|domain|interface):port(-range) */
|
||||
strncpy(addr, string_ftpport, ip_end - ip_start );
|
||||
}
|
||||
}
|
||||
else
|
||||
/* ipv4|interface */
|
||||
strcpy(addr, string_ftpport);
|
||||
|
||||
/* parse the port */
|
||||
if( ip_end != NULL ) {
|
||||
if(ip_end != NULL) {
|
||||
if((port_start = strchr(ip_end, ':')) != NULL) {
|
||||
port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
|
||||
if((port_sep = strchr(port_start, '-')) != NULL) {
|
||||
@@ -820,20 +823,19 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
if (addr)
|
||||
if(addr)
|
||||
free(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
switch(sa->sa_family)
|
||||
{
|
||||
switch(sa->sa_family) {
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
|
||||
break;
|
||||
case AF_INET6:
|
||||
Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
|
||||
break;
|
||||
default:
|
||||
Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
|
||||
break;
|
||||
}
|
||||
host = hbuf; /* use this host name */
|
||||
}
|
||||
@@ -841,7 +843,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
/* resolv ip/host to ip */
|
||||
rc = Curl_resolv(conn, host, 0, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_wait_for_resolv(conn, &h);
|
||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||
if(h) {
|
||||
res = h->addr;
|
||||
/* when we return from this function, we can forget about this entry
|
||||
@@ -851,10 +853,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
else
|
||||
res = NULL; /* failure! */
|
||||
|
||||
if (addr)
|
||||
if(addr)
|
||||
free(addr);
|
||||
|
||||
if (res == NULL) {
|
||||
if(res == NULL) {
|
||||
failf(data, "Curl_resolv failed, we can not recover!");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -863,7 +865,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
|
||||
portsock = CURL_SOCKET_BAD;
|
||||
error = 0;
|
||||
for (ai = res; ai; ai = ai->ai_next) {
|
||||
for(ai = res; ai; ai = ai->ai_next) {
|
||||
/*
|
||||
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
|
||||
*/
|
||||
@@ -887,8 +889,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
||||
sslen = ai->ai_addrlen;
|
||||
|
||||
for( port = port_min; port <= port_max; ) {
|
||||
if( sa->sa_family == AF_INET )
|
||||
for(port = port_min; port <= port_max;) {
|
||||
if(sa->sa_family == AF_INET)
|
||||
sa4->sin_port = htons(port);
|
||||
#ifdef ENABLE_IPV6
|
||||
else
|
||||
@@ -910,7 +912,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
sclose(portsock);
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
port = port_min;
|
||||
@@ -919,7 +921,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
else if(error != EADDRINUSE && error != EACCES) {
|
||||
failf(data, "bind(port=%hu) failed: %s", port,
|
||||
Curl_strerror(conn, error) );
|
||||
sclose(portsock);
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -930,9 +932,9 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* maybe all ports were in use already*/
|
||||
if (port > port_max) {
|
||||
if(port > port_max) {
|
||||
failf(data, "bind() failed, we ran out of ports!");
|
||||
sclose(portsock);
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -942,7 +944,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
sclose(portsock);
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -950,7 +952,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
|
||||
if(listen(portsock, 1)) {
|
||||
failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
|
||||
sclose(portsock);
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -967,7 +969,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
conn->bits.ftp_use_eprt = TRUE;
|
||||
#endif
|
||||
|
||||
for (; fcmd != DONE; fcmd++) {
|
||||
for(; fcmd != DONE; fcmd++) {
|
||||
|
||||
if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
|
||||
/* if disabled, goto next */
|
||||
@@ -1036,7 +1038,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
the cleanup function will close it in case we fail before the true
|
||||
secondary stuff is made */
|
||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = portsock;
|
||||
|
||||
/* this tcpconnect assignment below is a hackish work-around to make the
|
||||
@@ -1557,10 +1559,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
newport = (unsigned short)(num & 0xffff);
|
||||
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||
proxy address not the ftp host */
|
||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||
@@ -1613,10 +1615,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
conn->ip_addr_str);
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||
proxy address not the ftp host */
|
||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||
@@ -1657,7 +1659,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||
case of failure */
|
||||
(void)Curl_wait_for_resolv(conn, &addr);
|
||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||
|
||||
connectport =
|
||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||
@@ -1673,7 +1675,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
rc = Curl_resolv(conn, newhost, newport, &addr);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING */
|
||||
(void)Curl_wait_for_resolv(conn, &addr);
|
||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||
|
||||
connectport = newport; /* we connect to the remote port */
|
||||
|
||||
@@ -1718,7 +1720,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
||||
|
||||
switch(data->set.proxytype) {
|
||||
switch(conn->proxytype) {
|
||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||
* FALSE */
|
||||
case CURLPROXY_SOCKS5:
|
||||
@@ -2115,7 +2117,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
/* BLOCKING */
|
||||
/* PORT means we are now awaiting the server to connect to us. */
|
||||
result = AllowServerConnect(conn);
|
||||
if( result )
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2163,7 +2165,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
/*
|
||||
A;
|
||||
150 Opening BINARY mode data connection for /etc/passwd (2241
|
||||
bytes). (ok, the file is being transfered)
|
||||
bytes). (ok, the file is being transferred)
|
||||
|
||||
B:
|
||||
150 Opening ASCII mode data connection for /bin/ls
|
||||
@@ -2172,7 +2174,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
|
||||
|
||||
D:
|
||||
150 Opening ASCII mode data connection for /linux/fisk/kpanelrc (0.0.0.0,0) (545 bytes).
|
||||
150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes)
|
||||
|
||||
E:
|
||||
125 Data connection already open; Transfer starting. */
|
||||
@@ -2195,7 +2197,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
/*
|
||||
* It seems directory listings either don't show the size or very
|
||||
* often uses size 0 anyway. ASCII transfers may very well turn out
|
||||
* that the transfered amount of data is not the same as this line
|
||||
* that the transferred amount of data is not the same as this line
|
||||
* tells, why using this number in those cases only confuses us.
|
||||
*
|
||||
* Example D above makes this parsing a little tricky */
|
||||
@@ -2229,7 +2231,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
if(data->set.ftp_use_port) {
|
||||
/* BLOCKING */
|
||||
result = AllowServerConnect(conn);
|
||||
if( result )
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2584,7 +2586,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if('\"' == *ptr) {
|
||||
/* it started good */
|
||||
ptr++;
|
||||
for (store = dir; *ptr;) {
|
||||
for(store = dir; *ptr;) {
|
||||
if('\"' == *ptr) {
|
||||
if('\"' == ptr[1]) {
|
||||
/* "quote-doubling" */
|
||||
@@ -2650,9 +2652,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
/* Reply format is like
|
||||
215<space><OS-name><space><commentary>
|
||||
*/
|
||||
while (*ptr == ' ')
|
||||
while(*ptr == ' ')
|
||||
ptr++;
|
||||
for (store = os; *ptr && *ptr != ' ';)
|
||||
for(store = os; *ptr && *ptr != ' ';)
|
||||
*store++ = *ptr++;
|
||||
*store = '\0'; /* zero terminate */
|
||||
ftpc->server_os = os;
|
||||
@@ -2693,7 +2695,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
case FTP_RETR_PREQUOTE:
|
||||
case FTP_STOR_PREQUOTE:
|
||||
if((ftpcode >= 400) && !ftpc->count2) {
|
||||
/* failure reponse code, and not allowed to fail */
|
||||
/* failure response code, and not allowed to fail */
|
||||
failf(conn->data, "QUOT command failed with %03d", ftpcode);
|
||||
return CURLE_QUOTE_ERROR;
|
||||
}
|
||||
@@ -2771,7 +2773,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
|
||||
case FTP_PRET:
|
||||
if(ftpcode != 200) {
|
||||
/* there only is this one standard OK return code. */
|
||||
/* there only is this one standard OK return code. */
|
||||
failf(data, "PRET command not accepted: %03d", ftpcode);
|
||||
return CURLE_FTP_PRET_FAILED;
|
||||
}
|
||||
@@ -2914,7 +2916,7 @@ static CURLcode ftp_connect(struct connectdata *conn,
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
/* We always support persistant connections on ftp */
|
||||
/* We always support persistent connections on ftp */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
pp->response_time = RESP_TIMEOUT; /* set default response time-out */
|
||||
@@ -2949,10 +2951,8 @@ static CURLcode ftp_connect(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_FTPS) {
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
/* BLOCKING */
|
||||
/* FTPS is simply ftp with SSL for the control channel */
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -3100,7 +3100,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
still requested to use SSL */
|
||||
}
|
||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
@@ -3110,7 +3110,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
/*
|
||||
* Let's see what the server says about the transfer we just performed,
|
||||
* but lower the timeout as sometimes this connection has died while the
|
||||
* data has been transfered. This happens when doing through NATs etc that
|
||||
* data has been transferred. This happens when doing through NATs etc that
|
||||
* abandon old silent connections.
|
||||
*/
|
||||
long old_time = pp->response_time;
|
||||
@@ -3512,7 +3512,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
}
|
||||
else {
|
||||
wildcard->pattern = strdup(last_slash);
|
||||
if (!wildcard->pattern)
|
||||
if(!wildcard->pattern)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
last_slash[0] = '\0'; /* cut file from path */
|
||||
}
|
||||
@@ -3520,7 +3520,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
else { /* there is only 'wildcard pattern' or nothing */
|
||||
if(path[0]) {
|
||||
wildcard->pattern = strdup(path);
|
||||
if (!wildcard->pattern)
|
||||
if(!wildcard->pattern)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
path[0] = '\0';
|
||||
}
|
||||
@@ -3562,7 +3562,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
|
||||
/* backup old write_function */
|
||||
ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
|
||||
/* parsing write function (callback included directly from ftplistparser.c) */
|
||||
/* parsing write function */
|
||||
conn->data->set.fwrite_func = Curl_ftp_parselist;
|
||||
/* backup old file descriptor */
|
||||
ftp_tmp->backup.file_descriptor = conn->data->set.out;
|
||||
@@ -3772,13 +3772,10 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
bytes_written=0;
|
||||
write_len = strlen(s);
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
res = Curl_convert_to_network(conn->data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(res != CURLE_OK) {
|
||||
if(res)
|
||||
return(res);
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
for(;;) {
|
||||
#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI)
|
||||
@@ -3985,7 +3982,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
/* 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
|
||||
CWD requires a parameter and a non-existent parameter a) doesn't
|
||||
work on many servers and b) has no effect on the others. */
|
||||
int len = (int)(slash_pos - cur_pos + absolute_dir);
|
||||
ftpc->dirs[ftpc->dirdepth] =
|
||||
@@ -4009,14 +4006,14 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||
if(++ftpc->dirdepth >= ftpc->diralloc) {
|
||||
/* enlarge array */
|
||||
char *bigger;
|
||||
char **bigger;
|
||||
ftpc->diralloc *= 2; /* double the size each time */
|
||||
bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
|
||||
if(!bigger) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
ftpc->dirs = (char **)bigger;
|
||||
ftpc->dirs = bigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4083,7 +4080,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
|
||||
if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
|
||||
/* Failure detected, close the second socket if it was created already */
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
return result;
|
||||
}
|
||||
|
10
lib/ftp.h
10
lib/ftp.h
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -66,7 +66,7 @@ typedef enum {
|
||||
FTP_STOR_TYPE, /* set type when about to STOR a file */
|
||||
FTP_SIZE, /* get the remote file's size for head-like request */
|
||||
FTP_RETR_SIZE, /* get the remote file's size for RETR */
|
||||
FTP_STOR_SIZE, /* get the size for (resumed) STOR */
|
||||
FTP_STOR_SIZE, /* get the size for STOR */
|
||||
FTP_REST, /* when used to check if the server supports it in head-like */
|
||||
FTP_RETR_REST, /* when asking for "resume" in for RETR */
|
||||
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
|
||||
@@ -93,7 +93,8 @@ struct ftp_wc_tmpdata {
|
||||
typedef enum {
|
||||
FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
|
||||
FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */
|
||||
FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the file */
|
||||
FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the
|
||||
file */
|
||||
} curl_ftpfile;
|
||||
|
||||
typedef enum {
|
||||
@@ -147,7 +148,8 @@ struct ftp_conn {
|
||||
ftpstate state; /* always use ftp.c:state() to change state! */
|
||||
char * server_os; /* The target server operating system. */
|
||||
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
||||
LIST parsing was done and wc_statemach set it */
|
||||
LIST parsing was done and wc_statemach set
|
||||
it */
|
||||
};
|
||||
|
||||
#endif /* HEADER_CURL_FTP_H */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -329,7 +329,8 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||
compare = Curl_fnmatch;
|
||||
|
||||
/* filter pattern-corresponding filenames */
|
||||
if(compare(conn->data->set.fnmatch_data, wc->pattern, finfo->filename) == 0) {
|
||||
if(compare(conn->data->set.fnmatch_data, wc->pattern,
|
||||
finfo->filename) == 0) {
|
||||
/* discard symlink which is containing multiple " -> " */
|
||||
if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
|
||||
(strstr(finfo->strings.target, " -> "))) {
|
||||
@@ -645,7 +646,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
parser->state.UNIX.main = PL_UNIX_TIME;
|
||||
parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
|
||||
}
|
||||
else if (!ISDIGIT(c)) {
|
||||
else if(!ISDIGIT(c)) {
|
||||
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||
return bufflen;
|
||||
}
|
||||
@@ -960,7 +961,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
}
|
||||
else {
|
||||
char *endptr;
|
||||
finfo->size = curlx_strtoofft(finfo->b_data + parser->item_offset,
|
||||
finfo->size = curlx_strtoofft(finfo->b_data +
|
||||
parser->item_offset,
|
||||
&endptr, 10);
|
||||
if(!*endptr) {
|
||||
if(finfo->size == CURL_OFF_T_MAX ||
|
||||
|
@@ -260,7 +260,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
*param_slistp = ptr.to_slist;
|
||||
break;
|
||||
case CURLINFO_CONDITION_UNMET:
|
||||
/* return if the condition prevented the document to get transfered */
|
||||
/* return if the condition prevented the document to get transferred */
|
||||
*param_longp = data->info.timecond;
|
||||
break;
|
||||
case CURLINFO_RTSP_SESSION_ID:
|
||||
|
11
lib/gopher.c
11
lib/gopher.c
@@ -112,6 +112,7 @@ const struct Curl_handler Curl_handler_gopher = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_GOPHER, /* defport */
|
||||
CURLPROTO_GOPHER, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -132,7 +133,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
/* Create selector. Degenerate cases: / and /1 => convert to "" */
|
||||
if (strlen(path) <= 2)
|
||||
if(strlen(path) <= 2)
|
||||
sel = (char *)"";
|
||||
else {
|
||||
char *newp;
|
||||
@@ -151,7 +152,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* ... and finally unescape */
|
||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||
if (!sel)
|
||||
if(!sel)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
sel_org = sel;
|
||||
}
|
||||
@@ -162,7 +163,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
for(;;) {
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
if (CURLE_OK == result) { /* Which may not have written it all! */
|
||||
if(CURLE_OK == result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result) {
|
||||
Curl_safefree(sel_org);
|
||||
@@ -170,7 +171,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
k -= amount;
|
||||
sel += amount;
|
||||
if (k < 1)
|
||||
if(k < 1)
|
||||
break; /* but it did write it all */
|
||||
}
|
||||
else {
|
||||
@@ -195,7 +196,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||
save allocing another string/doing another _write loop. */
|
||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||
if (result != CURLE_OK) {
|
||||
if(result != CURLE_OK) {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
return result;
|
||||
}
|
||||
|
59
lib/gtls.c
59
lib/gtls.c
@@ -197,14 +197,14 @@ static gnutls_datum load_file (const char *file)
|
||||
long filelen;
|
||||
void *ptr;
|
||||
|
||||
if (!(f = fopen(file, "r")))
|
||||
if(!(f = fopen(file, "r")))
|
||||
return loaded_file;
|
||||
if (fseek(f, 0, SEEK_END) != 0
|
||||
|| (filelen = ftell(f)) < 0
|
||||
|| fseek(f, 0, SEEK_SET) != 0
|
||||
|| !(ptr = malloc((size_t)filelen)))
|
||||
if(fseek(f, 0, SEEK_END) != 0
|
||||
|| (filelen = ftell(f)) < 0
|
||||
|| fseek(f, 0, SEEK_SET) != 0
|
||||
|| !(ptr = malloc((size_t)filelen)))
|
||||
goto out;
|
||||
if (fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
|
||||
if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
|
||||
free(ptr);
|
||||
goto out;
|
||||
}
|
||||
@@ -255,7 +255,8 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd,
|
||||
nonblocking?0:(int)timeout_ms?1000:timeout_ms);
|
||||
nonblocking?0:
|
||||
timeout_ms?timeout_ms:1000);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
@@ -282,7 +283,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
if(nonblocking)
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if (rc < 0) {
|
||||
else if(rc < 0) {
|
||||
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@@ -357,7 +358,8 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].srp_client_cred,
|
||||
rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
|
||||
srp_client_cred,
|
||||
data->set.ssl.username,
|
||||
data->set.ssl.password);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
@@ -412,13 +414,13 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* convenient assign */
|
||||
session = conn->ssl[sockindex].session;
|
||||
|
||||
if ((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
|
||||
if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||
#endif
|
||||
sni &&
|
||||
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
|
||||
strlen(conn->host.name)) < 0))
|
||||
sni &&
|
||||
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
|
||||
strlen(conn->host.name)) < 0))
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
|
||||
@@ -442,12 +444,13 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
if( gnutls_certificate_set_x509_key_file(
|
||||
conn->ssl[sockindex].cred,
|
||||
data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY] ?
|
||||
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
||||
do_file_type(data->set.str[STRING_CERT_TYPE]) ) != GNUTLS_E_SUCCESS) {
|
||||
if(gnutls_certificate_set_x509_key_file(
|
||||
conn->ssl[sockindex].cred,
|
||||
data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY] ?
|
||||
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
||||
do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
|
||||
GNUTLS_E_SUCCESS) {
|
||||
failf(data, "error reading X.509 key or certificate file");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@@ -458,10 +461,10 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
||||
conn->ssl[sockindex].srp_client_cred);
|
||||
if (rc != GNUTLS_E_SUCCESS) {
|
||||
if(rc != GNUTLS_E_SUCCESS)
|
||||
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
#endif
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||
conn->ssl[sockindex].cred);
|
||||
@@ -586,13 +589,13 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
gnutls_x509_crt_t format */
|
||||
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
|
||||
|
||||
if (data->set.ssl.issuercert) {
|
||||
if(data->set.ssl.issuercert) {
|
||||
gnutls_x509_crt_init(&x509_issuer);
|
||||
issuerp = load_file(data->set.ssl.issuercert);
|
||||
gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
|
||||
rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
|
||||
unload_file(issuerp);
|
||||
if (rc <= 0) {
|
||||
if(rc <= 0) {
|
||||
failf(data, "server certificate issuer check failed (IssuerCert: %s)",
|
||||
data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
|
||||
return CURLE_SSL_ISSUER_ERROR;
|
||||
@@ -743,7 +746,7 @@ after_server_cert_verification:
|
||||
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
|
||||
|
||||
incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
|
||||
if (incache) {
|
||||
if(incache) {
|
||||
/* there was one before in the cache, so instead of risking that the
|
||||
previous one was rejected, we just kill that and store the new */
|
||||
Curl_ssl_delsessionid(conn, ssl_sessionid);
|
||||
@@ -869,7 +872,7 @@ static void close_one(struct connectdata *conn,
|
||||
conn->ssl[idx].cred = NULL;
|
||||
}
|
||||
#ifdef USE_TLS_SRP
|
||||
if (conn->ssl[idx].srp_client_cred) {
|
||||
if(conn->ssl[idx].srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
|
||||
conn->ssl[idx].srp_client_cred = NULL;
|
||||
}
|
||||
@@ -904,7 +907,7 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
if(conn->ssl[sockindex].session) {
|
||||
while(!done) {
|
||||
int what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server */
|
||||
|
29
lib/hash.c
29
lib/hash.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -72,7 +72,7 @@ Curl_hash_init(struct curl_hash *h,
|
||||
|
||||
h->table = malloc(slots * sizeof(struct curl_llist *));
|
||||
if(h->table) {
|
||||
for (i = 0; i < slots; ++i) {
|
||||
for(i = 0; i < slots; ++i) {
|
||||
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
||||
if(!h->table[i]) {
|
||||
while(i--)
|
||||
@@ -140,7 +140,10 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
|
||||
#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)]
|
||||
|
||||
/* Insert the data in the hash. If there already was a match in the hash,
|
||||
that data is replaced. */
|
||||
* that data is replaced.
|
||||
*
|
||||
* @unittest: 1305
|
||||
*/
|
||||
void *
|
||||
Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
|
||||
{
|
||||
@@ -148,7 +151,7 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
|
||||
struct curl_llist_element *le;
|
||||
struct curl_llist *l = FETCH_LIST (h, key, key_len);
|
||||
|
||||
for (le = l->head; le; le = le->next) {
|
||||
for(le = l->head; le; le = le->next) {
|
||||
he = (struct curl_hash_element *) le->ptr;
|
||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||
Curl_llist_remove(l, le, (void *)h);
|
||||
@@ -183,7 +186,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
|
||||
struct curl_hash_element *he;
|
||||
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
||||
|
||||
for (le = l->head; le; le = le->next) {
|
||||
for(le = l->head; le; le = le->next) {
|
||||
he = le->ptr;
|
||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||
Curl_llist_remove(l, le, (void *) h);
|
||||
@@ -200,7 +203,7 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
|
||||
struct curl_hash_element *he;
|
||||
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
||||
|
||||
for (le = l->head; le; le = le->next) {
|
||||
for(le = l->head; le; le = le->next) {
|
||||
he = le->ptr;
|
||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||
return he->ptr;
|
||||
@@ -218,10 +221,10 @@ Curl_hash_apply(curl_hash *h, void *user,
|
||||
struct curl_llist_element *le;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
for (le = (h->table[i])->head;
|
||||
le;
|
||||
le = le->next) {
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
for(le = (h->table[i])->head;
|
||||
le;
|
||||
le = le->next) {
|
||||
curl_hash_element *el = le->ptr;
|
||||
cb(user, el->ptr);
|
||||
}
|
||||
@@ -234,7 +237,7 @@ Curl_hash_clean(struct curl_hash *h)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
Curl_llist_destroy(h->table[i], (void *) h);
|
||||
h->table[i] = NULL;
|
||||
}
|
||||
@@ -251,7 +254,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
struct curl_llist *list;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < h->slots; ++i) {
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
list = h->table[i];
|
||||
le = list->head; /* get first list entry */
|
||||
while(le) {
|
||||
@@ -319,7 +322,7 @@ void Curl_hash_print(struct curl_hash *h,
|
||||
|
||||
fprintf(stderr, "=Hash dump=\n");
|
||||
|
||||
for (i = 0; i < h->slots; i++) {
|
||||
for(i = 0; i < h->slots; i++) {
|
||||
list = h->table[i];
|
||||
le = list->head; /* get first list entry */
|
||||
if(le) {
|
||||
|
12
lib/hmac.c
12
lib/hmac.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -59,7 +59,8 @@ Curl_HMAC_init(const HMAC_params * hashparams,
|
||||
unsigned char b;
|
||||
|
||||
/* Create HMAC context. */
|
||||
i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize + hashparams->hmac_resultlen;
|
||||
i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
|
||||
hashparams->hmac_resultlen;
|
||||
ctxt = malloc(i);
|
||||
|
||||
if(!ctxt)
|
||||
@@ -84,14 +85,14 @@ Curl_HMAC_init(const HMAC_params * hashparams,
|
||||
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
|
||||
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
|
||||
|
||||
for (i = 0; i < keylen; i++) {
|
||||
for(i = 0; i < keylen; i++) {
|
||||
b = (unsigned char)(*key ^ hmac_ipad);
|
||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
|
||||
b = (unsigned char)(*key++ ^ hmac_opad);
|
||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
|
||||
}
|
||||
|
||||
for (; i < hashparams->hmac_maxkeylen; i++) {
|
||||
for(; i < hashparams->hmac_maxkeylen; i++) {
|
||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
|
||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
|
||||
}
|
||||
@@ -114,7 +115,8 @@ int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result)
|
||||
{
|
||||
const HMAC_params * hashparams = ctxt->hmac_hash;
|
||||
|
||||
/* Do not get result if called with a null parameter: only release storage. */
|
||||
/* Do not get result if called with a null parameter: only release
|
||||
storage. */
|
||||
|
||||
if(!result)
|
||||
result = (unsigned char *) ctxt->hmac_hashctxt2 +
|
||||
|
114
lib/hostasyn.c
114
lib/hostasyn.c
@@ -72,20 +72,6 @@
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_ASYNCH
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_async_cancel(struct connectdata *conn)
|
||||
{
|
||||
/* If we have a "half" response already received, we first clear that off
|
||||
so that nothing is tempted to use it */
|
||||
if(conn->async.temp_ai) {
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
|
||||
* or getaddrinfo_thread() when we got the name resolved (or not!).
|
||||
@@ -109,24 +95,6 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
if(ai) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
Curl_addrinfo *ai_tail = ai;
|
||||
|
||||
while (ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = conn->async.temp_ai;
|
||||
conn->async.temp_ai = ai;
|
||||
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
|
||||
/* make sure the temp pointer is cleared and isn't pointing to something
|
||||
we take care of below */
|
||||
conn->async.temp_ai = NULL;
|
||||
#endif
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
@@ -143,52 +111,9 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
else {
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
if(--conn->async.num_pending > 0) {
|
||||
/* We are not done yet. Clean up and return.
|
||||
This function will be called again. */
|
||||
if(conn->async.temp_ai) {
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
else
|
||||
{
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
|
||||
if(conn->async.temp_ai) {
|
||||
/* We are done, and while this latest request
|
||||
failed, some previous results exist. */
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = Curl_cache_addr(data, conn->async.temp_ai,
|
||||
conn->async.hostname,
|
||||
conn->async.port);
|
||||
if(!dns) {
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
/* make sure the temp pointer is cleared and isn't pointing to
|
||||
something we've taken care of already */
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn->async.dns = dns;
|
||||
|
||||
@@ -202,4 +127,43 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Call this function after Curl_connect() has returned async=TRUE and
|
||||
then a successful name resolve has been received.
|
||||
|
||||
Note: this function disconnects and frees the conn data in case of
|
||||
resolve failure */
|
||||
CURLcode Curl_async_resolved(struct connectdata *conn,
|
||||
bool *protocol_done)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
if(conn->async.dns) {
|
||||
conn->dns_entry = conn->async.dns;
|
||||
conn->async.dns = NULL;
|
||||
}
|
||||
|
||||
code = Curl_setup_conn(conn, protocol_done);
|
||||
|
||||
if(code)
|
||||
/* We're not allowed to return failure with memory left allocated
|
||||
in the connectdata struct, free those here */
|
||||
Curl_disconnect(conn, FALSE); /* close the connection */
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() is the generic low-level name resolve API within this
|
||||
* source file. There are several versions of this function - for different
|
||||
* name resolve layers (selected at build-time). They all take this same set
|
||||
* of arguments
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
|
||||
}
|
||||
|
||||
#endif /* CURLRES_ASYNCH */
|
||||
|
22
lib/hostip.c
22
lib/hostip.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -110,11 +110,13 @@
|
||||
* hostip.c - method-independent resolver functions and utility functions
|
||||
* hostasyn.c - functions for asynchronous name resolves
|
||||
* hostsyn.c - functions for synchronous name resolves
|
||||
* hostares.c - functions for ares-using name resolves
|
||||
* hostthre.c - functions for threaded name resolves
|
||||
* hostip4.c - ipv4-specific functions
|
||||
* hostip6.c - ipv6-specific functions
|
||||
*
|
||||
* The two asynchronous name resolver backends are implemented in:
|
||||
* asyn-ares.c - functions for ares-using name resolves
|
||||
* asyn-thread.c - functions for threaded name resolves
|
||||
|
||||
* The hostip.h is the united header file for all this. It defines the
|
||||
* CURLRES_* defines based on the config*.h and setup.h defines.
|
||||
*/
|
||||
@@ -288,7 +290,7 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
{
|
||||
struct hostcache_prune_data user;
|
||||
|
||||
if( !dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
|
||||
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
|
||||
/* cache forever means never prune, and NULL hostcache means
|
||||
we can't do it */
|
||||
return 0;
|
||||
@@ -296,7 +298,7 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
time(&user.now);
|
||||
user.cache_timeout = data->set.dns_cache_timeout;
|
||||
|
||||
if( !hostcache_timestamp_remove(&user,dns) )
|
||||
if(!hostcache_timestamp_remove(&user,dns) )
|
||||
return 0;
|
||||
|
||||
Curl_hash_clean_with_criterium(data->dns.hostcache,
|
||||
@@ -426,7 +428,7 @@ int Curl_resolv(struct connectdata *conn,
|
||||
free(entry_id);
|
||||
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
if( remove_entry_if_stale(data, dns) )
|
||||
if(remove_entry_if_stale(data, dns))
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
|
||||
if(dns) {
|
||||
@@ -464,7 +466,7 @@ int Curl_resolv(struct connectdata *conn,
|
||||
/* the response to our resolve call will come asynchronously at
|
||||
a later time, good or bad */
|
||||
/* First, check that we haven't received the info by now */
|
||||
result = Curl_is_resolved(conn, &dns);
|
||||
result = Curl_resolver_is_resolved(conn, &dns);
|
||||
if(result) /* error detected */
|
||||
return CURLRESOLV_ERROR;
|
||||
if(dns)
|
||||
@@ -559,7 +561,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
*entry = NULL;
|
||||
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
if (data->set.no_signal)
|
||||
if(data->set.no_signal)
|
||||
/* Ignore the timeout when signals are disabled */
|
||||
timeout = 0;
|
||||
else
|
||||
@@ -689,7 +691,7 @@ void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
dns->inuse--;
|
||||
/* only free if nobody is using AND it is not in hostcache (timestamp ==
|
||||
0) */
|
||||
if (dns->inuse == 0 && dns->timestamp == 0) {
|
||||
if(dns->inuse == 0 && dns->timestamp == 0) {
|
||||
Curl_freeaddrinfo(dns->addr);
|
||||
free(dns);
|
||||
}
|
||||
@@ -707,7 +709,7 @@ static void freednsentry(void *freethis)
|
||||
|
||||
/* mark the entry as not in hostcache */
|
||||
p->timestamp = 0;
|
||||
if (p->inuse == 0) {
|
||||
if(p->inuse == 0) {
|
||||
Curl_freeaddrinfo(p->addr);
|
||||
free(p);
|
||||
}
|
||||
|
56
lib/hostip.h
56
lib/hostip.h
@@ -25,6 +25,7 @@
|
||||
#include "setup.h"
|
||||
#include "hash.h"
|
||||
#include "curl_addrinfo.h"
|
||||
#include "asyn.h"
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
@@ -35,14 +36,6 @@
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Comfortable CURLRES_* definitions are included from setup.h
|
||||
*/
|
||||
|
||||
#ifdef USE_ARES
|
||||
#include <ares_version.h>
|
||||
#endif
|
||||
|
||||
/* Allocate enough memory to hold the full name information structs and
|
||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||
* required for storing all possible aliases and IP numbers is according to
|
||||
@@ -53,29 +46,13 @@
|
||||
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
||||
many seconds for a name resolve */
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
#define CURL_ASYNC_SUCCESS ARES_SUCCESS
|
||||
#if ARES_VERSION >= 0x010500
|
||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
||||
#endif
|
||||
#else
|
||||
#define CURL_ASYNC_SUCCESS CURLE_OK
|
||||
#define ares_cancel(x) do {} while(0)
|
||||
#define ares_destroy(x) do {} while(0)
|
||||
#endif
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
struct connectdata;
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
void Curl_async_cancel(struct connectdata *conn);
|
||||
#else
|
||||
#define Curl_async_cancel(x) do {} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
|
||||
* Global DNS cache is general badness. Do not use. This will be removed in
|
||||
@@ -128,6 +105,7 @@ bool Curl_ipv6works(void);
|
||||
*/
|
||||
bool Curl_ipvalid(struct connectdata *conn);
|
||||
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() is the generic low-level name resolve API within this
|
||||
* source file. There are several versions of this function - for different
|
||||
@@ -139,20 +117,6 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns);
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
|
||||
/* Curl_resolv_getsock() is a generic function that exists in multiple
|
||||
versions depending on what name resolve technology we've built to use. The
|
||||
function is called from the multi_getsock() function. 'sock' is a pointer
|
||||
to an array to hold the file descriptors, with 'numsock' being the size of
|
||||
that array (in number of entries). This function is supposed to return
|
||||
bitmask indicating what file descriptors (referring to array indexes in the
|
||||
'sock' array) to wait for, read/write. */
|
||||
int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock,
|
||||
int numsocks);
|
||||
|
||||
/* unlock a previously resolved dns entry */
|
||||
void Curl_resolv_unlock(struct SessionHandle *data,
|
||||
@@ -182,11 +146,18 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
||||
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
||||
Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
|
||||
|
||||
CURLcode Curl_async_resolved(struct connectdata *conn,
|
||||
bool *protocol_connect);
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
#define Curl_async_resolved(x,y) CURLE_OK
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_addrinfo_callback() is used when we build with any asynch specialty.
|
||||
* Handles end of async request processing. Inserts ai into hostcache when
|
||||
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
||||
* request completed wether successfull or failed.
|
||||
* request completed whether successful or failed.
|
||||
*/
|
||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
int status,
|
||||
@@ -209,13 +180,6 @@ struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
||||
const char *hostname, int port);
|
||||
|
||||
/*
|
||||
* Curl_destroy_thread_data() cleans up async resolver data.
|
||||
* Complementary of ares_destroy.
|
||||
*/
|
||||
struct Curl_async; /* forward-declaration */
|
||||
void Curl_destroy_thread_data(struct Curl_async *async);
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define CURL_INADDR_NONE (in_addr_t) ~0
|
||||
#else
|
||||
|
@@ -87,6 +87,7 @@ bool Curl_ipvalid(struct connectdata *conn)
|
||||
}
|
||||
|
||||
#ifdef CURLRES_SYNCH
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - the ipv4 synchronous version.
|
||||
*
|
||||
|
@@ -78,7 +78,7 @@
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
|
||||
/* These are strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't wanna include in memdebug.c
|
||||
* require a bunch of structs I didn't want to include in memdebug.c
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -125,7 +125,7 @@ bool Curl_ipv6works(void)
|
||||
ipv6_works = 0;
|
||||
else {
|
||||
ipv6_works = 1;
|
||||
sclose(s);
|
||||
Curl_closesocket(NULL, s);
|
||||
}
|
||||
}
|
||||
return (ipv6_works>0)?TRUE:FALSE;
|
||||
@@ -148,7 +148,7 @@ bool Curl_ipvalid(struct connectdata *conn)
|
||||
static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
{
|
||||
printf("dump_addrinfo:\n");
|
||||
for ( ; ai; ai = ai->ai_next) {
|
||||
for(; ai; ai = ai->ai_next) {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
printf(" fam %2d, CNAME %s, ",
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -72,52 +72,5 @@
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_SYNCH
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() for synch-builds. Curl_resolv() can never return
|
||||
* wait==TRUE, so this function will never be called. If it still gets called,
|
||||
* we return failure at once.
|
||||
*
|
||||
* We provide this function only to allow multi.c to remain unaware if we are
|
||||
* doing asynch resolves or not.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
(void)conn;
|
||||
*entry=NULL;
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will never be called when synch-built. If it still gets
|
||||
* called, we return failure at once.
|
||||
*
|
||||
* We provide this function only to allow multi.c to remain unaware if we are
|
||||
* doing asynch resolves or not.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
(void)conn;
|
||||
*dns = NULL;
|
||||
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
/*
|
||||
* We just return OK, this function is never actually used for synch builds.
|
||||
* It is present here to keep #ifdefs out from multi.c
|
||||
*/
|
||||
|
||||
int Curl_resolv_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock,
|
||||
int numsocks)
|
||||
{
|
||||
(void)conn;
|
||||
(void)sock;
|
||||
(void)numsocks;
|
||||
|
||||
return 0; /* no bits since we don't use any socks */
|
||||
}
|
||||
|
||||
#endif /* truly sync */
|
||||
|
230
lib/http.c
230
lib/http.c
@@ -76,7 +76,6 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "formdata.h"
|
||||
#include "progress.h"
|
||||
#include "curl_base64.h"
|
||||
@@ -97,9 +96,9 @@
|
||||
#include "multiif.h"
|
||||
#include "rawstr.h"
|
||||
#include "content_encoding.h"
|
||||
#include "rtsp.h"
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -114,6 +113,8 @@
|
||||
static int http_getsock_do(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static int http_should_fail(struct connectdata *conn);
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
@@ -139,6 +140,7 @@ const struct Curl_handler Curl_handler_http = {
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -161,6 +163,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTPS, /* defport */
|
||||
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
@@ -192,7 +195,7 @@ char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||
* case of allocation failure. Returns an empty string if the header value
|
||||
* consists entirely of whitespace.
|
||||
*/
|
||||
char *Curl_copy_header_value(const char *h)
|
||||
static char *copy_header_value(const char *h)
|
||||
{
|
||||
const char *start;
|
||||
const char *end;
|
||||
@@ -202,10 +205,10 @@ char *Curl_copy_header_value(const char *h)
|
||||
DEBUGASSERT(h);
|
||||
|
||||
/* Find the end of the header name */
|
||||
while (*h && (*h != ':'))
|
||||
while(*h && (*h != ':'))
|
||||
++h;
|
||||
|
||||
if (*h)
|
||||
if(*h)
|
||||
/* Skip over colon */
|
||||
++h;
|
||||
|
||||
@@ -338,17 +341,16 @@ static bool pickoneauth(struct auth *pick)
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
CURLcode Curl_http_perhapsrewind(struct connectdata *conn)
|
||||
static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct HTTP *http = data->state.proto.http;
|
||||
curl_off_t bytessent;
|
||||
curl_off_t expectsend = -1; /* default is unknown */
|
||||
|
||||
if(!http || !(conn->handler->protocol & CURLPROTO_HTTP))
|
||||
/* If this is still NULL, we have not reach very far and we can
|
||||
safely skip this rewinding stuff, or this is attempted to get used
|
||||
when HTTP isn't activated */
|
||||
if(!http)
|
||||
/* If this is still NULL, we have not reach very far and we can safely
|
||||
skip this rewinding stuff */
|
||||
return CURLE_OK;
|
||||
|
||||
switch(data->set.httpreq) {
|
||||
@@ -475,7 +477,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||
(data->set.httpreq != HTTPREQ_HEAD) &&
|
||||
!conn->bits.rewindaftersend) {
|
||||
code = Curl_http_perhapsrewind(conn);
|
||||
code = http_perhapsrewind(conn);
|
||||
if(code)
|
||||
return code;
|
||||
}
|
||||
@@ -496,7 +498,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
data->state.authhost.done = TRUE;
|
||||
}
|
||||
}
|
||||
if(Curl_http_should_fail(conn)) {
|
||||
if(http_should_fail(conn)) {
|
||||
failf (data, "The requested URL returned error: %d",
|
||||
data->req.httpcode);
|
||||
code = CURLE_HTTP_RETURNED_ERROR;
|
||||
@@ -819,7 +821,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/**
|
||||
* Curl_http_should_fail() determines whether an HTTP response has gotten us
|
||||
* http_should_fail() determines whether an HTTP response has gotten us
|
||||
* into an error state or not.
|
||||
*
|
||||
* @param conn all information about the current connection
|
||||
@@ -828,7 +830,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
*
|
||||
* @retval 1 communications should not continue
|
||||
*/
|
||||
int Curl_http_should_fail(struct connectdata *conn)
|
||||
static int http_should_fail(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data;
|
||||
int httpcode;
|
||||
@@ -886,16 +888,6 @@ int Curl_http_should_fail(struct connectdata *conn)
|
||||
** the client needs to reauthenticate. Once that info is
|
||||
** available, use it here.
|
||||
*/
|
||||
#if 0 /* set to 1 when debugging this functionality */
|
||||
infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage);
|
||||
infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant);
|
||||
infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail);
|
||||
infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode);
|
||||
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
|
||||
infof(data,"%s: newurl = %s\n",__FUNCTION__,data->req.newurl ?
|
||||
data->req.newurl : "(null)");
|
||||
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Either we're not authenticating, or we're supposed to
|
||||
@@ -1014,19 +1006,17 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
|
||||
DEBUGASSERT(size > included_body_bytes);
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
res = Curl_convert_to_network(conn->data, ptr, headersize);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(res != CURLE_OK) {
|
||||
if(res) {
|
||||
/* conversion failed, free memory and return to the caller */
|
||||
if(in->buffer)
|
||||
free(in->buffer);
|
||||
free(in);
|
||||
return res;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_HTTPS) {
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
/* 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
|
||||
@@ -1305,7 +1295,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_HTTPS) {
|
||||
if(conn->given->flags & PROTOPT_SSL) {
|
||||
/* perform SSL initialization */
|
||||
if(data->state.used_interface == Curl_if_multi) {
|
||||
result = https_connecting(conn, done);
|
||||
@@ -1344,7 +1334,7 @@ static int http_getsock_do(struct connectdata *conn,
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
DEBUGASSERT((conn) && (conn->handler->protocol & CURLPROTO_HTTPS));
|
||||
DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
|
||||
|
||||
/* perform SSL initialization for this socket */
|
||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
|
||||
@@ -1362,7 +1352,7 @@ static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(conn->handler->protocol & CURLPROTO_HTTPS) {
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||
|
||||
if(!numsocks)
|
||||
@@ -1487,7 +1477,7 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
100-continue to the headers which actually speeds up post operations
|
||||
(as there is one packet coming back from the web server) */
|
||||
ptr = Curl_checkheaders(data, "Expect:");
|
||||
if (ptr) {
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
}
|
||||
@@ -1533,6 +1523,11 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
we will force length zero then */
|
||||
checkprefix("Content-Length", headers->data))
|
||||
;
|
||||
else if(conn->allocptr.te &&
|
||||
/* when asking for Transfer-Encoding, don't pass on a custom
|
||||
Connection: */
|
||||
checkprefix("Connection", headers->data))
|
||||
;
|
||||
else {
|
||||
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
|
||||
headers->data);
|
||||
@@ -1654,8 +1649,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if( (conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
||||
data->set.upload) {
|
||||
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
||||
data->set.upload) {
|
||||
httpreq = HTTPREQ_PUT;
|
||||
}
|
||||
|
||||
@@ -1728,6 +1723,29 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
/* we only consider transfer-encoding magic if libz support is built-in */
|
||||
|
||||
if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
|
||||
/* When we are to insert a TE: header in the request, we must also insert
|
||||
TE in a Connection: header, so we need to merge the custom provided
|
||||
Connection: header and prevent the original to get sent. Note that if
|
||||
the user has inserted his/hers own TE: header we don't do this magic
|
||||
but then assume that the user will handle it all! */
|
||||
char *cptr = Curl_checkheaders(data, "Connection:");
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(conn->allocptr.te);
|
||||
|
||||
/* Create the (updated) Connection: header */
|
||||
conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
|
||||
strdup("Connection: TE\r\n" TE_HEADER);
|
||||
|
||||
if(!conn->allocptr.te)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = Curl_checkheaders(data, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
@@ -1770,15 +1788,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
custom Host: header if this is NOT a redirect, as setting Host: in the
|
||||
redirected request is being out on thin ice. Except if the host name
|
||||
is the same as the first one! */
|
||||
char *cookiehost = Curl_copy_header_value(ptr);
|
||||
if (!cookiehost)
|
||||
char *cookiehost = copy_header_value(ptr);
|
||||
if(!cookiehost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if (!*cookiehost)
|
||||
if(!*cookiehost)
|
||||
/* ignore empty data */
|
||||
free(cookiehost);
|
||||
else {
|
||||
char *colon = strchr(cookiehost, ':');
|
||||
if (colon)
|
||||
if(colon)
|
||||
*colon = 0; /* The host must not include an embedded port number */
|
||||
Curl_safefree(conn->allocptr.cookiehost);
|
||||
conn->allocptr.cookiehost = cookiehost;
|
||||
@@ -1856,7 +1874,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
ppath = data->change.url;
|
||||
if(checkprefix("ftp://", ppath)) {
|
||||
if (data->set.proxy_transfer_mode) {
|
||||
if(data->set.proxy_transfer_mode) {
|
||||
/* when doing ftp, append ;type=<a|i> if not present */
|
||||
char *type = strstr(ppath, ";type=");
|
||||
if(type && type[6] && type[7] == 0) {
|
||||
@@ -1873,14 +1891,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
char *p = ftp_typecode;
|
||||
/* avoid sending invalid URLs like ftp://example.com;type=i if the
|
||||
* user specified ftp://example.com without the slash */
|
||||
if (!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
|
||||
if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
|
||||
*p++ = '/';
|
||||
}
|
||||
snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
|
||||
data->set.prefer_ascii ? 'a' : 'i');
|
||||
}
|
||||
}
|
||||
if (conn->bits.user_passwd && !conn->bits.userpwd_in_url)
|
||||
if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
|
||||
paste_ftp_userpwd = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -2036,17 +2054,17 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* add the main request stuff */
|
||||
/* GET/HEAD/POST/PUT */
|
||||
result = Curl_add_bufferf(req_buffer, "%s ", request);
|
||||
if (result)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* url */
|
||||
if (paste_ftp_userpwd)
|
||||
if(paste_ftp_userpwd)
|
||||
result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
|
||||
conn->user, conn->passwd,
|
||||
ppath + sizeof("ftp://") - 1);
|
||||
else
|
||||
result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
|
||||
if (result)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
@@ -2058,6 +2076,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
"%s" /* user agent */
|
||||
"%s" /* host */
|
||||
"%s" /* accept */
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
"%s" /* Proxy-Connection */
|
||||
@@ -2075,6 +2094,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->allocptr.uagent:"",
|
||||
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
|
||||
http->p_accept?http->p_accept:"",
|
||||
conn->allocptr.te?conn->allocptr.te:"",
|
||||
(data->set.str[STRING_ENCODING] &&
|
||||
*data->set.str[STRING_ENCODING] &&
|
||||
conn->allocptr.accept_encoding)?
|
||||
@@ -2262,14 +2282,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
Curl_formclean(&http->sendit); /* free that whole lot */
|
||||
return result;
|
||||
}
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* time to convert the form data... */
|
||||
result = Curl_formconvert(data, http->sendit);
|
||||
|
||||
/* convert the form data */
|
||||
result = Curl_convert_form(data, http->sendit);
|
||||
if(result) {
|
||||
Curl_formclean(&http->sendit); /* free that whole lot */
|
||||
return result;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
break;
|
||||
|
||||
case HTTPREQ_PUT: /* Let's PUT the data to the server! */
|
||||
@@ -2508,13 +2528,13 @@ checkhttpprefix(struct SessionHandle *data,
|
||||
/* convert from the network encoding using a scratch area */
|
||||
char *scratch = strdup(s);
|
||||
if(NULL == scratch) {
|
||||
failf (data, "Failed to allocate memory for conversion!");
|
||||
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
|
||||
failf (data, "Failed to allocate memory for conversion!");
|
||||
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
|
||||
}
|
||||
if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
free(scratch);
|
||||
return FALSE; /* can't return CURLE_foobar so return FALSE */
|
||||
free(scratch);
|
||||
return FALSE; /* can't return CURLE_foobar so return FALSE */
|
||||
}
|
||||
s = scratch;
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
@@ -2527,9 +2547,8 @@ checkhttpprefix(struct SessionHandle *data,
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
if((rc != TRUE) && (checkprefix("HTTP/", s))) {
|
||||
if((rc != TRUE) && (checkprefix("HTTP/", s)))
|
||||
rc = TRUE;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
free(scratch);
|
||||
@@ -2775,7 +2794,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
*/
|
||||
if(Curl_http_should_fail(conn)) {
|
||||
if(http_should_fail(conn)) {
|
||||
failf (data, "The requested URL returned error: %d",
|
||||
k->httpcode);
|
||||
return CURLE_HTTP_RETURNED_ERROR;
|
||||
@@ -2901,10 +2920,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
res = Curl_convert_from_network(data,
|
||||
&scratch[0],
|
||||
SCRATCHSIZE);
|
||||
if(CURLE_OK != res) {
|
||||
if(res)
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
#define HEADER1 k->p /* no conversion needed, just use k->p */
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
@@ -2957,8 +2975,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
data->info.httpcode = k->httpcode;
|
||||
|
||||
data->info.httpversion = conn->httpversion;
|
||||
if (!data->state.httpversion ||
|
||||
data->state.httpversion > conn->httpversion)
|
||||
if(!data->state.httpversion ||
|
||||
data->state.httpversion > conn->httpversion)
|
||||
/* store the lowest server version we encounter */
|
||||
data->state.httpversion = conn->httpversion;
|
||||
|
||||
@@ -3035,14 +3053,10 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, k->p, strlen(k->p));
|
||||
if(CURLE_OK != result) {
|
||||
return(result);
|
||||
}
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Check for Content-Length: header lines to get size */
|
||||
if(!k->ignorecl && !data->set.ignorecl &&
|
||||
@@ -3072,10 +3086,10 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
/* check for Content-Type: header lines to get the MIME-type */
|
||||
else if(checkprefix("Content-Type:", k->p)) {
|
||||
char *contenttype = Curl_copy_header_value(k->p);
|
||||
if (!contenttype)
|
||||
char *contenttype = copy_header_value(k->p);
|
||||
if(!contenttype)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if (!*contenttype)
|
||||
if(!*contenttype)
|
||||
/* ignore empty data */
|
||||
free(contenttype);
|
||||
else {
|
||||
@@ -3127,8 +3141,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
*/
|
||||
conn->bits.close = TRUE; /* close when done */
|
||||
}
|
||||
else if(Curl_compareheader(k->p, "Transfer-Encoding:", "chunked") &&
|
||||
!(conn->handler->protocol & CURLPROTO_RTSP)) {
|
||||
else if(checkprefix("Transfer-Encoding:", k->p)) {
|
||||
/* One or more encodings. We check for chunked and/or a compression
|
||||
algorithm. */
|
||||
/*
|
||||
* [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
|
||||
* means that the server will send a series of "chunks". Each
|
||||
@@ -3137,10 +3152,60 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
* with the previously mentioned size. There can be any amount
|
||||
* of chunks, and a chunk-data set to zero signals the
|
||||
* end-of-chunks. */
|
||||
k->chunk = TRUE; /* chunks coming our way */
|
||||
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
char *start;
|
||||
|
||||
/* Find the first non-space letter */
|
||||
start = k->p + 18;
|
||||
|
||||
for(;;) {
|
||||
/* skip whitespaces and commas */
|
||||
while(*start && (ISSPACE(*start) || (*start == ',')))
|
||||
start++;
|
||||
|
||||
if(checkprefix("chunked", start)) {
|
||||
k->chunk = TRUE; /* chunks coming our way */
|
||||
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
|
||||
start += 7;
|
||||
}
|
||||
|
||||
if(k->auto_decoding)
|
||||
/* TODO: we only support the first mentioned compression for now */
|
||||
break;
|
||||
|
||||
if(checkprefix("identity", start)) {
|
||||
k->auto_decoding = IDENTITY;
|
||||
start += 8;
|
||||
}
|
||||
else if(checkprefix("deflate", start)) {
|
||||
k->auto_decoding = DEFLATE;
|
||||
start += 7;
|
||||
}
|
||||
else if(checkprefix("gzip", start)) {
|
||||
k->auto_decoding = GZIP;
|
||||
start += 4;
|
||||
}
|
||||
else if(checkprefix("x-gzip", start)) {
|
||||
k->auto_decoding = GZIP;
|
||||
start += 6;
|
||||
}
|
||||
else if(checkprefix("compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 8;
|
||||
}
|
||||
else if(checkprefix("x-compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 10;
|
||||
}
|
||||
else
|
||||
/* unknown! */
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(checkprefix("Content-Encoding:", k->p) &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
@@ -3160,15 +3225,15 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
|
||||
/* Record the content-encoding for later use */
|
||||
if(checkprefix("identity", start))
|
||||
k->content_encoding = IDENTITY;
|
||||
k->auto_decoding = IDENTITY;
|
||||
else if(checkprefix("deflate", start))
|
||||
k->content_encoding = DEFLATE;
|
||||
k->auto_decoding = DEFLATE;
|
||||
else if(checkprefix("gzip", start)
|
||||
|| checkprefix("x-gzip", start))
|
||||
k->content_encoding = GZIP;
|
||||
k->auto_decoding = GZIP;
|
||||
else if(checkprefix("compress", start)
|
||||
|| checkprefix("x-compress", start))
|
||||
k->content_encoding = COMPRESS;
|
||||
k->auto_decoding = COMPRESS;
|
||||
}
|
||||
else if(checkprefix("Content-Range:", k->p)) {
|
||||
/* Content-Range: bytes [num]-
|
||||
@@ -3227,10 +3292,10 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
checkprefix("Location:", k->p) &&
|
||||
!data->req.location) {
|
||||
/* this is the URL that the server advises us to use instead */
|
||||
char *location = Curl_copy_header_value(k->p);
|
||||
if (!location)
|
||||
char *location = copy_header_value(k->p);
|
||||
if(!location)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if (!*location)
|
||||
if(!*location)
|
||||
/* ignore empty data */
|
||||
free(location);
|
||||
else {
|
||||
@@ -3244,19 +3309,18 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
|
||||
/* some cases of POST and PUT etc needs to rewind the data
|
||||
stream at this point */
|
||||
result = Curl_http_perhapsrewind(conn);
|
||||
result = http_perhapsrewind(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
else if(conn->handler->protocol & CURLPROTO_RTSP) {
|
||||
result = Curl_rtsp_parseheader(conn, k->p);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* End of header-checks. Write them to the client.
|
||||
*/
|
||||
|
@@ -36,9 +36,6 @@ bool Curl_compareheader(const char *headerline, /* line to check */
|
||||
|
||||
char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader);
|
||||
|
||||
char *Curl_copy_header_value(const char *h);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*
|
||||
* The add_buffer series of functions are used to build one large memory chunk
|
||||
@@ -83,8 +80,6 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||
CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
|
||||
|
||||
int Curl_http_should_fail(struct connectdata *conn);
|
||||
|
||||
/* If only the PICKNONE bit is set, there has been a round-trip and we
|
||||
selected to use no auth at all. Ie, we actively select no auth, as opposed
|
||||
to not having one selected. The other CURLAUTH_* defines are present in the
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "content_encoding.h"
|
||||
#include "http.h"
|
||||
#include "curl_memory.h"
|
||||
#include "easyif.h" /* for Curl_convert_to_network prototype */
|
||||
#include "non-ascii.h" /* for Curl_convert_to_network prototype */
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -153,17 +153,16 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
}
|
||||
/* length and datap are unmodified */
|
||||
ch->hexbuffer[ch->hexindex]=0;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
/* convert to host encoding before calling strtoul */
|
||||
result = Curl_convert_from_network(conn->data,
|
||||
ch->hexbuffer,
|
||||
result = Curl_convert_from_network(conn->data, ch->hexbuffer,
|
||||
ch->hexindex);
|
||||
if(result != CURLE_OK) {
|
||||
if(result) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* Treat it as a bad hex character */
|
||||
return(CHUNKE_ILLEGAL_HEX);
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
|
||||
ch->state = CHUNK_POSTHEX;
|
||||
}
|
||||
@@ -209,11 +208,11 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
/* Write the data portion available */
|
||||
#ifdef HAVE_LIBZ
|
||||
switch (conn->data->set.http_ce_skip?
|
||||
IDENTITY : data->req.content_encoding) {
|
||||
IDENTITY : data->req.auto_decoding) {
|
||||
case IDENTITY:
|
||||
#endif
|
||||
if(!k->ignorebody) {
|
||||
if( !data->set.http_te_skip )
|
||||
if(!data->set.http_te_skip)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
|
||||
piece);
|
||||
else
|
||||
@@ -297,17 +296,14 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
conn->trailer[conn->trlPos++]=0x0a;
|
||||
conn->trailer[conn->trlPos]=0;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Convert to host encoding before calling Curl_client_write */
|
||||
result = Curl_convert_from_network(conn->data,
|
||||
conn->trailer,
|
||||
result = Curl_convert_from_network(conn->data, conn->trailer,
|
||||
conn->trlPos);
|
||||
if(result != CURLE_OK)
|
||||
if(result)
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* Treat it as a bad chunk */
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
if(!data->set.http_te_skip) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
conn->trailer, conn->trlPos);
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "strtok.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "curl_memory.h"
|
||||
#include "easyif.h" /* included for Curl_convert_... prototypes */
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -49,6 +49,8 @@
|
||||
#define MAX_VALUE_LENGTH 256
|
||||
#define MAX_CONTENT_LENGTH 1024
|
||||
|
||||
static void digest_cleanup_one(struct digestdata *dig);
|
||||
|
||||
/*
|
||||
* Return 0 on success and then the buffers are filled in fine.
|
||||
*
|
||||
@@ -88,8 +90,8 @@ static int get_pair(const char *str, char *value, char *content,
|
||||
break;
|
||||
case ',':
|
||||
if(!starts_with_quote) {
|
||||
/* this signals the end of the content if we didn't get a starting quote
|
||||
and then we do "sloppy" parsing */
|
||||
/* this signals the end of the content if we didn't get a starting
|
||||
quote and then we do "sloppy" parsing */
|
||||
c=0; /* the end */
|
||||
continue;
|
||||
}
|
||||
@@ -156,7 +158,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
before = TRUE;
|
||||
|
||||
/* clear off any former leftovers and init to defaults */
|
||||
Curl_digest_cleanup_one(d);
|
||||
digest_cleanup_one(d);
|
||||
|
||||
for(;;) {
|
||||
char value[MAX_VALUE_LENGTH];
|
||||
@@ -294,7 +296,6 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct digestdata *d;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
CURLcode rc;
|
||||
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
|
||||
It converts digest text to ASCII so the MD5 will be correct for
|
||||
@@ -306,9 +307,6 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
free(b); \
|
||||
return rc; \
|
||||
}
|
||||
#else
|
||||
#define CURL_OUTPUT_DIGEST_CONV(a, b)
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(proxy) {
|
||||
d = &data->state.proxydigest;
|
||||
@@ -543,7 +541,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_digest_cleanup_one(struct digestdata *d)
|
||||
static void digest_cleanup_one(struct digestdata *d)
|
||||
{
|
||||
if(d->nonce)
|
||||
free(d->nonce);
|
||||
@@ -577,8 +575,8 @@ void Curl_digest_cleanup_one(struct digestdata *d)
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
{
|
||||
Curl_digest_cleanup_one(&data->state.digest);
|
||||
Curl_digest_cleanup_one(&data->state.proxydigest);
|
||||
digest_cleanup_one(&data->state.digest);
|
||||
digest_cleanup_one(&data->state.proxydigest);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -46,7 +46,6 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
bool proxy,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath);
|
||||
void Curl_digest_cleanup_one(struct digestdata *dig);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -100,7 +100,8 @@ get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
|
||||
}
|
||||
|
||||
static void
|
||||
log_gss_error(struct connectdata *conn, OM_uint32 error_status, const char *prefix)
|
||||
log_gss_error(struct connectdata *conn, OM_uint32 error_status,
|
||||
const char *prefix)
|
||||
{
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
@@ -167,7 +168,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
|
||||
if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
|
||||
/* We finished succesfully our part of authentication, but server
|
||||
/* We finished successfully 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);
|
||||
@@ -192,47 +193,47 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", header)) {
|
||||
ASN1_OBJECT * object = NULL;
|
||||
int rc = 1;
|
||||
unsigned char * spnegoToken = NULL;
|
||||
size_t spnegoTokenLength = 0;
|
||||
unsigned char * mechToken = NULL;
|
||||
size_t mechTokenLength = 0;
|
||||
ASN1_OBJECT * object = NULL;
|
||||
int rc = 1;
|
||||
unsigned char * spnegoToken = NULL;
|
||||
size_t spnegoTokenLength = 0;
|
||||
unsigned char * mechToken = NULL;
|
||||
size_t mechTokenLength = 0;
|
||||
|
||||
if(input_token.value == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
spnegoToken = malloc(input_token.length);
|
||||
if(spnegoToken == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
spnegoTokenLength = input_token.length;
|
||||
|
||||
object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
|
||||
if(!parseSpnegoTargetToken(spnegoToken,
|
||||
spnegoTokenLength,
|
||||
NULL,
|
||||
NULL,
|
||||
&mechToken,
|
||||
&mechTokenLength,
|
||||
NULL,
|
||||
NULL)) {
|
||||
free(spnegoToken);
|
||||
spnegoToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token failed\n");
|
||||
}
|
||||
else {
|
||||
free(input_token.value);
|
||||
input_token.value = malloc(mechTokenLength);
|
||||
if(input_token.value == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
spnegoToken = malloc(input_token.length);
|
||||
if(spnegoToken == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
spnegoTokenLength = input_token.length;
|
||||
|
||||
object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
|
||||
if(!parseSpnegoTargetToken(spnegoToken,
|
||||
spnegoTokenLength,
|
||||
NULL,
|
||||
NULL,
|
||||
&mechToken,
|
||||
&mechTokenLength,
|
||||
NULL,
|
||||
NULL)) {
|
||||
free(spnegoToken);
|
||||
spnegoToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token failed\n");
|
||||
}
|
||||
else {
|
||||
free(input_token.value);
|
||||
input_token.value = malloc(mechTokenLength);
|
||||
if (input_token.value == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(input_token.value, mechToken,mechTokenLength);
|
||||
input_token.length = mechTokenLength;
|
||||
free(mechToken);
|
||||
mechToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
|
||||
}
|
||||
memcpy(input_token.value, mechToken,mechTokenLength);
|
||||
input_token.length = mechTokenLength;
|
||||
free(mechToken);
|
||||
mechToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -242,7 +243,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
&neg_ctx->context,
|
||||
neg_ctx->server_name,
|
||||
GSS_C_NO_OID,
|
||||
GSS_C_DELEG_FLAG,
|
||||
0,
|
||||
0,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
@@ -289,7 +290,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
size_t responseTokenLength = 0;
|
||||
|
||||
responseToken = malloc(neg_ctx->output_token.length);
|
||||
if( responseToken == NULL)
|
||||
if(responseToken == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(responseToken, neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length);
|
||||
|
@@ -122,7 +122,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
|
||||
if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
|
||||
/* We finished succesfully our part of authentication, but server
|
||||
/* We finished successfully 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);
|
||||
@@ -133,17 +133,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
(ret = get_gss_name(conn, proxy, neg_ctx->server_name)))
|
||||
return ret;
|
||||
|
||||
if (!neg_ctx->max_token_length) {
|
||||
if(!neg_ctx->output_token) {
|
||||
PSecPkgInfo SecurityPackage;
|
||||
ret = s_pSecFn->QuerySecurityPackageInfo((SEC_CHAR *)"Negotiate",
|
||||
&SecurityPackage);
|
||||
if (ret != SEC_E_OK)
|
||||
if(ret != SEC_E_OK)
|
||||
return -1;
|
||||
|
||||
/* Allocate input and output buffers according to the max token size
|
||||
as indicated by the security package */
|
||||
neg_ctx->max_token_length = SecurityPackage->cbMaxToken;
|
||||
neg_ctx->output_token = (BYTE *)malloc(neg_ctx->max_token_length);
|
||||
neg_ctx->output_token = malloc(neg_ctx->max_token_length);
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
}
|
||||
|
||||
@@ -153,25 +153,14 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
if(len > 0) {
|
||||
input_token = malloc(neg_ctx->max_token_length);
|
||||
if(!input_token)
|
||||
return -1;
|
||||
|
||||
input_token_len = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token);
|
||||
if(input_token_len == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( !input_token ) {
|
||||
/* first call in a new negotation, we have to require credentials,
|
||||
if(!len) {
|
||||
/* first call in a new negotation, we have to acquire credentials,
|
||||
and allocate memory for the context */
|
||||
|
||||
neg_ctx->credentials = (CredHandle *)malloc(sizeof(CredHandle));
|
||||
neg_ctx->context = (CtxtHandle *)malloc(sizeof(CtxtHandle));
|
||||
neg_ctx->credentials = malloc(sizeof(CredHandle));
|
||||
neg_ctx->context = malloc(sizeof(CtxtHandle));
|
||||
|
||||
if ( !neg_ctx->credentials || !neg_ctx->context)
|
||||
if(!neg_ctx->credentials || !neg_ctx->context)
|
||||
return -1;
|
||||
|
||||
neg_ctx->status =
|
||||
@@ -179,7 +168,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
||||
NULL, NULL, neg_ctx->credentials,
|
||||
&lifetime);
|
||||
if ( neg_ctx->status != SEC_E_OK )
|
||||
if(neg_ctx->status != SEC_E_OK)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
input_token = malloc(neg_ctx->max_token_length);
|
||||
if(!input_token)
|
||||
return -1;
|
||||
|
||||
input_token_len = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token);
|
||||
if(input_token_len == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -193,7 +192,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
||||
|
||||
|
||||
if (input_token) {
|
||||
if(input_token) {
|
||||
in_buff_desc.ulVersion = 0;
|
||||
in_buff_desc.cBuffers = 1;
|
||||
in_buff_desc.pBuffers = &out_sec_buff;
|
||||
@@ -217,14 +216,14 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
&context_attributes,
|
||||
&lifetime);
|
||||
|
||||
if ( GSS_ERROR(neg_ctx->status) )
|
||||
if(GSS_ERROR(neg_ctx->status))
|
||||
return -1;
|
||||
|
||||
if ( neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
|
||||
neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE ) {
|
||||
if(neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
|
||||
neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE) {
|
||||
neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
|
||||
&out_buff_desc);
|
||||
if ( GSS_ERROR(neg_ctx->status) )
|
||||
if(GSS_ERROR(neg_ctx->status))
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -280,6 +279,8 @@ static void cleanup(struct negotiatedata *neg_ctx)
|
||||
free(neg_ctx->output_token);
|
||||
neg_ctx->output_token = 0;
|
||||
}
|
||||
|
||||
neg_ctx->max_token_length = 0;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
|
164
lib/http_ntlm.c
164
lib/http_ntlm.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -25,10 +25,6 @@
|
||||
|
||||
http://davenport.sourceforge.net/ntlm.html
|
||||
http://www.innovation.ch/java/ntlm.html
|
||||
|
||||
Another implementation:
|
||||
http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsNTLMAuthModule.cpp
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
@@ -52,7 +48,7 @@
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "non-ascii.h" /* for Curl_convert_... prototypes */
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_base64.h"
|
||||
@@ -87,6 +83,10 @@
|
||||
# include <rand.h>
|
||||
# endif
|
||||
|
||||
#ifndef OPENSSL_VERSION_NUMBER
|
||||
#error "OPENSSL_VERSION_NUMBER not defined"
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||
#define DES_key_schedule des_key_schedule
|
||||
#define DES_cblock des_cblock
|
||||
@@ -137,7 +137,7 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef USE_NTRESPONSES
|
||||
#ifndef USE_NTRESPONSES
|
||||
/* Define this to make the type-3 message include the NT response message */
|
||||
#define USE_NTRESPONSES 1
|
||||
|
||||
@@ -516,6 +516,7 @@ static void mk_lm_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
CURLcode res;
|
||||
unsigned char pw[14];
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
@@ -525,16 +526,13 @@ static void mk_lm_hash(struct SessionHandle *data,
|
||||
Curl_strntoupper((char *)pw, password, len);
|
||||
memset(&pw[len], 0, 14-len);
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* The LanManager hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
*/
|
||||
if(data)
|
||||
Curl_convert_to_network(data, (char *)pw, 14);
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
res = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(res)
|
||||
return;
|
||||
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
@@ -575,7 +573,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
size_t srclen)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0; i<srclen; i++) {
|
||||
for(i=0; i<srclen; i++) {
|
||||
dest[2*i] = (unsigned char)src[i];
|
||||
dest[2*i+1] = '\0';
|
||||
}
|
||||
@@ -590,21 +588,19 @@ static CURLcode mk_nt_hash(struct SessionHandle *data,
|
||||
{
|
||||
size_t len = strlen(password);
|
||||
unsigned char *pw = malloc(len*2);
|
||||
CURLcode result;
|
||||
if(!pw)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ascii_to_unicode_le(pw, password, len);
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* The NT hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
* The NT hashed password needs to be created using the password in the
|
||||
* network encoding not the host encoding.
|
||||
*/
|
||||
if(data)
|
||||
Curl_convert_to_network(data, (char *)pw, len*2);
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
result = Curl_convert_to_network(data, (char *)pw, len*2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create NT hashed password. */
|
||||
@@ -664,6 +660,20 @@ ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
||||
|
||||
#define HOSTNAME_MAX 1024
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
/* copy the source to the destination and fill in zeroes in every
|
||||
other destination byte! */
|
||||
static void unicodecpy(unsigned char *dest,
|
||||
const char *src, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<length; i++) {
|
||||
dest[2*i] = (unsigned char)src[i];
|
||||
dest[2*i+1] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy)
|
||||
@@ -724,10 +734,10 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
passwdp="";
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if (s_hSecDll == NULL) {
|
||||
if(s_hSecDll == NULL) {
|
||||
/* not thread safe and leaks - use curl_global_init() to avoid */
|
||||
CURLcode err = Curl_sspi_global_init();
|
||||
if (s_hSecDll == NULL)
|
||||
if(s_hSecDll == NULL)
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@@ -881,25 +891,26 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||
NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
print_flags(stderr,
|
||||
NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
fprintf(stderr, "\n****\n");
|
||||
});
|
||||
fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
|
||||
"0x%08.8x ",
|
||||
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||
NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
print_flags(stderr,
|
||||
NTLMFLAG_NEGOTIATE_OEM|
|
||||
NTLMFLAG_REQUEST_TARGET|
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||
NTLM2FLAG|
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
fprintf(stderr, "\n****\n");
|
||||
});
|
||||
|
||||
/* now size is the size of the base64 encoded package size */
|
||||
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
|
||||
@@ -955,14 +966,17 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
type_3.pvBuffer = ntlmbuf;
|
||||
type_3.cbBuffer = sizeof(ntlmbuf);
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, &ntlm->c_handle,
|
||||
(char *) host,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP, &type_2_desc,
|
||||
0, &ntlm->c_handle, &type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
|
||||
&ntlm->c_handle,
|
||||
(char *) host,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
&type_2_desc,
|
||||
0, &ntlm->c_handle,
|
||||
&type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -978,9 +992,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
int ntrespoff;
|
||||
unsigned char ntresp[24]; /* fixed-size */
|
||||
#endif
|
||||
bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE)?TRUE:FALSE;
|
||||
size_t useroff;
|
||||
const char *user;
|
||||
size_t userlen;
|
||||
CURLcode res;
|
||||
|
||||
user = strchr(userp, '\\');
|
||||
if(!user)
|
||||
@@ -1010,6 +1026,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
hostlen = strlen(host);
|
||||
}
|
||||
|
||||
if(unicode) {
|
||||
domlen = domlen * 2;
|
||||
userlen = userlen * 2;
|
||||
hostlen = hostlen * 2;
|
||||
}
|
||||
|
||||
#if USE_NTLM2SESSION
|
||||
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||
@@ -1069,7 +1091,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
unsigned char ntbuffer[0x18];
|
||||
@@ -1099,13 +1121,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
useroff = domoff + domlen;
|
||||
hostoff = useroff + userlen;
|
||||
|
||||
/*
|
||||
* In the case the server sets the flag NTLMFLAG_NEGOTIATE_UNICODE, we
|
||||
* need to filter it off because libcurl doesn't UNICODE encode the
|
||||
* strings it packs into the NTLM authenticate packet.
|
||||
*/
|
||||
ntlm->flags &= ~NTLMFLAG_NEGOTIATE_UNICODE;
|
||||
|
||||
/* Create the big type-3 message binary blob */
|
||||
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
||||
NTLMSSP_SIGNATURE "%c"
|
||||
@@ -1211,14 +1226,14 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
}
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "\n ntresp=");
|
||||
fprintf(stderr, "\n ntresp=");
|
||||
print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||
fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||
LONGQUARTET(ntlm->flags), ntlm->flags);
|
||||
print_flags(stderr, ntlm->flags);
|
||||
fprintf(stderr, "\n****\n");
|
||||
@@ -1233,25 +1248,34 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
}
|
||||
|
||||
DEBUGASSERT(size == domoff);
|
||||
memcpy(&ntlmbuf[size], domain, domlen);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], domain, domlen/2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], domain, domlen);
|
||||
|
||||
size += domlen;
|
||||
|
||||
DEBUGASSERT(size == useroff);
|
||||
memcpy(&ntlmbuf[size], user, userlen);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], user, userlen/2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], user, userlen);
|
||||
|
||||
size += userlen;
|
||||
|
||||
DEBUGASSERT(size == hostoff);
|
||||
memcpy(&ntlmbuf[size], host, hostlen);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], host, hostlen/2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], host, hostlen);
|
||||
|
||||
size += hostlen;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert domain, user, and host to ASCII but leave the rest as-is */
|
||||
if(CURLE_OK != Curl_convert_to_network(conn->data,
|
||||
(char *)&ntlmbuf[domoff],
|
||||
size-domoff)) {
|
||||
res = Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff],
|
||||
size-domoff);
|
||||
if(res)
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -24,6 +24,9 @@
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "http_proxy.h"
|
||||
@@ -33,6 +36,8 @@
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -160,8 +165,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
if(CURLE_OK == result) {
|
||||
/* Now send off the request */
|
||||
result = Curl_add_buffer_send(req_buffer, conn,
|
||||
&data->info.request_size, 0, sockindex);
|
||||
result =
|
||||
Curl_add_buffer_send(req_buffer, conn,
|
||||
&data->info.request_size, 0, sockindex);
|
||||
}
|
||||
req_buffer = NULL;
|
||||
if(result)
|
||||
@@ -238,7 +244,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
/* loop every second at least, less if the timeout is near */
|
||||
switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
|
||||
check<1000L?(int)check:1000)) {
|
||||
check<1000L?check:1000)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Proxy CONNECT aborted due to select/poll error");
|
||||
@@ -315,14 +321,12 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
char letter;
|
||||
int writetype;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, line_start,
|
||||
perline);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
/* output debug if that is requested */
|
||||
if(data->set.verbose)
|
||||
@@ -479,7 +483,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
if(closeConnection && data->req.newurl) {
|
||||
/* Connection closed by server. Don't use it anymore */
|
||||
sclose(conn->sock[sockindex]);
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
break;
|
||||
}
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#ifndef HEADER_CURL_HTTP_PROXY_H
|
||||
#define HEADER_CURL_HTTP_PROXY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -31,3 +33,5 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
#else
|
||||
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -24,22 +24,28 @@
|
||||
* Pierre Joye <pierre@php.net>
|
||||
***************************************************************************/
|
||||
#if defined(WIN32) && defined(USE_WIN32_IDN)
|
||||
#include "windows.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef WANT_IDN_PROTOTYPES
|
||||
WINBASEAPI int WINAPI IdnToAscii(DWORD, LPCWSTR, int, LPWSTR, int);
|
||||
WINBASEAPI int WINAPI IdnToUnicode(DWORD, LPCWSTR, int, LPWSTR, int);
|
||||
#endif
|
||||
|
||||
#define IDN_MAX_LENGTH 255
|
||||
|
||||
static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
if (str_utf8) {
|
||||
if(str_utf8) {
|
||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||
str_utf8, -1, NULL, 0);
|
||||
if (str_w_len) {
|
||||
str_w = (wchar_t *) malloc(str_w_len * sizeof(wchar_t));
|
||||
if (str_w) {
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
if(str_w_len) {
|
||||
str_w = malloc(str_w_len * sizeof(wchar_t));
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
free(str_w);
|
||||
str_w = NULL;
|
||||
@@ -55,21 +61,23 @@ static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if (str_w) {
|
||||
if(str_w) {
|
||||
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
DWORD err = GetLastError();
|
||||
if (str_utf8_len) {
|
||||
str_utf8 = (char *) malloc(str_utf8_len * sizeof(wchar_t));
|
||||
if (str_w) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
if(str_utf8_len) {
|
||||
str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
DWORD err = GetLastError();
|
||||
(void) GetLastError();
|
||||
free((void *)str_utf8);
|
||||
str_utf8 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
(void) GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
return str_utf8;
|
||||
@@ -78,9 +86,9 @@ static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
|
||||
int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
{
|
||||
wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
|
||||
if (in_w) {
|
||||
if(in_w) {
|
||||
wchar_t punycode[IDN_MAX_LENGTH];
|
||||
if (IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
|
||||
if(IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
|
||||
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||
free(in_w);
|
||||
return 0;
|
||||
@@ -88,7 +96,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
free(in_w);
|
||||
|
||||
*out = (char *)_curl_win32_wchar_to_UTF8(punycode);
|
||||
if (!(*out)) {
|
||||
if(!(*out)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -97,16 +105,16 @@ int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
|
||||
int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
|
||||
{
|
||||
if (in) {
|
||||
if(in) {
|
||||
WCHAR unicode[IDN_MAX_LENGTH];
|
||||
|
||||
if (IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
|
||||
if(IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
|
||||
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
|
||||
if (!out_utf8) {
|
||||
if(!out_utf8) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
16
lib/if2ip.c
16
lib/if2ip.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -76,22 +76,22 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
|
||||
struct ifaddrs *iface, *head;
|
||||
char *ip=NULL;
|
||||
|
||||
if (getifaddrs(&head) >= 0) {
|
||||
for (iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||
if ((iface->ifa_addr != NULL) &&
|
||||
(iface->ifa_addr->sa_family == af) &&
|
||||
curl_strequal(iface->ifa_name, interface)) {
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
for(iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||
if((iface->ifa_addr != NULL) &&
|
||||
(iface->ifa_addr->sa_family == af) &&
|
||||
curl_strequal(iface->ifa_name, interface)) {
|
||||
void *addr;
|
||||
char scope[12]="";
|
||||
#ifdef ENABLE_IPV6
|
||||
if (af == AF_INET6) {
|
||||
if(af == AF_INET6) {
|
||||
unsigned int scopeid = 0;
|
||||
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
/* Include the scope of this interface as part of the address */
|
||||
scopeid = ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
|
||||
#endif
|
||||
if (scopeid)
|
||||
if(scopeid)
|
||||
snprintf(scope, sizeof(scope), "%%%u", scopeid);
|
||||
}
|
||||
else
|
||||
|
26
lib/imap.c
26
lib/imap.c
@@ -64,8 +64,6 @@
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
|
||||
#include "if2ip.h"
|
||||
#include "hostip.h"
|
||||
#include "progress.h"
|
||||
@@ -101,7 +99,7 @@ static CURLcode imap_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode imap_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode imap_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection);
|
||||
static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static int imap_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
@@ -128,9 +126,10 @@ const struct Curl_handler Curl_handler_imap = {
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAP, /* defport */
|
||||
CURLPROTO_IMAP, /* protocol */
|
||||
PROTOPT_CLOSEACTION /* flags */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
|
||||
};
|
||||
|
||||
|
||||
@@ -152,9 +151,10 @@ const struct Curl_handler Curl_handler_imaps = {
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAPS, /* defport */
|
||||
CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -176,6 +176,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -200,6 +201,7 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAPS, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -472,7 +474,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn,
|
||||
infof(data, "Filesize left: %" FORMAT_OFF_T "\n", filesize);
|
||||
|
||||
if(!filesize)
|
||||
/* the entire data is already transfered! */
|
||||
/* the entire data is already transferred! */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
else
|
||||
/* IMAP download */
|
||||
@@ -631,12 +633,10 @@ static CURLcode imap_multi_statemach(struct connectdata *conn,
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
CURLcode result;
|
||||
|
||||
if((conn->handler->protocol & CURLPROTO_IMAPS) && !imapc->ssldone) {
|
||||
if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone)
|
||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
|
||||
}
|
||||
else {
|
||||
else
|
||||
result = Curl_pp_multi_statemach(&imapc->pp);
|
||||
}
|
||||
|
||||
*done = (bool)(imapc->state == IMAP_STOP);
|
||||
|
||||
@@ -711,7 +711,7 @@ static CURLcode imap_connect(struct connectdata *conn,
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
/* We always support persistant connections on imap */
|
||||
/* We always support persistent connections on imap */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
pp->response_time = RESP_TIMEOUT; /* set default response time-out */
|
||||
@@ -746,11 +746,9 @@ static CURLcode imap_connect(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if((conn->handler->protocol & CURLPROTO_IMAPS) &&
|
||||
if((conn->handler->flags & PROTOPT_SSL) &&
|
||||
data->state.used_interface != Curl_if_multi) {
|
||||
/* BLOCKING */
|
||||
/* IMAPS is simply imap with SSL for the control channel */
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009 - 2011, 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
|
||||
@@ -33,7 +33,8 @@ typedef enum {
|
||||
a connect */
|
||||
IMAP_LOGIN,
|
||||
IMAP_STARTTLS,
|
||||
IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS (multi mode only) */
|
||||
IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
|
||||
(multi mode only) */
|
||||
IMAP_SELECT,
|
||||
IMAP_FETCH,
|
||||
IMAP_LOGOUT,
|
||||
@@ -48,7 +49,7 @@ struct imap_conn {
|
||||
imapstate state; /* always use imap.c:state() to change state! */
|
||||
int cmdid; /* id number/index */
|
||||
const char *idstr; /* pointer to a string for which to wait for as id */
|
||||
bool ssldone; /* is connect() over SSL done? only relevant in multi mode */
|
||||
bool ssldone; /* connect() over SSL? only relevant in multi mode */
|
||||
};
|
||||
|
||||
extern const struct Curl_handler Curl_handler_imap;
|
||||
|
@@ -69,8 +69,7 @@ static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
|
||||
len = strlen(tmp);
|
||||
if(len == 0 || len >= size)
|
||||
{
|
||||
if(len == 0 || len >= size) {
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -105,61 +104,51 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof(words));
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
for(i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
best.len = 0;
|
||||
cur.len = 0;
|
||||
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
if(words[i] == 0)
|
||||
{
|
||||
for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if(words[i] == 0) {
|
||||
if(cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
}
|
||||
else if(cur.base != -1)
|
||||
{
|
||||
else if(cur.base != -1) {
|
||||
if(best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||
best = cur;
|
||||
best = cur;
|
||||
if(best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/* Format the result.
|
||||
*/
|
||||
best.base = -1;
|
||||
/* Format the result. */
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's?
|
||||
*/
|
||||
if(best.base != -1 && i >= best.base && i < (best.base + best.len))
|
||||
{
|
||||
for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if(best.base != -1 && i >= best.base && i < (best.base + best.len)) {
|
||||
if(i == best.base)
|
||||
*tp++ = ':';
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are we following an initial run of 0x00s or any real hex?
|
||||
*/
|
||||
if(i != 0)
|
||||
*tp++ = ':';
|
||||
*tp++ = ':';
|
||||
|
||||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if(i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
{
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -177,8 +166,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
|
||||
|
||||
/* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if((size_t)(tp - tmp) > size)
|
||||
{
|
||||
if((size_t)(tp - tmp) > size) {
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -195,9 +183,9 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
|
||||
* error, EAFNOSUPPORT or ENOSPC.
|
||||
*
|
||||
* On Windows we store the error in the thread errno, not
|
||||
* in the winsock error code. This is to avoid loosing the
|
||||
* in the winsock error code. This is to avoid losing the
|
||||
* actual last winsock error. So use macro ERRNO to fetch the
|
||||
* errno this funtion sets when returning NULL, not SOCKERRNO.
|
||||
* errno this function sets when returning NULL, not SOCKERRNO.
|
||||
*/
|
||||
char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
|
||||
{
|
||||
|
@@ -61,9 +61,9 @@ static int inet_pton6(const char *src, unsigned char *dst);
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* notice:
|
||||
* On Windows we store the error in the thread errno, not
|
||||
* in the winsock error code. This is to avoid loosing the
|
||||
* in the winsock error code. This is to avoid losing the
|
||||
* actual last winsock error. So use macro ERRNO to fetch the
|
||||
* errno this funtion sets when returning (-1), not SOCKERRNO.
|
||||
* errno this function sets when returning (-1), not SOCKERRNO.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
@@ -223,7 +223,7 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
|
||||
if(tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
for(i = 1; i <= n; i++) {
|
||||
*(endp - i) = *(colonp + n - i);
|
||||
*(colonp + n - i) = 0;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* Copyright (c) 2004 - 2010 Daniel Stenberg
|
||||
* Copyright (c) 2004 - 2011 Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -88,9 +88,9 @@ strlcpy (char *dst, const char *src, size_t dst_sz)
|
||||
size_t n;
|
||||
char *p;
|
||||
|
||||
for (p = dst, n = 0;
|
||||
n + 1 < dst_sz && *src != '\0';
|
||||
++p, ++src, ++n)
|
||||
for(p = dst, n = 0;
|
||||
n + 1 < dst_sz && *src != '\0';
|
||||
++p, ++src, ++n)
|
||||
*p = *src;
|
||||
*p = '\0';
|
||||
if(*src == '\0')
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -47,7 +47,8 @@ extern struct Curl_sec_client_mech Curl_krb5_client_mech;
|
||||
#endif
|
||||
|
||||
CURLcode Curl_krb_kauth(struct connectdata *conn);
|
||||
int Curl_sec_read_msg (struct connectdata *conn, char *, enum protection_level);
|
||||
int Curl_sec_read_msg (struct connectdata *conn, char *,
|
||||
enum protection_level);
|
||||
void Curl_sec_end (struct connectdata *);
|
||||
CURLcode Curl_sec_login (struct connectdata *);
|
||||
int Curl_sec_request_prot (struct connectdata *conn, const char *level);
|
||||
|
@@ -157,7 +157,8 @@ krb5_encode(void *app_data, const void *from, int length, int level, void **to,
|
||||
if(maj != GSS_S_COMPLETE)
|
||||
return -1;
|
||||
|
||||
/* malloc a new buffer, in case gss_release_buffer doesn't work as expected */
|
||||
/* malloc a new buffer, in case gss_release_buffer doesn't work as
|
||||
expected */
|
||||
*to = malloc(enc.length);
|
||||
if(!*to)
|
||||
return -1;
|
||||
@@ -222,7 +223,8 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
if(maj != GSS_S_COMPLETE) {
|
||||
gss_release_name(&min, &gssname);
|
||||
if(service == srv_host) {
|
||||
Curl_failf(data, "Error importing service name %s", input_buffer.value);
|
||||
Curl_failf(data, "Error importing service name %s",
|
||||
input_buffer.value);
|
||||
return AUTH_ERROR;
|
||||
}
|
||||
service = srv_host;
|
||||
@@ -327,7 +329,7 @@ static void krb5_end(void *app_data)
|
||||
{
|
||||
OM_uint32 maj, min;
|
||||
gss_ctx_id_t *context = app_data;
|
||||
if (*context != GSS_C_NO_CONTEXT) {
|
||||
if(*context != GSS_C_NO_CONTEXT) {
|
||||
maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
|
||||
DEBUGASSERT(maj == GSS_S_COMPLETE);
|
||||
}
|
||||
|
79
lib/ldap.c
79
lib/ldap.c
@@ -46,7 +46,8 @@
|
||||
#ifdef CURL_LDAP_WIN /* Use Windows LDAP implementation. */
|
||||
# include <winldap.h>
|
||||
# ifndef LDAP_VENDOR_NAME
|
||||
# error Your Platform SDK is NOT sufficient for LDAP support! Update your Platform SDK, or disable LDAP support!
|
||||
# error Your Platform SDK is NOT sufficient for LDAP support! \
|
||||
Update your Platform SDK, or disable LDAP support!
|
||||
# else
|
||||
# include <winber.h>
|
||||
# endif
|
||||
@@ -139,6 +140,7 @@ const struct Curl_handler Curl_handler_ldap = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_LDAP, /* defport */
|
||||
CURLPROTO_LDAP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
@@ -162,6 +164,7 @@ const struct Curl_handler Curl_handler_ldaps = {
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_LDAPS, /* defport */
|
||||
CURLPROTO_LDAP | CURLPROTO_LDAPS, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
@@ -205,7 +208,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* Get the URL scheme ( either ldap or ldaps ) */
|
||||
if(conn->given->protocol & CURLPROTO_LDAPS)
|
||||
if(conn->given->flags & PROTOPT_SSL)
|
||||
ldap_ssl = 1;
|
||||
infof(data, "LDAP local: trying to establish %s connection\n",
|
||||
ldap_ssl ? "encrypted" : "cleartext");
|
||||
@@ -218,7 +221,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(ldap_ssl) {
|
||||
#ifdef HAVE_LDAP_SSL
|
||||
#ifdef CURL_LDAP_WIN
|
||||
/* Win32 LDAP SDK doesnt support insecure mode without CA! */
|
||||
/* Win32 LDAP SDK doesn't support insecure mode without CA! */
|
||||
server = ldap_sslinit(conn->host.name, (int)conn->port, 1);
|
||||
ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
|
||||
#else
|
||||
@@ -255,9 +258,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
ldap_option = LDAPSSL_VERIFY_SERVER;
|
||||
} else {
|
||||
ldap_option = LDAPSSL_VERIFY_NONE;
|
||||
}
|
||||
else
|
||||
ldap_option = LDAPSSL_VERIFY_NONE;
|
||||
rc = ldapssl_set_verify_mode(ldap_option);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: ERROR setting cert verify mode: %s",
|
||||
@@ -277,7 +280,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
||||
failf(data, "LDAP local: ERROR OpenLDAP does only support PEM cert-type!");
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
|
||||
status = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
@@ -295,9 +298,10 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
ldap_option = LDAP_OPT_X_TLS_DEMAND;
|
||||
} else {
|
||||
ldap_option = LDAP_OPT_X_TLS_NEVER;
|
||||
}
|
||||
else
|
||||
ldap_option = LDAP_OPT_X_TLS_NEVER;
|
||||
|
||||
rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: ERROR setting cert verify mode: %s",
|
||||
@@ -339,7 +343,8 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CURL_LDAP_USE_SSL */
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
server = ldap_init(conn->host.name, (int)conn->port);
|
||||
if(server == NULL) {
|
||||
failf(data, "LDAP local: Cannot connect to %s:%hu",
|
||||
@@ -363,9 +368,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
conn->bits.user_passwd ? conn->passwd : NULL);
|
||||
}
|
||||
if(rc != 0) {
|
||||
failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
|
||||
status = CURLE_LDAP_CANNOT_BIND;
|
||||
goto quit;
|
||||
failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
|
||||
status = CURLE_LDAP_CANNOT_BIND;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
|
||||
@@ -379,8 +384,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
|
||||
for(num = 0, entryIterator = ldap_first_entry(server, result);
|
||||
entryIterator;
|
||||
entryIterator = ldap_next_entry(server, entryIterator), num++)
|
||||
{
|
||||
entryIterator = ldap_next_entry(server, entryIterator), num++) {
|
||||
BerElement *ber = NULL;
|
||||
char *attribute; /*! suspicious that this isn't 'const' */
|
||||
char *dn = ldap_get_dn(server, entryIterator);
|
||||
@@ -392,16 +396,13 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
|
||||
dlsize += strlen(dn)+5;
|
||||
|
||||
for (attribute = ldap_first_attribute(server, entryIterator, &ber);
|
||||
attribute;
|
||||
attribute = ldap_next_attribute(server, entryIterator, ber))
|
||||
{
|
||||
for(attribute = ldap_first_attribute(server, entryIterator, &ber);
|
||||
attribute;
|
||||
attribute = ldap_next_attribute(server, entryIterator, ber)) {
|
||||
BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);
|
||||
|
||||
if(vals != NULL)
|
||||
{
|
||||
for (i = 0; (vals[i] != NULL); i++)
|
||||
{
|
||||
if(vals != NULL) {
|
||||
for(i = 0; (vals[i] != NULL); i++) {
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0);
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
||||
@@ -515,15 +516,15 @@ static char **split_str (char *str)
|
||||
char **res, *lasts, *s;
|
||||
int i;
|
||||
|
||||
for (i = 2, s = strchr(str,','); s; i++)
|
||||
s = strchr(++s,',');
|
||||
for(i = 2, s = strchr(str,','); s; i++)
|
||||
s = strchr(++s,',');
|
||||
|
||||
res = calloc(i, sizeof(char*));
|
||||
if(!res)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, s = strtok_r(str, ",", &lasts); s;
|
||||
s = strtok_r(NULL, ",", &lasts), i++)
|
||||
for(i = 0, s = strtok_r(str, ",", &lasts); s;
|
||||
s = strtok_r(NULL, ",", &lasts), i++)
|
||||
res[i] = s;
|
||||
return res;
|
||||
}
|
||||
@@ -541,16 +542,16 @@ static bool unescape_elements (void *data, LDAPURLDesc *ludp)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
|
||||
for(i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
|
||||
ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
|
||||
if(!ludp->lud_attrs[i])
|
||||
return (FALSE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
|
||||
for(i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
|
||||
ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
|
||||
if(!ludp->lud_exts[i])
|
||||
return (FALSE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if(ludp->lud_dn) {
|
||||
@@ -620,7 +621,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(!ludp->lud_attrs)
|
||||
return LDAP_NO_MEMORY;
|
||||
|
||||
for (i = 0; ludp->lud_attrs[i]; i++)
|
||||
for(i = 0; ludp->lud_attrs[i]; i++)
|
||||
LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i]));
|
||||
}
|
||||
|
||||
@@ -666,7 +667,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(!ludp->lud_exts)
|
||||
return LDAP_NO_MEMORY;
|
||||
|
||||
for (i = 0; ludp->lud_exts[i]; i++)
|
||||
for(i = 0; ludp->lud_exts[i]; i++)
|
||||
LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
|
||||
|
||||
success:
|
||||
@@ -699,23 +700,23 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp)
|
||||
int i;
|
||||
|
||||
if(!ludp)
|
||||
return;
|
||||
return;
|
||||
|
||||
if(ludp->lud_dn)
|
||||
free(ludp->lud_dn);
|
||||
free(ludp->lud_dn);
|
||||
|
||||
if(ludp->lud_filter)
|
||||
free(ludp->lud_filter);
|
||||
free(ludp->lud_filter);
|
||||
|
||||
if(ludp->lud_attrs) {
|
||||
for (i = 0; ludp->lud_attrs[i]; i++)
|
||||
free(ludp->lud_attrs[i]);
|
||||
for(i = 0; ludp->lud_attrs[i]; i++)
|
||||
free(ludp->lud_attrs[i]);
|
||||
free(ludp->lud_attrs);
|
||||
}
|
||||
|
||||
if(ludp->lud_exts) {
|
||||
for (i = 0; ludp->lud_exts[i]; i++)
|
||||
free(ludp->lud_exts[i]);
|
||||
for(i = 0; ludp->lud_exts[i]; i++)
|
||||
free(ludp->lud_exts[i]);
|
||||
free(ludp->lud_exts);
|
||||
}
|
||||
free (ludp);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user