Compare commits
176 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 |
@@ -62,8 +62,7 @@ CURL_HEADERS := \
|
|||||||
mprintf.h \
|
mprintf.h \
|
||||||
multi.h \
|
multi.h \
|
||||||
stdcheaders.h \
|
stdcheaders.h \
|
||||||
typecheck-gcc.h \
|
typecheck-gcc.h
|
||||||
types.h
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(addprefix lib/,$(CSOURCES))
|
LOCAL_SRC_FILES := $(addprefix lib/,$(CSOURCES))
|
||||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/
|
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_COPY_HEADERS := $(addprefix include/curl/,$(CURL_HEADERS))
|
||||||
|
|
||||||
LOCAL_MODULE:= libcurl
|
LOCAL_MODULE:= libcurl
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
# Copy the licence to a place where Android will find it.
|
# Copy the licence to a place where Android will find it.
|
||||||
# Actually, this doesn't quite work because the build system searches
|
# 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_SRC_FILES := $(addprefix src/,$(CURL_CFILES))
|
||||||
|
|
||||||
LOCAL_MODULE := curl
|
LOCAL_MODULE := curl
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
LOCAL_STATIC_LIBRARIES := libcurl
|
LOCAL_STATIC_LIBRARIES := libcurl
|
||||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ include(Utilities)
|
|||||||
|
|
||||||
project( CURL C )
|
project( CURL C )
|
||||||
|
|
||||||
|
|
||||||
file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
|
file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
|
||||||
string (REGEX MATCH "LIBCURL_VERSION_MAJOR[ \t]+([0-9]+)"
|
string (REGEX MATCH "LIBCURL_VERSION_MAJOR[ \t]+([0-9]+)"
|
||||||
LIBCURL_VERSION_MJ ${CURL_VERSION_H_CONTENTS})
|
LIBCURL_VERSION_MJ ${CURL_VERSION_H_CONTENTS})
|
||||||
@@ -191,12 +190,12 @@ if(WIN32)
|
|||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
# This macro checks if the symbol exists in the library and if it
|
# 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)
|
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})
|
${VARIABLE})
|
||||||
if(${VARIABLE})
|
if(${VARIABLE})
|
||||||
set(CURL_LIBS ${CURL_LIBS} ${LIBRARY})
|
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||||
endif(${VARIABLE})
|
endif(${VARIABLE})
|
||||||
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
|
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)
|
# CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ)
|
||||||
# ENDIF(NOT CURL_SPECIAL_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 for idn
|
||||||
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
|
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()
|
||||||
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
|
# If we have features.h, then do the _BSD_SOURCE magic
|
||||||
check_include_file("features.h" HAVE_FEATURES_H)
|
check_include_file("features.h" HAVE_FEATURES_H)
|
||||||
|
|
||||||
@@ -852,3 +851,14 @@ endif()
|
|||||||
if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
|
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")
|
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()
|
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
|
bin_SCRIPTS = curl-config
|
||||||
|
|
||||||
SUBDIRS = lib src
|
SUBDIRS = lib src include
|
||||||
DIST_SUBDIRS = $(SUBDIRS) tests include packages docs
|
DIST_SUBDIRS = $(SUBDIRS) tests packages docs
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = libcurl.pc
|
pkgconfig_DATA = libcurl.pc
|
||||||
@@ -155,3 +155,7 @@ ca-bundle: lib/mk-ca-bundle.pl
|
|||||||
ca-firefox: lib/firefox-db2pem.sh
|
ca-firefox: lib/firefox-db2pem.sh
|
||||||
@echo "generate a fresh ca-bundle.crt"
|
@echo "generate a fresh ca-bundle.crt"
|
||||||
./lib/firefox-db2pem.sh lib/ca-bundle.crt
|
./lib/firefox-db2pem.sh lib/ca-bundle.crt
|
||||||
|
|
||||||
|
checksrc:
|
||||||
|
cd lib && $(MAKE) checksrc
|
||||||
|
cd src && $(MAKE) checksrc
|
||||||
|
|||||||
@@ -1,22 +1,38 @@
|
|||||||
Curl and libcurl 7.21.6
|
Curl and libcurl 7.21.7
|
||||||
|
|
||||||
Public curl releases: 122
|
Public curl releases: 123
|
||||||
Command line options: 144
|
Command line options: 144
|
||||||
curl_easy_setopt() options: 186
|
curl_easy_setopt() options: 186
|
||||||
Public functions in libcurl: 58
|
Public functions in libcurl: 58
|
||||||
Known libcurl bindings: 39
|
Known libcurl bindings: 39
|
||||||
Contributors: 865
|
Contributors: 868
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o Added --tr-encoding and CURLOPT_TRANSFER_ENCODING
|
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:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o curl-config: fix --version
|
o SECURITY ADVISORY: inappropriate GSSAPI delegation. Full details at
|
||||||
o curl_easy_setopt.3: CURLOPT_PROXYTYPE clarification
|
http://curl.haxx.se/docs/adv_20110623.html
|
||||||
o use HTTPS properly after CONNECT
|
o NTLM: work with unicode
|
||||||
o SFTP: close file before post quote operations
|
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:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@@ -25,8 +41,9 @@ This release includes the following known bugs:
|
|||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Patrick Monnerat, Dan Fandrich, Gisle Vanem, Guenter Knauf,
|
Dan Fandrich, Guenter Knauf, Vsevolod Novikov, Zmey Petroff,
|
||||||
Rajesh Naganathan, Josue Andrade Gomes, Ryan Schmidt, Fabian Keil,
|
Dagobert Michelsen, Jeff Pohlmeyer, Dmitri Shubin, Matteo Rocco,
|
||||||
Julien Chaffraix
|
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)
|
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_arg2 in 'char *' 'void *'; do
|
||||||
for recvfrom_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do
|
for recvfrom_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do
|
||||||
for recvfrom_arg4 in 'int' '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
|
for recvfrom_arg6 in 'socklen_t *' 'int *' 'unsigned int *' 'size_t *' 'void *'; do
|
||||||
if test "$curl_cv_func_recvfrom_args" = "unknown"; then
|
if test "$curl_cv_func_recvfrom_args" = "unknown"; then
|
||||||
AC_COMPILE_IFELSE([
|
AC_COMPILE_IFELSE([
|
||||||
@@ -1731,7 +1731,7 @@ AC_DEFUN([CURL_CHECK_FUNC_RECVFROM], [
|
|||||||
shift
|
shift
|
||||||
#
|
#
|
||||||
recvfrom_ptrt_arg2=$[2]
|
recvfrom_ptrt_arg2=$[2]
|
||||||
recvfrom_ptrt_arg5=$[5]
|
recvfrom_qual_ptrt_arg5=$[5]
|
||||||
recvfrom_ptrt_arg6=$[6]
|
recvfrom_ptrt_arg6=$[6]
|
||||||
#
|
#
|
||||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG1, $[1],
|
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG1, $[1],
|
||||||
@@ -1753,12 +1753,25 @@ AC_DEFUN([CURL_CHECK_FUNC_RECVFROM], [
|
|||||||
;;
|
;;
|
||||||
esac
|
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_arg2=`echo $recvfrom_ptrt_arg2 | sed 's/ \*//'`
|
||||||
recvfrom_type_arg5=`echo $recvfrom_ptrt_arg5 | sed 's/ \*//'`
|
recvfrom_type_arg5=`echo $recvfrom_ptrt_arg5 | sed 's/ \*//'`
|
||||||
recvfrom_type_arg6=`echo $recvfrom_ptrt_arg6 | sed 's/ \*//'`
|
recvfrom_type_arg6=`echo $recvfrom_ptrt_arg6 | sed 's/ \*//'`
|
||||||
#
|
#
|
||||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG2, $recvfrom_type_arg2,
|
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG2, $recvfrom_type_arg2,
|
||||||
[Define to the type pointed by arg 2 for recvfrom.])
|
[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,
|
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG5, $recvfrom_type_arg5,
|
||||||
[Define to the type pointed by arg 5 for recvfrom.])
|
[Define to the type pointed by arg 5 for recvfrom.])
|
||||||
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG6, $recvfrom_type_arg6,
|
AC_DEFINE_UNQUOTED(RECVFROM_TYPE_ARG6, $recvfrom_type_arg6,
|
||||||
@@ -2843,7 +2856,7 @@ AC_DEFUN([DO_CURL_OFF_T_CHECK], [
|
|||||||
tmp_includes=""
|
tmp_includes=""
|
||||||
tmp_source=""
|
tmp_source=""
|
||||||
tmp_fmt=""
|
tmp_fmt=""
|
||||||
case AS_TR_SH([$1]) in
|
case XC_SH_TR_SH([$1]) in
|
||||||
int64_t)
|
int64_t)
|
||||||
tmp_includes="$curl_includes_inttypes"
|
tmp_includes="$curl_includes_inttypes"
|
||||||
tmp_source="char f@<:@@:>@ = PRId64;"
|
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_t="unknown"
|
||||||
curl_suffix_curl_off_tu="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)
|
long_long | __longlong | __longlong_t)
|
||||||
tst_suffixes="LL::"
|
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/'`
|
curl_format_curl_off_tu=`echo "$curl_format_curl_off_tu" | "$SED" 's/D$/U/'`
|
||||||
else
|
else
|
||||||
x_pull_headers="no"
|
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)
|
long_long | __longlong | __longlong_t)
|
||||||
curl_format_curl_off_t="lld"
|
curl_format_curl_off_t="lld"
|
||||||
curl_format_curl_off_tu="llu"
|
curl_format_curl_off_tu="llu"
|
||||||
|
|||||||
30
configure.ac
30
configure.ac
@@ -305,6 +305,24 @@ AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
|
|||||||
CURL_CHECK_CURLDEBUG
|
CURL_CHECK_CURLDEBUG
|
||||||
AM_CONDITIONAL(CURLDEBUG, test x$want_curldebug = xyes)
|
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 **********************************************************************
|
||||||
dnl Compilation based checks should not be done before this point.
|
dnl Compilation based checks should not be done before this point.
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -1513,6 +1531,7 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
export LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH
|
||||||
AC_MSG_NOTICE([Added $LIB_OPENSSL to LD_LIBRARY_PATH])
|
AC_MSG_NOTICE([Added $LIB_OPENSSL to LD_LIBRARY_PATH])
|
||||||
fi
|
fi
|
||||||
|
CURL_CHECK_OPENSSL_API
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
@@ -1624,8 +1643,12 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
|
|||||||
[read randomness from FILE (default=/dev/urandom)]),
|
[read randomness from FILE (default=/dev/urandom)]),
|
||||||
[ RANDOM_FILE="$withval" ],
|
[ RANDOM_FILE="$withval" ],
|
||||||
[
|
[
|
||||||
dnl Check for random device
|
if test x$cross_compiling != xyes; then
|
||||||
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
|
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
|
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_FSETXATTR
|
||||||
CURL_CHECK_FUNC_FTRUNCATE
|
CURL_CHECK_FUNC_FTRUNCATE
|
||||||
CURL_CHECK_FUNC_GETADDRINFO
|
CURL_CHECK_FUNC_GETADDRINFO
|
||||||
|
CURL_CHECK_FUNC_GAI_STRERROR
|
||||||
CURL_CHECK_FUNC_GETHOSTBYADDR
|
CURL_CHECK_FUNC_GETHOSTBYADDR
|
||||||
CURL_CHECK_FUNC_GETHOSTBYADDR_R
|
CURL_CHECK_FUNC_GETHOSTBYADDR_R
|
||||||
CURL_CHECK_FUNC_GETHOSTBYNAME
|
CURL_CHECK_FUNC_GETHOSTBYNAME
|
||||||
@@ -2593,7 +2617,7 @@ AC_CHECK_FUNCS([fork \
|
|||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
eval "ac_cv_func_$func=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.])
|
[Define to 1 if you have the $func function.])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([but still no])
|
AC_MSG_RESULT([but still no])
|
||||||
|
|||||||
29
docs/FAQ
29
docs/FAQ
@@ -36,7 +36,7 @@ FAQ
|
|||||||
3.2 How do I tell curl to resume a transfer?
|
3.2 How do I tell curl to resume a transfer?
|
||||||
3.3 Why doesn't my posting using -F work?
|
3.3 Why doesn't my posting using -F work?
|
||||||
3.4 How do I tell curl to run custom FTP commands?
|
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.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.7 Can I use curl to delete/rename a file through FTP?
|
||||||
3.8 How do I tell curl to follow HTTP redirects?
|
3.8 How do I tell curl to follow HTTP redirects?
|
||||||
@@ -491,7 +491,6 @@ FAQ
|
|||||||
3.2 How do I tell curl to resume a transfer?
|
3.2 How do I tell curl to resume a transfer?
|
||||||
|
|
||||||
Curl supports resumed transfers both ways on both FTP and HTTP.
|
Curl supports resumed transfers both ways on both FTP and HTTP.
|
||||||
|
|
||||||
Try the -C option.
|
Try the -C option.
|
||||||
|
|
||||||
3.3 Why doesn't my posting using -F work?
|
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
|
FTP commands without transferring anything. Therefore you must always specify
|
||||||
a URL to transfer to/from even when doing custom FTP commands.
|
a URL to transfer to/from even when doing custom FTP commands.
|
||||||
|
|
||||||
3.5 How can I disable the Pragma: nocache header?
|
3.5 How can I disable the Accept: */* header?
|
||||||
|
|
||||||
You can change all internally generated headers by adding a replacement with
|
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
|
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?
|
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:
|
install and use them, in the libcurl section of the curl web site:
|
||||||
http://curl.haxx.se/libcurl/
|
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
|
In October 2009, there were interfaces available for the following
|
||||||
languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
|
languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
|
||||||
Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET,
|
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
|
libcurl will reuse connections for all transfers that are made using the
|
||||||
same libcurl handle.
|
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!
|
5.7 Link errors when building libcurl on Windows!
|
||||||
|
|
||||||
You need to make sure that your project, and all the libraries (both static
|
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
|
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
|
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.
|
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
|
Instead, you need to make sure that one of the callbacks you use returns an
|
||||||
appropriate value that will stop the transfer.
|
appropriate value that will stop the transfer. Suitable callbacks that you
|
||||||
|
can do this with include the progress callback, the read callback and the
|
||||||
Suitable callbacks that you can do this with include the progress callback,
|
write callback.
|
||||||
the read callback and the write callback.
|
|
||||||
|
|
||||||
If you're using the multi interface, you can also stop a transfer by
|
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.
|
think the transfer is done.
|
||||||
|
|
||||||
5.14 Using C++ non-static functions for callbacks?
|
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
|
binary package. This document describes how to compile, build and install
|
||||||
curl and libcurl from source code.
|
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
|
UNIX
|
||||||
====
|
====
|
||||||
A normal unix installation is made in three or four steps (after you've
|
A normal unix installation is made in three or four steps (after you've
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ Building with CMake
|
|||||||
CMake builds can be configured either from the command line, or from one
|
CMake builds can be configured either from the command line, or from one
|
||||||
of CMake's GUI's.
|
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
|
Command Line CMake
|
||||||
==================
|
==================
|
||||||
A command line build of Curl is similar to the autotools build of Curl. It
|
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.
|
# variable prior to running CMake.
|
||||||
cmake ../curl
|
cmake ../curl
|
||||||
make
|
make
|
||||||
# currently make test and make install are not implemented
|
# currently make test is not implemented
|
||||||
#make test
|
#make test
|
||||||
#make install
|
# Install to default location:
|
||||||
|
make install
|
||||||
|
|
||||||
ccmake
|
ccmake
|
||||||
=========
|
=========
|
||||||
|
|||||||
@@ -424,6 +424,7 @@ Jose Kahan
|
|||||||
Josef Wolf
|
Josef Wolf
|
||||||
Josh Kapell
|
Josh Kapell
|
||||||
Joshua Kwan
|
Joshua Kwan
|
||||||
|
Josue Andrade Gomes
|
||||||
Juan F. Codagnone
|
Juan F. Codagnone
|
||||||
Juan Ignacio Herv<72>s
|
Juan Ignacio Herv<72>s
|
||||||
Judson Bishop
|
Judson Bishop
|
||||||
@@ -673,6 +674,7 @@ Rafa Muyo
|
|||||||
Rafael Sagula
|
Rafael Sagula
|
||||||
Rainer Canavan
|
Rainer Canavan
|
||||||
Rainer Koenig
|
Rainer Koenig
|
||||||
|
Rajesh Naganathan
|
||||||
Ralf S. Engelschall
|
Ralf S. Engelschall
|
||||||
Ralph Beckmann
|
Ralph Beckmann
|
||||||
Ralph Mitchell
|
Ralph Mitchell
|
||||||
@@ -727,6 +729,7 @@ Ruslan Gazizov
|
|||||||
Rutger Hofman
|
Rutger Hofman
|
||||||
Ryan Chan
|
Ryan Chan
|
||||||
Ryan Nelson
|
Ryan Nelson
|
||||||
|
Ryan Schmidt
|
||||||
S. Moonesamy
|
S. Moonesamy
|
||||||
Salvador D<>vila
|
Salvador D<>vila
|
||||||
Salvatore Sorrentino
|
Salvatore Sorrentino
|
||||||
|
|||||||
933
docs/curl.1
933
docs/curl.1
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,6 @@
|
|||||||
#else
|
#else
|
||||||
# ifdef __VMS
|
# ifdef __VMS
|
||||||
typedef int intptr_t;
|
typedef int intptr_t;
|
||||||
# else
|
|
||||||
# include <stdint.h>
|
|
||||||
# endif
|
# endif
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
.SH DESCRIPTION
|
||||||
This function converts the given input string to an URL encoded string and
|
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,
|
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
|
A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" version
|
||||||
two-digit hexadecimal number).
|
(%NN where NN is a two-digit hexadecimal number).
|
||||||
|
|
||||||
If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_escape(3)\fP
|
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.
|
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
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
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
|
start until the file transfer is just about to begin. This includes all
|
||||||
pre-transfer commands and negotiations that are specific to the particular
|
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
|
.IP CURLINFO_STARTTRANSFER_TIME
|
||||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
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
|
start until the first byte is received by libcurl. This includes
|
||||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate the
|
||||||
the result.
|
result.
|
||||||
.IP CURLINFO_REDIRECT_TIME
|
.IP CURLINFO_REDIRECT_TIME
|
||||||
Pass a pointer to a double to receive the total time, in seconds, it took for
|
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
|
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.
|
and negotiations that are specific to the particular protocol(s) involved.
|
||||||
.IP STARTTRANSFER
|
.IP STARTTRANSFER
|
||||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
\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
|
.IP TOTAL
|
||||||
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
||||||
.IP REDIRECT
|
.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
|
output. This is only relevant for protocols that actually have headers
|
||||||
preceding the data (like HTTP).
|
preceding the data (like HTTP).
|
||||||
.IP CURLOPT_NOPROGRESS
|
.IP CURLOPT_NOPROGRESS
|
||||||
A parameter set to 1 tells the library to shut off the built-in progress meter
|
Pass a long. If set to 1, it tells the library to shut off the progress meter
|
||||||
completely.
|
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
|
Future versions of libcurl are likely to not have any built-in progress meter
|
||||||
at all.
|
at all.
|
||||||
@@ -105,18 +106,18 @@ This feature is only supported by the FTP download for now.
|
|||||||
|
|
||||||
A brief introduction of its syntax follows:
|
A brief introduction of its syntax follows:
|
||||||
.RS
|
.RS
|
||||||
.IP "\fB*\fP - ASTERISK"
|
.IP "* - ASTERISK"
|
||||||
\&ftp://example.com/some/path/\fB*.txt\fP (for all txt's from the root
|
\&ftp://example.com/some/path/\fB*.txt\fP (for all txt's from the root
|
||||||
directory)
|
directory)
|
||||||
.RE
|
.RE
|
||||||
.RS
|
.RS
|
||||||
.IP "\fB?\fP - QUESTION MARK"
|
.IP "? - QUESTION MARK"
|
||||||
Question mark matches any (exactly one) character.
|
Question mark matches any (exactly one) character.
|
||||||
|
|
||||||
\&ftp://example.com/some/path/\fBphoto?.jpeg\fP
|
\&ftp://example.com/some/path/\fBphoto?.jpeg\fP
|
||||||
.RE
|
.RE
|
||||||
.RS
|
.RS
|
||||||
.IP "\fB[\fP - BRACKET EXPRESSION"
|
.IP "[ - BRACKET EXPRESSION"
|
||||||
The left bracket opens a bracket expression. The question mark and asterisk have
|
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
|
no special meaning in a bracket expression. Each bracket expression ends by the
|
||||||
right bracket and matches exactly one character. Some examples follow:
|
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
|
.SH CALLBACK OPTIONS
|
||||||
.IP CURLOPT_WRITEFUNCTION
|
.IP CURLOPT_WRITEFUNCTION
|
||||||
Function pointer that should match the following prototype: \fBsize_t
|
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
|
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
|
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
|
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
|
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||||
argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP.
|
argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP.
|
||||||
(Option added in 7.17.1.)
|
(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
|
.IP CURLOPT_PROGRESSFUNCTION
|
||||||
Function pointer that should match the \fIcurl_progress_callback\fP prototype
|
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
|
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( 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
|
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
|
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
|
lines are passed on to the callback. Parsing headers is very easy using
|
||||||
using this. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
this. The size of the data pointed to by \fIptr\fP is \fIsize\fP multiplied
|
||||||
multiplied with \fInmemb\fP. Do not assume that the header line is zero
|
with \fInmemb\fP. Do not assume that the header line is zero terminated! The
|
||||||
terminated! The pointer named \fIuserdata\fP is the one you set with the
|
pointer named \fIuserdata\fP is the one you set with the
|
||||||
\fICURLOPT_WRITEHEADER\fP option. The callback function must return the number
|
\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
|
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
|
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
|
response, you will need to collect headers in the callback yourself and use
|
||||||
HTTP status lines, for example, to delimit response boundaries.
|
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
|
When a server sends a chunked encoded transfer, it may contain a trailer. That
|
||||||
trailer. That trailer is identical to a HTTP header and if such a trailer is
|
trailer is identical to a HTTP header and if such a trailer is received it is
|
||||||
received it is passed to the application using this callback as well. There
|
passed to the application using this callback as well. There are several ways
|
||||||
are several ways to detect it being a trailer and not an ordinary header: 1)
|
to detect it being a trailer and not an ordinary header: 1) it comes after the
|
||||||
it comes after the response-body. 2) it comes after the final header line (CR
|
response-body. 2) it comes after the final header line (CR LF) 3) a Trailer:
|
||||||
LF) 3) a Trailer: header among the response-headers mention what header to
|
header among the regular response-headers mention what header(s) to expect in
|
||||||
expect in the trailer.
|
the trailer.
|
||||||
.IP CURLOPT_WRITEHEADER
|
.IP CURLOPT_WRITEHEADER
|
||||||
(This option is also known as \fBCURLOPT_HEADERDATA\fP) Pass a pointer to be
|
(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
|
used to write the header part of the received data to. If you don't use
|
||||||
own callback to take care of the writing, this must be a valid FILE *. See
|
\fICURLOPT_WRITEFUNCTION\fP or \fICURLOPT_HEADERFUNCTION\fP to take care of
|
||||||
also the \fICURLOPT_HEADERFUNCTION\fP option above on how to set a custom
|
the writing, this must be a valid FILE * as the internal default will then be
|
||||||
get-all-headers callback.
|
a plain fwrite(). See also the \fICURLOPT_HEADERFUNCTION\fP option above on
|
||||||
|
how to set a custom get-all-headers callback.
|
||||||
.IP CURLOPT_DEBUGFUNCTION
|
.IP CURLOPT_DEBUGFUNCTION
|
||||||
Function pointer that should match the following prototype: \fIint
|
Function pointer that should match the following prototype: \fIint
|
||||||
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
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
|
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,
|
specified the exact same way as the proxy can be set with \fICURLOPT_PROXY\fP,
|
||||||
include protocol prefix (http://) and embedded user + password.
|
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
|
.IP CURLOPT_PROXYPORT
|
||||||
Pass a long with this option to set the proxy port to connect to unless it is
|
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.
|
specified in the proxy string \fICURLOPT_PROXY\fP.
|
||||||
@@ -2098,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)
|
option is only for SCP and SFTP transfers. (Added in 7.17.1)
|
||||||
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
||||||
Pass a char * pointing to a file name for your public key. If not used,
|
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.
|
libcurl defaults to \fB$HOME/.ssh/id_dsa.pub\fP if the HOME environment
|
||||||
(Added in 7.16.1)
|
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
|
.IP CURLOPT_SSH_PRIVATE_KEYFILE
|
||||||
Pass a char * pointing to a file name for your private key. If not used,
|
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
|
libcurl defaults to \fB$HOME/.ssh/id_dsa\fP if the HOME environment variable
|
||||||
password-protected, set the password with \fICURLOPT_KEYPASSWD\fP. (Added in
|
is set, and just "id_dsa" in the current directory if HOME is not set. If the
|
||||||
7.16.1)
|
file is password-protected, set the password with
|
||||||
|
\fICURLOPT_KEYPASSWD\fP. (Added in 7.16.1)
|
||||||
.IP CURLOPT_SSH_KNOWNHOSTS
|
.IP CURLOPT_SSH_KNOWNHOSTS
|
||||||
Pass a pointer to a zero terminated string holding the file name of the
|
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
|
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
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
curl_formadd() is used to append sections when building a multipart/formdata
|
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
|
HTTP POST (sometimes referred to as RFC2388-style posts). Append one section
|
||||||
a time until you've added all the sections you want included and then you pass
|
at a time until you've added all the sections you want included and then you
|
||||||
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
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
|
\fIlastitem\fP is set after each \fIcurl_formadd(3)\fP call and on repeated
|
||||||
left as set to allow repeated invokes to find the end of the list faster.
|
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.
|
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
|
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
|
the function itself. You must call \fIcurl_formfree(3)\fP on the
|
||||||
has been done to free the resources.
|
\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.
|
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.
|
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
|
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
|
\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.
|
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
|
.SH RETURN VALUE
|
||||||
None
|
None
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
|||||||
@@ -23,24 +23,27 @@
|
|||||||
.SH NAME
|
.SH NAME
|
||||||
curl_formget - serialize a previously built multipart/formdata HTTP POST chain
|
curl_formget - serialize a previously built multipart/formdata HTTP POST chain
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
.B #include <curl/curl.h>
|
.B #include <curl/curl.h>
|
||||||
.sp
|
|
||||||
.BI "void curl_formget(struct curl_httppost *" form, " void *" arg,
|
void curl_formget(struct curl_httppost * form, void *userp,
|
||||||
.BI " curl_formget_callback " append ");"
|
curl_formget_callback append );
|
||||||
.ad
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
curl_formget() is used to serialize data previously built/appended with
|
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
|
\fIcurl_formadd(3)\fP. Accepts a void pointer as second argument named
|
||||||
passed to the curl_formget_callback function.
|
\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 ");"
|
.BI " size_t " len ");"
|
||||||
.nf
|
|
||||||
|
|
||||||
The curl_formget_callback will be executed for each part of the HTTP POST
|
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
|
chain. The character buffer passed to the callback must not be freed. The
|
||||||
curl_formget(). The character buffer passed to it must not be freed. The
|
|
||||||
callback should return the buffer length passed to it on success.
|
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
|
.SH RETURN VALUE
|
||||||
0 means everything was ok, non-zero means an error occurred
|
0 means everything was ok, non-zero means an error occurred
|
||||||
.SH EXAMPLE
|
.SH EXAMPLE
|
||||||
@@ -52,6 +55,7 @@ callback should return the buffer length passed to it on success.
|
|||||||
(*(size_t *) arg) += len;
|
(*(size_t *) arg) += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print_httppost(struct curl_httppost *post)
|
size_t print_httppost(struct curl_httppost *post)
|
||||||
{
|
{
|
||||||
size_t total_size = 0;
|
size_t total_size = 0;
|
||||||
|
|||||||
@@ -295,6 +295,8 @@ CURLOPT_CHUNK_DATA 7.21.0
|
|||||||
CURLOPT_CHUNK_END_FUNCTION 7.21.0
|
CURLOPT_CHUNK_END_FUNCTION 7.21.0
|
||||||
CURLOPT_CLOSEFUNCTION 7.7 7.11.1 7.15.5
|
CURLOPT_CLOSEFUNCTION 7.7 7.11.1 7.15.5
|
||||||
CURLOPT_CLOSEPOLICY 7.7 7.16.1
|
CURLOPT_CLOSEPOLICY 7.7 7.16.1
|
||||||
|
CURLOPT_CLOSESOCKETDATA 7.21.7
|
||||||
|
CURLOPT_CLOSESOCKETFUNCTION 7.21.7
|
||||||
CURLOPT_CONNECTTIMEOUT 7.7
|
CURLOPT_CONNECTTIMEOUT 7.7
|
||||||
CURLOPT_CONNECTTIMEOUT_MS 7.16.2
|
CURLOPT_CONNECTTIMEOUT_MS 7.16.2
|
||||||
CURLOPT_CONNECT_ONLY 7.15.2
|
CURLOPT_CONNECT_ONLY 7.15.2
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#
|
#
|
||||||
###########################################################################
|
###########################################################################
|
||||||
pkginclude_HEADERS = \
|
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
|
typecheck-gcc.h curlbuild.h curlrules.h
|
||||||
|
|
||||||
pkgincludedir= $(includedir)/curl
|
pkgincludedir= $(includedir)/curl
|
||||||
@@ -44,3 +44,10 @@ EXTRA_DIST = curlbuild.h.in
|
|||||||
|
|
||||||
DISTCLEANFILES = curlbuild.h
|
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,
|
curlsocktype purpose,
|
||||||
struct curl_sockaddr *address);
|
struct curl_sockaddr *address);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CURLIOE_OK, /* I/O operation successful */
|
CURLIOE_OK, /* I/O operation successful */
|
||||||
CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
|
CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
|
||||||
@@ -507,7 +510,7 @@ typedef enum {
|
|||||||
7.19.0) */
|
7.19.0) */
|
||||||
CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
||||||
CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
|
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_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
|
||||||
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||||
|
|
||||||
@@ -755,7 +758,7 @@ typedef enum {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_ISOCPP
|
#ifdef CURL_ISOCPP
|
||||||
#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
|
#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
|
||||||
#else
|
#else
|
||||||
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
||||||
#define LONG CURLOPTTYPE_LONG
|
#define LONG CURLOPTTYPE_LONG
|
||||||
@@ -924,7 +927,7 @@ typedef enum {
|
|||||||
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
|
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
|
||||||
CINIT(UPLOAD, LONG, 46), /* this is an upload */
|
CINIT(UPLOAD, LONG, 46), /* this is an upload */
|
||||||
CINIT(POST, LONG, 47), /* HTTP POST method */
|
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! */
|
CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */
|
||||||
|
|
||||||
@@ -991,8 +994,7 @@ typedef enum {
|
|||||||
/* Max amount of cached alive connections */
|
/* Max amount of cached alive connections */
|
||||||
CINIT(MAXCONNECTS, LONG, 71),
|
CINIT(MAXCONNECTS, LONG, 71),
|
||||||
|
|
||||||
/* What policy to use when closing connections when the cache is filled
|
/* 72 - DEPRECATED */
|
||||||
up */
|
|
||||||
CINIT(CLOSEPOLICY, LONG, 72),
|
CINIT(CLOSEPOLICY, LONG, 72),
|
||||||
|
|
||||||
/* 73 = OBSOLETE */
|
/* 73 = OBSOLETE */
|
||||||
@@ -1119,8 +1121,8 @@ typedef enum {
|
|||||||
and password to whatever host the server decides. */
|
and password to whatever host the server decides. */
|
||||||
CINIT(UNRESTRICTED_AUTH, LONG, 105),
|
CINIT(UNRESTRICTED_AUTH, LONG, 105),
|
||||||
|
|
||||||
/* Specifically switch on or off the FTP engine's use of the EPRT command ( it
|
/* Specifically switch on or off the FTP engine's use of the EPRT command (
|
||||||
also disables the LPRT attempt). By default, those ones will always be
|
it also disables the LPRT attempt). By default, those ones will always be
|
||||||
attempted before the good old traditional PORT command. */
|
attempted before the good old traditional PORT command. */
|
||||||
CINIT(FTP_USE_EPRT, LONG, 106),
|
CINIT(FTP_USE_EPRT, LONG, 106),
|
||||||
|
|
||||||
@@ -1476,6 +1478,11 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
CINIT(TRANSFER_ENCODING, LONG, 207),
|
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 */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -1704,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
|
* Should return the buffer length passed to it as the argument "len" on
|
||||||
* success.
|
* 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()
|
* 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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -58,52 +58,52 @@
|
|||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_LONG
|
#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
|
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
#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
|
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
#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
|
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
#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
|
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_T
|
#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
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_TU
|
#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
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_OFF_T
|
#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
|
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_OFF_T
|
#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
|
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_T
|
#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
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
#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
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,13 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.21.6-DEV"
|
#define LIBCURL_VERSION "7.21.7-DEV"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 21
|
#define LIBCURL_VERSION_MINOR 21
|
||||||
#define LIBCURL_VERSION_PATCH 6
|
#define LIBCURL_VERSION_PATCH 7
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
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
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x071506
|
#define LIBCURL_VERSION_NUM 0x071507
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the date and time when the full source package was created. The
|
* This is the date and time when the full source package was created. The
|
||||||
|
|||||||
@@ -41,66 +41,66 @@
|
|||||||
#define curl_easy_setopt(handle, option, value) \
|
#define curl_easy_setopt(handle, option, value) \
|
||||||
__extension__ ({ \
|
__extension__ ({ \
|
||||||
__typeof__ (option) _curl_opt = option; \
|
__typeof__ (option) _curl_opt = option; \
|
||||||
if (__builtin_constant_p(_curl_opt)) { \
|
if(__builtin_constant_p(_curl_opt)) { \
|
||||||
if (_curl_is_long_option(_curl_opt)) \
|
if(_curl_is_long_option(_curl_opt)) \
|
||||||
if (!_curl_is_long(value)) \
|
if(!_curl_is_long(value)) \
|
||||||
_curl_easy_setopt_err_long(); \
|
_curl_easy_setopt_err_long(); \
|
||||||
if (_curl_is_off_t_option(_curl_opt)) \
|
if(_curl_is_off_t_option(_curl_opt)) \
|
||||||
if (!_curl_is_off_t(value)) \
|
if(!_curl_is_off_t(value)) \
|
||||||
_curl_easy_setopt_err_curl_off_t(); \
|
_curl_easy_setopt_err_curl_off_t(); \
|
||||||
if (_curl_is_string_option(_curl_opt)) \
|
if(_curl_is_string_option(_curl_opt)) \
|
||||||
if (!_curl_is_string(value)) \
|
if(!_curl_is_string(value)) \
|
||||||
_curl_easy_setopt_err_string(); \
|
_curl_easy_setopt_err_string(); \
|
||||||
if (_curl_is_write_cb_option(_curl_opt)) \
|
if(_curl_is_write_cb_option(_curl_opt)) \
|
||||||
if (!_curl_is_write_cb(value)) \
|
if(!_curl_is_write_cb(value)) \
|
||||||
_curl_easy_setopt_err_write_callback(); \
|
_curl_easy_setopt_err_write_callback(); \
|
||||||
if ((_curl_opt) == CURLOPT_READFUNCTION) \
|
if((_curl_opt) == CURLOPT_READFUNCTION) \
|
||||||
if (!_curl_is_read_cb(value)) \
|
if(!_curl_is_read_cb(value)) \
|
||||||
_curl_easy_setopt_err_read_cb(); \
|
_curl_easy_setopt_err_read_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
||||||
if (!_curl_is_ioctl_cb(value)) \
|
if(!_curl_is_ioctl_cb(value)) \
|
||||||
_curl_easy_setopt_err_ioctl_cb(); \
|
_curl_easy_setopt_err_ioctl_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
||||||
if (!_curl_is_sockopt_cb(value)) \
|
if(!_curl_is_sockopt_cb(value)) \
|
||||||
_curl_easy_setopt_err_sockopt_cb(); \
|
_curl_easy_setopt_err_sockopt_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||||
if (!_curl_is_opensocket_cb(value)) \
|
if(!_curl_is_opensocket_cb(value)) \
|
||||||
_curl_easy_setopt_err_opensocket_cb(); \
|
_curl_easy_setopt_err_opensocket_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
||||||
if (!_curl_is_progress_cb(value)) \
|
if(!_curl_is_progress_cb(value)) \
|
||||||
_curl_easy_setopt_err_progress_cb(); \
|
_curl_easy_setopt_err_progress_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
||||||
if (!_curl_is_debug_cb(value)) \
|
if(!_curl_is_debug_cb(value)) \
|
||||||
_curl_easy_setopt_err_debug_cb(); \
|
_curl_easy_setopt_err_debug_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||||
if (!_curl_is_ssl_ctx_cb(value)) \
|
if(!_curl_is_ssl_ctx_cb(value)) \
|
||||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
||||||
if (_curl_is_conv_cb_option(_curl_opt)) \
|
if(_curl_is_conv_cb_option(_curl_opt)) \
|
||||||
if (!_curl_is_conv_cb(value)) \
|
if(!_curl_is_conv_cb(value)) \
|
||||||
_curl_easy_setopt_err_conv_cb(); \
|
_curl_easy_setopt_err_conv_cb(); \
|
||||||
if ((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
||||||
if (!_curl_is_seek_cb(value)) \
|
if(!_curl_is_seek_cb(value)) \
|
||||||
_curl_easy_setopt_err_seek_cb(); \
|
_curl_easy_setopt_err_seek_cb(); \
|
||||||
if (_curl_is_cb_data_option(_curl_opt)) \
|
if(_curl_is_cb_data_option(_curl_opt)) \
|
||||||
if (!_curl_is_cb_data(value)) \
|
if(!_curl_is_cb_data(value)) \
|
||||||
_curl_easy_setopt_err_cb_data(); \
|
_curl_easy_setopt_err_cb_data(); \
|
||||||
if ((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
||||||
if (!_curl_is_error_buffer(value)) \
|
if(!_curl_is_error_buffer(value)) \
|
||||||
_curl_easy_setopt_err_error_buffer(); \
|
_curl_easy_setopt_err_error_buffer(); \
|
||||||
if ((_curl_opt) == CURLOPT_STDERR) \
|
if((_curl_opt) == CURLOPT_STDERR) \
|
||||||
if (!_curl_is_FILE(value)) \
|
if(!_curl_is_FILE(value)) \
|
||||||
_curl_easy_setopt_err_FILE(); \
|
_curl_easy_setopt_err_FILE(); \
|
||||||
if (_curl_is_postfields_option(_curl_opt)) \
|
if(_curl_is_postfields_option(_curl_opt)) \
|
||||||
if (!_curl_is_postfields(value)) \
|
if(!_curl_is_postfields(value)) \
|
||||||
_curl_easy_setopt_err_postfields(); \
|
_curl_easy_setopt_err_postfields(); \
|
||||||
if ((_curl_opt) == CURLOPT_HTTPPOST) \
|
if((_curl_opt) == CURLOPT_HTTPPOST) \
|
||||||
if (!_curl_is_arr((value), struct curl_httppost)) \
|
if(!_curl_is_arr((value), struct curl_httppost)) \
|
||||||
_curl_easy_setopt_err_curl_httpost(); \
|
_curl_easy_setopt_err_curl_httpost(); \
|
||||||
if (_curl_is_slist_option(_curl_opt)) \
|
if(_curl_is_slist_option(_curl_opt)) \
|
||||||
if (!_curl_is_arr((value), struct curl_slist)) \
|
if(!_curl_is_arr((value), struct curl_slist)) \
|
||||||
_curl_easy_setopt_err_curl_slist(); \
|
_curl_easy_setopt_err_curl_slist(); \
|
||||||
if ((_curl_opt) == CURLOPT_SHARE) \
|
if((_curl_opt) == CURLOPT_SHARE) \
|
||||||
if (!_curl_is_ptr((value), CURLSH)) \
|
if(!_curl_is_ptr((value), CURLSH)) \
|
||||||
_curl_easy_setopt_err_CURLSH(); \
|
_curl_easy_setopt_err_CURLSH(); \
|
||||||
} \
|
} \
|
||||||
curl_easy_setopt(handle, _curl_opt, value); \
|
curl_easy_setopt(handle, _curl_opt, value); \
|
||||||
@@ -111,18 +111,18 @@ __extension__ ({ \
|
|||||||
#define curl_easy_getinfo(handle, info, arg) \
|
#define curl_easy_getinfo(handle, info, arg) \
|
||||||
__extension__ ({ \
|
__extension__ ({ \
|
||||||
__typeof__ (info) _curl_info = info; \
|
__typeof__ (info) _curl_info = info; \
|
||||||
if (__builtin_constant_p(_curl_info)) { \
|
if(__builtin_constant_p(_curl_info)) { \
|
||||||
if (_curl_is_string_info(_curl_info)) \
|
if(_curl_is_string_info(_curl_info)) \
|
||||||
if (!_curl_is_arr((arg), char *)) \
|
if(!_curl_is_arr((arg), char *)) \
|
||||||
_curl_easy_getinfo_err_string(); \
|
_curl_easy_getinfo_err_string(); \
|
||||||
if (_curl_is_long_info(_curl_info)) \
|
if(_curl_is_long_info(_curl_info)) \
|
||||||
if (!_curl_is_arr((arg), long)) \
|
if(!_curl_is_arr((arg), long)) \
|
||||||
_curl_easy_getinfo_err_long(); \
|
_curl_easy_getinfo_err_long(); \
|
||||||
if (_curl_is_double_info(_curl_info)) \
|
if(_curl_is_double_info(_curl_info)) \
|
||||||
if (!_curl_is_arr((arg), double)) \
|
if(!_curl_is_arr((arg), double)) \
|
||||||
_curl_easy_getinfo_err_double(); \
|
_curl_easy_getinfo_err_double(); \
|
||||||
if (_curl_is_slist_info(_curl_info)) \
|
if(_curl_is_slist_info(_curl_info)) \
|
||||||
if (!_curl_is_arr((arg), struct curl_slist *)) \
|
if(!_curl_is_arr((arg), struct curl_slist *)) \
|
||||||
_curl_easy_getinfo_err_curl_slist(); \
|
_curl_easy_getinfo_err_curl_slist(); \
|
||||||
} \
|
} \
|
||||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
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_WARNING(_curl_easy_setopt_err_curl_off_t,
|
||||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
"curl_easy_setopt expects a curl_off_t argument for this option")
|
||||||
_CURL_WARNING(_curl_easy_setopt_err_string,
|
_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_WARNING(_curl_easy_setopt_err_write_callback,
|
||||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
"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_WARNING(_curl_easy_setopt_err_sockopt_cb,
|
||||||
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
||||||
_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
|
_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_WARNING(_curl_easy_setopt_err_progress_cb,
|
||||||
"curl_easy_setopt expects a curl_progress_callback argument for this option")
|
"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_WARNING(_curl_easy_setopt_err_seek_cb,
|
||||||
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
||||||
_CURL_WARNING(_curl_easy_setopt_err_cb_data,
|
_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_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_WARNING(_curl_easy_setopt_err_FILE,
|
||||||
"curl_easy_setopt expects a FILE* argument for this option")
|
"curl_easy_setopt expects a FILE* argument for this option")
|
||||||
_CURL_WARNING(_curl_easy_setopt_err_postfields,
|
_CURL_WARNING(_curl_easy_setopt_err_postfields,
|
||||||
@@ -481,7 +485,8 @@ typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
|||||||
typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
|
typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
|
||||||
curlsocktype);
|
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) \
|
#define _curl_is_opensocket_cb(expr) \
|
||||||
(_curl_is_NULL(expr) || \
|
(_curl_is_NULL(expr) || \
|
||||||
__builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
|
__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_callback5)(CURL *, SSL_CTX, void *);
|
||||||
typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const 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_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
|
#else
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
|
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")
|
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS ${LIB_NAME} DESTINATION lib)
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
|
|||||||
CFLAGS += -dUSE_WINDOWS_SSPI
|
CFLAGS += -dUSE_WINDOWS_SSPI
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifdef %use_winidn
|
||||||
|
CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN
|
||||||
|
! if $(__VERSION__) <= 1290
|
||||||
|
CFLAGS += -dWANT_IDN_PROTOTYPES
|
||||||
|
! endif
|
||||||
|
!endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Change to suite.
|
# Change to suite.
|
||||||
#
|
#
|
||||||
@@ -229,6 +236,14 @@ $(LINK_ARG): $(__MAKEFILES__)
|
|||||||
!ifdef %use_ares
|
!ifdef %use_ares
|
||||||
@%append $^@ library $(ARES_ROOT)$(DS)cares.lib
|
@%append $^@ library $(ARES_ROOT)$(DS)cares.lib
|
||||||
!endif
|
!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__)
|
$(LIB_ARG): $(__MAKEFILES__)
|
||||||
%create $^@
|
%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 \
|
config-win32ce.h config-os400.h setup-os400.h config-symbian.h \
|
||||||
Makefile.Watcom config-tpf.h $(DOCS) $(VCPROJ) mk-ca-bundle.pl \
|
Makefile.Watcom config-tpf.h $(DOCS) $(VCPROJ) mk-ca-bundle.pl \
|
||||||
mk-ca-bundle.vbs firefox-db2pem.sh $(CMAKE_DIST) config-vxworks.h \
|
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)
|
CLEANFILES = $(DSP) $(VCPROJ)
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ lib_LTLIBRARIES = libcurl.la
|
|||||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||||
|
|
||||||
# This might hold -Werror
|
# 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
|
# 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
|
# $(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
|
# For the full guide on libcurl ABI rules, see docs/libcurl/ABI
|
||||||
|
|
||||||
if NO_UNDEFINED
|
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
|
UNDEF = -no-undefined
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -116,18 +116,18 @@ if MIMPURE
|
|||||||
MIMPURE = -mimpure-text
|
MIMPURE = -mimpure-text
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LINKFLAGS=$(UNDEF) $(MIMPURE) $(LIBCURL_LIBS)
|
libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(LIBCURL_LIBS)
|
||||||
|
|
||||||
libcurl_la_LDFLAGS = $(LINKFLAGS) $(VERSIONINFO)
|
# unit testing static library built only along with unit tests
|
||||||
|
if BUILD_UNITTESTS
|
||||||
# as unit testing will compile and link everything an extra time, we only
|
|
||||||
# do it if debug is enabled
|
|
||||||
if CURLDEBUG
|
|
||||||
noinst_LTLIBRARIES = libcurlu.la
|
noinst_LTLIBRARIES = libcurlu.la
|
||||||
libcurlu_la_CFLAGS = -DUNITTESTS
|
else
|
||||||
libcurlu_la_LDFLAGS = -static $(LINKFLAGS)
|
noinst_LTLIBRARIES =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DUNITTESTS
|
||||||
|
libcurlu_la_LDFLAGS = -static $(LIBCURL_LIBS)
|
||||||
|
|
||||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
include Makefile.inc
|
include Makefile.inc
|
||||||
|
|
||||||
@@ -184,3 +184,12 @@ $(VCPROJ): vc8proj.head vc8proj.foot Makefile.am
|
|||||||
echo "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
|
echo "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
|
||||||
done; \
|
done; \
|
||||||
cat $(srcdir)/vc8proj.foot $(VCPROJOUT) )
|
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,14 +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 \
|
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 \
|
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 \
|
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 \
|
hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \
|
||||||
inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \
|
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \
|
||||||
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \
|
qssl.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||||
socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c \
|
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||||
curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c \
|
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \
|
||||||
warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c\
|
curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \
|
||||||
gopher.c axtls.c idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c \
|
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
|
||||||
non-ascii.c
|
asyn-ares.c asyn-thread.c
|
||||||
|
|
||||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
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 \
|
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||||
@@ -36,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 \
|
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_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 \
|
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 \
|
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
|
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ CCNODBG = cl.exe /O2 /DNDEBUG
|
|||||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
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
|
CFLAGSLIB = /DCURL_STATICLIB
|
||||||
LNKDLL = link.exe /DLL
|
LNKDLL = link.exe /DLL
|
||||||
LNKLIB = link.exe /lib
|
LNKLIB = link.exe /lib
|
||||||
@@ -457,6 +457,8 @@ clean:
|
|||||||
# A config was provided, so the library can be built.
|
# A config was provided, so the library can be built.
|
||||||
#
|
#
|
||||||
X_OBJS= \
|
X_OBJS= \
|
||||||
|
$(DIROBJ)\asyn-ares.obj \
|
||||||
|
$(DIROBJ)\asyn-thread.obj \
|
||||||
$(DIROBJ)\base64.obj \
|
$(DIROBJ)\base64.obj \
|
||||||
$(DIROBJ)\connect.obj \
|
$(DIROBJ)\connect.obj \
|
||||||
$(DIROBJ)\content_encoding.obj \
|
$(DIROBJ)\content_encoding.obj \
|
||||||
@@ -479,17 +481,15 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\ftp.obj \
|
$(DIROBJ)\ftp.obj \
|
||||||
$(DIROBJ)\getenv.obj \
|
$(DIROBJ)\getenv.obj \
|
||||||
$(DIROBJ)\getinfo.obj \
|
$(DIROBJ)\getinfo.obj \
|
||||||
$(DIROBJ)\gtls.obj \
|
|
||||||
$(DIROBJ)\gopher.obj \
|
$(DIROBJ)\gopher.obj \
|
||||||
|
$(DIROBJ)\gtls.obj \
|
||||||
$(DIROBJ)\hash.obj \
|
$(DIROBJ)\hash.obj \
|
||||||
$(DIROBJ)\hmac.obj \
|
$(DIROBJ)\hmac.obj \
|
||||||
$(DIROBJ)\hostares.obj \
|
|
||||||
$(DIROBJ)\hostasyn.obj \
|
$(DIROBJ)\hostasyn.obj \
|
||||||
$(DIROBJ)\hostip4.obj \
|
$(DIROBJ)\hostip4.obj \
|
||||||
$(DIROBJ)\hostip6.obj \
|
$(DIROBJ)\hostip6.obj \
|
||||||
$(DIROBJ)\hostip.obj \
|
$(DIROBJ)\hostip.obj \
|
||||||
$(DIROBJ)\hostsyn.obj \
|
$(DIROBJ)\hostsyn.obj \
|
||||||
$(DIROBJ)\hostthre.obj \
|
|
||||||
$(DIROBJ)\http_chunks.obj \
|
$(DIROBJ)\http_chunks.obj \
|
||||||
$(DIROBJ)\http_digest.obj \
|
$(DIROBJ)\http_digest.obj \
|
||||||
$(DIROBJ)\http_negotiate.obj \
|
$(DIROBJ)\http_negotiate.obj \
|
||||||
|
|||||||
@@ -60,6 +60,14 @@
|
|||||||
#define in_addr_t unsigned long
|
#define in_addr_t unsigned long
|
||||||
#endif
|
#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 "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
@@ -76,18 +84,140 @@
|
|||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#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"
|
#include "curl_memory.h"
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
/***********************************************************************
|
struct ResolverResults {
|
||||||
* Only for ares-enabled builds
|
int num_pending; /* number of ares_gethostbyname() requests */
|
||||||
**********************************************************************/
|
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||||
|
int last_status;
|
||||||
#ifdef CURLRES_ARES
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
* 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
|
* ares. The caller must make sure that this function is only called when we
|
||||||
* have a working ares channel.
|
* have a working ares channel.
|
||||||
@@ -95,22 +225,23 @@
|
|||||||
* Returns: CURLE_OK always!
|
* Returns: CURLE_OK always!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Curl_resolv_getsock(struct connectdata *conn,
|
int Curl_resolver_getsock(struct connectdata *conn,
|
||||||
curl_socket_t *socks,
|
curl_socket_t *socks,
|
||||||
int numsocks)
|
int numsocks)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct timeval maxtime;
|
struct timeval maxtime;
|
||||||
struct timeval timebuf;
|
struct timeval timebuf;
|
||||||
struct timeval *timeout;
|
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);
|
(ares_socket_t *)socks, numsocks);
|
||||||
|
|
||||||
|
|
||||||
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
||||||
maxtime.tv_usec = 0;
|
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,
|
Curl_expire(conn->data,
|
||||||
(timeout->tv_sec * 1000) + (timeout->tv_usec/1000));
|
(timeout->tv_sec * 1000) + (timeout->tv_usec/1000));
|
||||||
@@ -138,7 +269,8 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
|||||||
int i;
|
int i;
|
||||||
int num = 0;
|
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++) {
|
for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||||
pfd[i].events = 0;
|
pfd[i].events = 0;
|
||||||
@@ -165,11 +297,12 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
|||||||
if(!nfds)
|
if(!nfds)
|
||||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||||
above, as otherwise the ares name resolve won't timeout! */
|
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 {
|
else {
|
||||||
/* move through the descriptors and ask for processing on them */
|
/* move through the descriptors and ask for processing on them */
|
||||||
for(i=0; i < num; i++)
|
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].revents & (POLLRDNORM|POLLIN)?
|
||||||
pfd[i].fd:ARES_SOCKET_BAD,
|
pfd[i].fd:ARES_SOCKET_BAD,
|
||||||
pfd[i].revents & (POLLWRNORM|POLLOUT)?
|
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
|
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||||
* request has completed. It should also make sure to time-out if the
|
* name resolve request has completed. It should also make sure to time-out if
|
||||||
* operation seems to take too long.
|
* the operation seems to take too long.
|
||||||
*
|
*
|
||||||
* Returns normal CURLcode errors.
|
* Returns normal CURLcode errors.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **dns)
|
struct Curl_dns_entry **dns)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct ResolverResults *res = (struct ResolverResults *)
|
||||||
|
conn->async.os_specific;
|
||||||
|
|
||||||
*dns = NULL;
|
*dns = NULL;
|
||||||
|
|
||||||
waitperform(conn, 0);
|
waitperform(conn, 0);
|
||||||
|
|
||||||
if(conn->async.done) {
|
if(res && !res->num_pending) {
|
||||||
/* we're done, kill the ares handle */
|
(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) {
|
if(!conn->async.dns) {
|
||||||
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
|
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
|
||||||
ares_strerror(conn->async.status));
|
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
|
* Curl_resolver_wait_resolv()
|
||||||
* be avoided since using this risk getting the multi interface to "hang".
|
*
|
||||||
|
* 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
|
* 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
|
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
CURLcode rc=CURLE_OK;
|
CURLcode rc=CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
long timeout;
|
long timeout;
|
||||||
struct timeval now = Curl_tvnow();
|
struct timeval now = Curl_tvnow();
|
||||||
|
struct Curl_dns_entry *temp_entry;
|
||||||
|
|
||||||
timeout = Curl_timeleft(data, &now, TRUE);
|
timeout = Curl_timeleft(data, &now, TRUE);
|
||||||
if(!timeout)
|
if(!timeout)
|
||||||
@@ -240,7 +382,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
store.tv_sec = itimeout/1000;
|
store.tv_sec = itimeout/1000;
|
||||||
store.tv_usec = (itimeout%1000)*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
|
/* 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
|
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;
|
timeout_ms = 1000;
|
||||||
|
|
||||||
waitperform(conn, timeout_ms);
|
waitperform(conn, timeout_ms);
|
||||||
|
Curl_resolver_is_resolved(conn,&temp_entry);
|
||||||
|
|
||||||
if(conn->async.done)
|
if(conn->async.done)
|
||||||
break;
|
break;
|
||||||
@@ -267,7 +410,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
if(timeout < 0) {
|
if(timeout < 0) {
|
||||||
/* our timeout, so we cancel the ares operation */
|
/* our timeout, so we cancel the ares operation */
|
||||||
ares_cancel(data->state.areschannel);
|
ares_cancel((ares_channel)data->state.resolver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,7 +424,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
/* a name was not resolved */
|
/* a name was not resolved */
|
||||||
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
|
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);
|
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
|
||||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||||
}
|
}
|
||||||
@@ -291,7 +434,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(conn->async.done) {
|
else if(conn->async.done) {
|
||||||
if (conn->bits.httpproxy) {
|
if(conn->bits.httpproxy) {
|
||||||
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
|
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
|
||||||
ares_strerror(conn->async.status));
|
ares_strerror(conn->async.status));
|
||||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||||
@@ -313,53 +456,73 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
return rc;
|
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
|
* ares_query_completed_cb() is the callback that ares will call when
|
||||||
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
||||||
* when using ares, is completed either successfully or with failure.
|
* when using ares, is completed either successfully or with failure.
|
||||||
*/
|
*/
|
||||||
static void ares_query_completed_cb(void *arg, /* (struct connectdata *) */
|
static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||||
int status,
|
int status,
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||||
int timeouts,
|
int timeouts,
|
||||||
#endif
|
#endif
|
||||||
struct hostent *hostent)
|
struct hostent *hostent)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = (struct connectdata *)arg;
|
struct connectdata *conn = (struct connectdata *)arg;
|
||||||
struct Curl_addrinfo * ai = NULL;
|
struct ResolverResults *res;
|
||||||
|
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||||
(void)timeouts; /* ignored */
|
(void)timeouts; /* ignored */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(status) {
|
if(ARES_EDESTRUCTION == status)
|
||||||
case CURL_ASYNC_SUCCESS:
|
/* when this ares handle is getting destroyed, the 'arg' pointer may not
|
||||||
ai = Curl_he2ai(hostent, conn->async.port);
|
be valid so only defer it when we know the 'status' says its fine! */
|
||||||
break;
|
|
||||||
case ARES_EDESTRUCTION:
|
|
||||||
/* this ares handle is getting destroyed, the 'arg' pointer may not be
|
|
||||||
valid! */
|
|
||||||
return;
|
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
|
* Returns name information about the given hostname and port number. If
|
||||||
* successful, the 'hostent' is returned and the forth argument will point to
|
* 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
|
* memory we need to free after use. That memory *MUST* be freed with
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
* Curl_freeaddrinfo(), nothing else.
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
char *bufp;
|
char *bufp;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
@@ -379,10 +542,9 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||||
/* Otherwise, check if this is an IPv6 address string */
|
/* 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. */
|
/* This must be an IPv6 address literal. */
|
||||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||||
}
|
|
||||||
|
|
||||||
switch(conn->ip_version) {
|
switch(conn->ip_version) {
|
||||||
default:
|
default:
|
||||||
@@ -402,34 +564,42 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
#endif /* CURLRES_IPV6 */
|
#endif /* CURLRES_IPV6 */
|
||||||
|
|
||||||
bufp = strdup(hostname);
|
bufp = strdup(hostname);
|
||||||
|
|
||||||
if(bufp) {
|
if(bufp) {
|
||||||
|
struct ResolverResults *res = NULL;
|
||||||
Curl_safefree(conn->async.hostname);
|
Curl_safefree(conn->async.hostname);
|
||||||
conn->async.hostname = bufp;
|
conn->async.hostname = bufp;
|
||||||
conn->async.port = port;
|
conn->async.port = port;
|
||||||
conn->async.done = FALSE; /* not done */
|
conn->async.done = FALSE; /* not done */
|
||||||
conn->async.status = 0; /* clear */
|
conn->async.status = 0; /* clear */
|
||||||
conn->async.dns = NULL; /* 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 */
|
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||||
if(family == PF_UNSPEC) {
|
if(family == PF_UNSPEC) {
|
||||||
conn->async.num_pending = 2;
|
res->num_pending = 2;
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||||
ares_query_completed_cb, conn);
|
PF_INET, query_completed_cb, conn);
|
||||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET6,
|
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||||
ares_query_completed_cb, conn);
|
PF_INET6, query_completed_cb, conn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* CURLRES_IPV6 */
|
#endif /* CURLRES_IPV6 */
|
||||||
{
|
{
|
||||||
conn->async.num_pending = 1;
|
res->num_pending = 1;
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
|
||||||
ares_query_completed_cb, conn);
|
query_completed_cb, conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
*waitp = 1; /* expect asynchronous response */
|
*waitp = 1; /* expect asynchronous response */
|
||||||
@@ -64,6 +64,12 @@
|
|||||||
#define in_addr_t unsigned long
|
#define in_addr_t unsigned long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETADDRINFO
|
||||||
|
# define RESOLVER_ENOMEM EAI_MEMORY
|
||||||
|
#else
|
||||||
|
# define RESOLVER_ENOMEM ENOMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
@@ -88,6 +94,71 @@
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef CURLRES_THREADED
|
#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 */
|
/* This function is used to init a threaded resolve */
|
||||||
static bool init_resolve_thread(struct connectdata *conn,
|
static bool init_resolve_thread(struct connectdata *conn,
|
||||||
const char *hostname, int port,
|
const char *hostname, int port,
|
||||||
@@ -117,7 +188,7 @@ struct thread_data {
|
|||||||
struct thread_sync_data tsd;
|
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);
|
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
|
static
|
||||||
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||||
{
|
{
|
||||||
if (tsd->mtx) {
|
if(tsd->mtx) {
|
||||||
Curl_mutex_destroy(tsd->mtx);
|
Curl_mutex_destroy(tsd->mtx);
|
||||||
free(tsd->mtx);
|
free(tsd->mtx);
|
||||||
}
|
}
|
||||||
@@ -136,7 +207,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
|||||||
if(tsd->hostname)
|
if(tsd->hostname)
|
||||||
free(tsd->hostname);
|
free(tsd->hostname);
|
||||||
|
|
||||||
if (tsd->res)
|
if(tsd->res)
|
||||||
Curl_freeaddrinfo(tsd->res);
|
Curl_freeaddrinfo(tsd->res);
|
||||||
|
|
||||||
memset(tsd,0,sizeof(*tsd));
|
memset(tsd,0,sizeof(*tsd));
|
||||||
@@ -160,7 +231,8 @@ int init_thread_sync_data(struct thread_sync_data * tsd,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
tsd->mtx = malloc(sizeof(curl_mutex_t));
|
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);
|
Curl_mutex_init(tsd->mtx);
|
||||||
|
|
||||||
@@ -170,7 +242,8 @@ int init_thread_sync_data(struct thread_sync_data * tsd,
|
|||||||
* thread during gethostbyname execution.
|
* thread during gethostbyname execution.
|
||||||
*/
|
*/
|
||||||
tsd->hostname = strdup(hostname);
|
tsd->hostname = strdup(hostname);
|
||||||
if (!tsd->hostname) goto err_exit;
|
if(!tsd->hostname)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -186,9 +259,9 @@ static int getaddrinfo_complete(struct connectdata *conn)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
|
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.
|
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
||||||
Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
||||||
*/
|
*/
|
||||||
tsd->res = NULL;
|
tsd->res = NULL;
|
||||||
|
|
||||||
return rc;
|
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);
|
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
|
||||||
|
|
||||||
if (rc != 0) {
|
if(rc != 0) {
|
||||||
tsd->sock_error = SOCKERRNO;
|
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
|
||||||
if (tsd->sock_error == 0)
|
if(tsd->sock_error == 0)
|
||||||
tsd->sock_error = ENOMEM;
|
tsd->sock_error = RESOLVER_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_mutex_acquire(tsd->mtx);
|
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);
|
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
||||||
|
|
||||||
if (!tsd->res) {
|
if(!tsd->res) {
|
||||||
tsd->sock_error = SOCKERRNO;
|
tsd->sock_error = SOCKERRNO;
|
||||||
if (tsd->sock_error == 0)
|
if(tsd->sock_error == 0)
|
||||||
tsd->sock_error = ENOMEM;
|
tsd->sock_error = RESOLVER_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_mutex_acquire(tsd->mtx);
|
Curl_mutex_acquire(tsd->mtx);
|
||||||
@@ -253,10 +326,9 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
|||||||
#endif /* HAVE_GETADDRINFO */
|
#endif /* HAVE_GETADDRINFO */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_destroy_thread_data() cleans up async resolver data and thread handle.
|
* destroy_async_data() cleans up async resolver data and thread handle.
|
||||||
* Complementary of ares_destroy.
|
|
||||||
*/
|
*/
|
||||||
void Curl_destroy_thread_data (struct Curl_async *async)
|
static void destroy_async_data (struct Curl_async *async)
|
||||||
{
|
{
|
||||||
if(async->hostname)
|
if(async->hostname)
|
||||||
free(async->hostname);
|
free(async->hostname);
|
||||||
@@ -264,10 +336,10 @@ void Curl_destroy_thread_data (struct Curl_async *async)
|
|||||||
if(async->os_specific) {
|
if(async->os_specific) {
|
||||||
struct thread_data *td = (struct thread_data*) 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);
|
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);
|
Curl_thread_join(&td->thread_hnd);
|
||||||
|
|
||||||
destroy_thread_sync_data(&td->tsd);
|
destroy_thread_sync_data(&td->tsd);
|
||||||
@@ -289,7 +361,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
|||||||
const struct addrinfo *hints)
|
const struct addrinfo *hints)
|
||||||
{
|
{
|
||||||
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
||||||
int err = ENOMEM;
|
int err = RESOLVER_ENOMEM;
|
||||||
|
|
||||||
conn->async.os_specific = (void*) td;
|
conn->async.os_specific = (void*) td;
|
||||||
if(!td)
|
if(!td)
|
||||||
@@ -302,7 +374,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
|||||||
td->dummy_sock = CURL_SOCKET_BAD;
|
td->dummy_sock = CURL_SOCKET_BAD;
|
||||||
td->thread_hnd = curl_thread_t_null;
|
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;
|
goto err_exit;
|
||||||
|
|
||||||
Curl_safefree(conn->async.hostname);
|
Curl_safefree(conn->async.hostname);
|
||||||
@@ -311,12 +383,12 @@ static bool init_resolve_thread (struct connectdata *conn,
|
|||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
||||||
#ifdef WIN32
|
#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
|
* should never become signalled for read since it's unbound but
|
||||||
* Windows needs at least 1 socket in select().
|
* Windows needs at least 1 socket in select().
|
||||||
*/
|
*/
|
||||||
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
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;
|
goto err_exit;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -336,37 +408,93 @@ static bool init_resolve_thread (struct connectdata *conn,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
Curl_destroy_thread_data(&conn->async);
|
destroy_async_data(&conn->async);
|
||||||
|
|
||||||
SET_ERRNO(err);
|
SET_ERRNO(err);
|
||||||
|
|
||||||
return FALSE;
|
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
|
* resolver_error() calls failf() with the appropriate message after a resolve
|
||||||
* be avoided since using this risk getting the multi interface to "hang".
|
* 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
|
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||||
*
|
*
|
||||||
* This is the version for resolves-in-a-thread.
|
* This is the version for resolves-in-a-thread.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
CURLcode rc = CURLE_OK;
|
CURLcode rc = CURLE_OK;
|
||||||
|
|
||||||
DEBUGASSERT(conn && td);
|
DEBUGASSERT(conn && td);
|
||||||
|
|
||||||
/* wait for the thread to resolve the name */
|
/* 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);
|
rc = getaddrinfo_complete(conn);
|
||||||
} else {
|
else
|
||||||
DEBUGASSERT(0);
|
DEBUGASSERT(0);
|
||||||
}
|
|
||||||
|
|
||||||
conn->async.done = TRUE;
|
conn->async.done = TRUE;
|
||||||
|
|
||||||
@@ -375,18 +503,17 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
/* a name was not resolved */
|
/* a name was not resolved */
|
||||||
if (conn->bits.httpproxy) {
|
if(conn->bits.httpproxy) {
|
||||||
failf(data, "Could not resolve proxy: %s; %s",
|
resolver_error(conn, "proxy");
|
||||||
conn->async.hostname, Curl_strerror(conn, conn->async.status));
|
|
||||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||||
} else {
|
}
|
||||||
failf(data, "Could not resolve host: %s; %s",
|
else {
|
||||||
conn->async.hostname, Curl_strerror(conn, conn->async.status));
|
resolver_error(conn, "host");
|
||||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_destroy_thread_data(&conn->async);
|
destroy_async_data(&conn->async);
|
||||||
|
|
||||||
if(!conn->async.dns)
|
if(!conn->async.dns)
|
||||||
conn->bits.close = TRUE;
|
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
|
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||||
* request has completed. It should also make sure to time-out if the
|
* name resolve request has completed. It should also make sure to time-out if
|
||||||
* operation seems to take too long.
|
* the operation seems to take too long.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||||
@@ -408,7 +535,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
|
|
||||||
*entry = NULL;
|
*entry = NULL;
|
||||||
|
|
||||||
if (!td) {
|
if(!td) {
|
||||||
DEBUGASSERT(td);
|
DEBUGASSERT(td);
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
@@ -417,30 +544,30 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
done = td->tsd.done;
|
done = td->tsd.done;
|
||||||
Curl_mutex_release(td->tsd.mtx);
|
Curl_mutex_release(td->tsd.mtx);
|
||||||
|
|
||||||
if (done) {
|
if(done) {
|
||||||
getaddrinfo_complete(conn);
|
getaddrinfo_complete(conn);
|
||||||
Curl_destroy_thread_data(&conn->async);
|
destroy_async_data(&conn->async);
|
||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
failf(data, "Could not resolve host: %s; %s",
|
resolver_error(conn, "host");
|
||||||
conn->host.name, Curl_strerror(conn, conn->async.status));
|
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
*entry = conn->async.dns;
|
*entry = conn->async.dns;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||||
int elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
int elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
if (elapsed < 0)
|
if(elapsed < 0)
|
||||||
elapsed = 0;
|
elapsed = 0;
|
||||||
|
|
||||||
if (td->poll_interval == 0)
|
if(td->poll_interval == 0)
|
||||||
/* Start at 1ms poll interval */
|
/* Start at 1ms poll interval */
|
||||||
td->poll_interval = 1;
|
td->poll_interval = 1;
|
||||||
else if (elapsed >= td->interval_end)
|
else if(elapsed >= td->interval_end)
|
||||||
/* Back-off exponentially if last interval expired */
|
/* Back-off exponentially if last interval expired */
|
||||||
td->poll_interval *= 2;
|
td->poll_interval *= 2;
|
||||||
|
|
||||||
if (td->poll_interval > 250)
|
if(td->poll_interval > 250)
|
||||||
td->poll_interval = 250;
|
td->poll_interval = 250;
|
||||||
|
|
||||||
td->interval_end = elapsed + td->poll_interval;
|
td->interval_end = elapsed + td->poll_interval;
|
||||||
@@ -450,9 +577,9 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Curl_resolv_getsock(struct connectdata *conn,
|
int Curl_resolver_getsock(struct connectdata *conn,
|
||||||
curl_socket_t *socks,
|
curl_socket_t *socks,
|
||||||
int numsocks)
|
int numsocks)
|
||||||
{
|
{
|
||||||
const struct thread_data *td =
|
const struct thread_data *td =
|
||||||
(const struct thread_data *) conn->async.os_specific;
|
(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_getaddrinfo() - for platforms without getaddrinfo
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
|
|
||||||
@@ -498,19 +625,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
#else /* !HAVE_GETADDRINFO */
|
#else /* !HAVE_GETADDRINFO */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_getaddrinfo() - for getaddrinfo
|
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
Curl_addrinfo *res;
|
Curl_addrinfo *res;
|
||||||
int error;
|
int error;
|
||||||
char sbuf[NI_MAXSERV];
|
char sbuf[NI_MAXSERV];
|
||||||
int pf = PF_INET;
|
int pf = PF_INET;
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
*waitp = 0; /* default to synchronous response */
|
||||||
|
|
||||||
@@ -549,12 +675,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fall-back to blocking version */
|
/* 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));
|
hostname, Curl_strerror(conn, ERRNO));
|
||||||
|
|
||||||
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
|
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
|
||||||
if(error) {
|
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));
|
hostname, port, Curl_strerror(conn, SOCKERRNO));
|
||||||
return NULL;
|
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)
|
static CURLcode map_error_to_curl(int axtls_err)
|
||||||
{
|
{
|
||||||
switch (axtls_err)
|
switch (axtls_err) {
|
||||||
{
|
|
||||||
case SSL_ERROR_NOT_SUPPORTED:
|
case SSL_ERROR_NOT_SUPPORTED:
|
||||||
case SSL_ERROR_INVALID_VERSION:
|
case SSL_ERROR_INVALID_VERSION:
|
||||||
case -70: /* protocol version alert from server */
|
case -70: /* protocol version alert from server */
|
||||||
@@ -416,7 +415,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
|||||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
||||||
sizeof(buf));
|
sizeof(buf));
|
||||||
|
|
||||||
if (nread < SSL_OK){
|
if(nread < SSL_OK){
|
||||||
failf(data, "close notify alert not received during shutdown");
|
failf(data, "close notify alert not received during shutdown");
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
11
lib/base64.c
11
lib/base64.c
@@ -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
|
* Given a base64 string at src, decode it and return an allocated memory in
|
||||||
* the *outptr. Returns the length of the decoded data.
|
* the *outptr. Returns the length of the decoded data.
|
||||||
|
*
|
||||||
|
* @unittest: 1302
|
||||||
*/
|
*/
|
||||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||||
{
|
{
|
||||||
@@ -135,11 +137,13 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
|||||||
* is a pointer to an allocated area holding the base64 data. If something
|
* is a pointer to an allocated area holding the base64 data. If something
|
||||||
* went wrong, 0 is returned.
|
* went wrong, 0 is returned.
|
||||||
*
|
*
|
||||||
|
* @unittest: 1302
|
||||||
*/
|
*/
|
||||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||||
const char *inputbuff, size_t insize,
|
const char *inputbuff, size_t insize,
|
||||||
char **outptr)
|
char **outptr)
|
||||||
{
|
{
|
||||||
|
CURLcode res;
|
||||||
unsigned char ibuf[3];
|
unsigned char ibuf[3];
|
||||||
unsigned char obuf[4];
|
unsigned char obuf[4];
|
||||||
int i;
|
int i;
|
||||||
@@ -164,14 +168,17 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
|||||||
* not the host encoding. And we can't change the actual input
|
* 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.
|
* so we copy it to a buffer, translate it, and use that instead.
|
||||||
*/
|
*/
|
||||||
if(Curl_convert_clone(data, indata, insize, &convbuf))
|
res = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||||
|
if(res) {
|
||||||
|
free(output);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(convbuf)
|
if(convbuf)
|
||||||
indata = (char *)convbuf;
|
indata = (char *)convbuf;
|
||||||
|
|
||||||
while(insize > 0) {
|
while(insize > 0) {
|
||||||
for (i = inputparts = 0; i < 3; i++) {
|
for(i = inputparts = 0; i < 3; i++) {
|
||||||
if(insize > 0) {
|
if(insize > 0) {
|
||||||
inputparts++;
|
inputparts++;
|
||||||
ibuf[i] = (unsigned char) *indata;
|
ibuf[i] = (unsigned char) *indata;
|
||||||
|
|||||||
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 "inet_pton.h"
|
||||||
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
|
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
|
#include "warnless.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@@ -130,6 +131,8 @@ singleipconnect(struct connectdata *conn,
|
|||||||
* If 'nowp' is non-NULL, it points to the current time.
|
* If 'nowp' is non-NULL, it points to the current time.
|
||||||
* 'duringconnect' is FALSE if not during a connect, as then of course the
|
* 'duringconnect' is FALSE if not during a connect, as then of course the
|
||||||
* connect timeout is not taken into account!
|
* connect timeout is not taken into account!
|
||||||
|
*
|
||||||
|
* @unittest: 1303
|
||||||
*/
|
*/
|
||||||
long Curl_timeleft(struct SessionHandle *data,
|
long Curl_timeleft(struct SessionHandle *data,
|
||||||
struct timeval *nowp,
|
struct timeval *nowp,
|
||||||
@@ -210,8 +213,8 @@ int waitconnect(struct connectdata *conn,
|
|||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
/* now select() until we get connect or timeout */
|
/* now select() until we get connect or timeout */
|
||||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, (int)(timeout_msec>1000?
|
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, timeout_msec>1000?
|
||||||
1000:timeout_msec));
|
1000:timeout_msec);
|
||||||
if(Curl_pgrsUpdate(conn))
|
if(Curl_pgrsUpdate(conn))
|
||||||
return WAITCONN_ABORTED;
|
return WAITCONN_ABORTED;
|
||||||
|
|
||||||
@@ -263,7 +266,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Select device to bind socket to
|
* Select device to bind socket to
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
if ( !dev && !port )
|
if(!dev && !port)
|
||||||
/* no local kind of binding was requested */
|
/* no local kind of binding was requested */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
@@ -315,16 +318,16 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
long ipver = conn->ip_version;
|
long ipver = conn->ip_version;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (af == AF_INET)
|
if(af == AF_INET)
|
||||||
conn->ip_version = CURL_IPRESOLVE_V4;
|
conn->ip_version = CURL_IPRESOLVE_V4;
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
else if (af == AF_INET6)
|
else if(af == AF_INET6)
|
||||||
conn->ip_version = CURL_IPRESOLVE_V6;
|
conn->ip_version = CURL_IPRESOLVE_V6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = Curl_resolv(conn, dev, 0, &h);
|
rc = Curl_resolv(conn, dev, 0, &h);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
(void)Curl_wait_for_resolv(conn, &h);
|
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||||
conn->ip_version = ipver;
|
conn->ip_version = ipver;
|
||||||
|
|
||||||
if(h) {
|
if(h) {
|
||||||
@@ -372,14 +375,14 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
else {
|
else {
|
||||||
/* no device was given, prepare sa to match af's needs */
|
/* no device was given, prepare sa to match af's needs */
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if ( af == AF_INET6 ) {
|
if(af == AF_INET6) {
|
||||||
si6->sin6_family = AF_INET6;
|
si6->sin6_family = AF_INET6;
|
||||||
si6->sin6_port = htons(port);
|
si6->sin6_port = htons(port);
|
||||||
sizeof_sa = sizeof(struct sockaddr_in6);
|
sizeof_sa = sizeof(struct sockaddr_in6);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if ( af == AF_INET ) {
|
if(af == AF_INET) {
|
||||||
si4->sin_family = AF_INET;
|
si4->sin_family = AF_INET;
|
||||||
si4->sin_port = htons(port);
|
si4->sin_port = htons(port);
|
||||||
sizeof_sa = sizeof(struct sockaddr_in);
|
sizeof_sa = sizeof(struct sockaddr_in);
|
||||||
@@ -387,8 +390,8 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if( bind(sockfd, sock, sizeof_sa) >= 0) {
|
if(bind(sockfd, sock, sizeof_sa) >= 0) {
|
||||||
/* we succeeded to bind */
|
/* we succeeded to bind */
|
||||||
struct Curl_sockaddr_storage add;
|
struct Curl_sockaddr_storage add;
|
||||||
curl_socklen_t size = sizeof(add);
|
curl_socklen_t size = sizeof(add);
|
||||||
memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
|
memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
|
||||||
@@ -510,7 +513,7 @@ static CURLcode trynextip(struct connectdata *conn,
|
|||||||
*connected = FALSE;
|
*connected = FALSE;
|
||||||
|
|
||||||
if(sockindex != FIRSTSOCKET) {
|
if(sockindex != FIRSTSOCKET) {
|
||||||
sclose(fd_to_close);
|
Curl_closesocket(conn, fd_to_close);
|
||||||
return CURLE_COULDNT_CONNECT; /* no next */
|
return CURLE_COULDNT_CONNECT; /* no next */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,12 +528,12 @@ static CURLcode trynextip(struct connectdata *conn,
|
|||||||
/* store the new socket descriptor */
|
/* store the new socket descriptor */
|
||||||
conn->sock[sockindex] = sockfd;
|
conn->sock[sockindex] = sockfd;
|
||||||
conn->ip_addr = ai;
|
conn->ip_addr = ai;
|
||||||
sclose(fd_to_close);
|
Curl_closesocket(conn, fd_to_close);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
ai = ai->ai_next;
|
ai = ai->ai_next;
|
||||||
}
|
}
|
||||||
sclose(fd_to_close);
|
Curl_closesocket(conn, fd_to_close);
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,7 +701,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
|
|
||||||
if(WAITCONN_CONNECTED == rc) {
|
if(WAITCONN_CONNECTED == rc) {
|
||||||
if(verifyconnect(sockfd, &error)) {
|
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;
|
conn->bits.tcpconnect = TRUE;
|
||||||
*connected = TRUE;
|
*connected = TRUE;
|
||||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||||
@@ -809,8 +818,8 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
|||||||
int curval = 0;
|
int curval = 0;
|
||||||
int curlen = sizeof(curval);
|
int curlen = sizeof(curval);
|
||||||
|
|
||||||
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
|
if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
|
||||||
if (curval > val)
|
if(curval > val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
|
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
|
||||||
@@ -888,7 +897,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
#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;
|
sa6->sin6_scope_id = conn->scope;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -899,7 +908,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||||
error, Curl_strerror(conn, error));
|
error, Curl_strerror(conn, error));
|
||||||
sclose(sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
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)
|
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
|
||||||
isconnected = TRUE;
|
isconnected = TRUE;
|
||||||
else if(error) {
|
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;
|
return CURLE_ABORTED_BY_CALLBACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,7 +945,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
/* possibly bind the local end to an IP, interface or port */
|
/* possibly bind the local end to an IP, interface or port */
|
||||||
res = bindlocal(conn, sockfd, addr.family);
|
res = bindlocal(conn, sockfd, addr.family);
|
||||||
if(res) {
|
if(res) {
|
||||||
sclose(sockfd); /* close socket and bail out */
|
Curl_closesocket(conn, sockfd); /* close socket and bail out */
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,7 +979,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
rc = waitconnect(conn, sockfd, timeout_ms);
|
rc = waitconnect(conn, sockfd, timeout_ms);
|
||||||
if(WAITCONN_ABORTED == rc) {
|
if(WAITCONN_ABORTED == rc) {
|
||||||
sclose(sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
return CURLE_ABORTED_BY_CALLBACK;
|
return CURLE_ABORTED_BY_CALLBACK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1011,7 +1020,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* connect failed or timed out */
|
/* connect failed or timed out */
|
||||||
sclose(sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -1067,8 +1076,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
/*
|
/*
|
||||||
* Connecting with a Curl_addrinfo chain
|
* Connecting with a Curl_addrinfo chain
|
||||||
*/
|
*/
|
||||||
for (curr_addr = ai, aliasindex=0; curr_addr;
|
for(curr_addr = ai, aliasindex=0; curr_addr;
|
||||||
curr_addr = curr_addr->ai_next, aliasindex++) {
|
curr_addr = curr_addr->ai_next, aliasindex++) {
|
||||||
|
|
||||||
/* start connecting to the IP curr_addr points to */
|
/* start connecting to the IP curr_addr points to */
|
||||||
CURLcode res =
|
CURLcode res =
|
||||||
@@ -1157,3 +1166,17 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
|||||||
|
|
||||||
return sockfd;
|
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
|
#endif
|
||||||
|
|
||||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||||
|
|
||||||
void Curl_persistconninfo(struct connectdata *conn);
|
void Curl_persistconninfo(struct connectdata *conn);
|
||||||
|
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||||
#endif
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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
|
/* because the buffer size is fixed, iteratively decompress and transfer to
|
||||||
the client via client_write. */
|
the client via client_write. */
|
||||||
for (;;) {
|
for(;;) {
|
||||||
/* (re)set buffer for decompressed output for every iteration */
|
/* (re)set buffer for decompressed output for every iteration */
|
||||||
z->next_out = (Bytef *)decomp;
|
z->next_out = (Bytef *)decomp;
|
||||||
z->avail_out = DSIZ;
|
z->avail_out = DSIZ;
|
||||||
|
|||||||
27
lib/cookie.c
27
lib/cookie.c
@@ -84,7 +84,7 @@ Example set of cookies:
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 <curl/mprintf.h>
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
@@ -101,7 +101,6 @@ Example set of cookies:
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
|
||||||
static void freecookie(struct Cookie *co)
|
static void freecookie(struct Cookie *co)
|
||||||
{
|
{
|
||||||
if(co->expirestr)
|
if(co->expirestr)
|
||||||
@@ -371,10 +370,10 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
/* Session cookies have expires set to 0 so if we get that back
|
/* 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
|
from the date parser let's add a second to make it a
|
||||||
non-session cookie */
|
non-session cookie */
|
||||||
if (co->expires == 0)
|
if(co->expires == 0)
|
||||||
co->expires = 1;
|
co->expires = 1;
|
||||||
else if( co->expires < 0 )
|
else if(co->expires < 0)
|
||||||
co->expires = 0;
|
co->expires = 0;
|
||||||
}
|
}
|
||||||
else if(!co->name) {
|
else if(!co->name) {
|
||||||
co->name = strdup(name);
|
co->name = strdup(name);
|
||||||
@@ -398,7 +397,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
if(Curl_raw_equal("secure", what)) {
|
if(Curl_raw_equal("secure", what)) {
|
||||||
co->secure = TRUE;
|
co->secure = TRUE;
|
||||||
}
|
}
|
||||||
else if (Curl_raw_equal("httponly", what)) {
|
else if(Curl_raw_equal("httponly", what)) {
|
||||||
co->httponly = TRUE;
|
co->httponly = TRUE;
|
||||||
}
|
}
|
||||||
/* else,
|
/* else,
|
||||||
@@ -482,7 +481,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
lines are preceded 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..
|
as usual, so we skip 10 characters of the line..
|
||||||
*/
|
*/
|
||||||
if (strncmp(lineptr, "#HttpOnly_", 10) == 0) {
|
if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
|
||||||
lineptr += 10;
|
lineptr += 10;
|
||||||
co->httponly = TRUE;
|
co->httponly = TRUE;
|
||||||
}
|
}
|
||||||
@@ -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
|
As far as I can see, it is set to true when the cookie says
|
||||||
.domain.com and to false when the domain is complete www.domain.com
|
.domain.com and to false when the domain is complete www.domain.com
|
||||||
*/
|
*/
|
||||||
co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE"); /* store information */
|
co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* It turns out, that sometimes the file format allows the path
|
/* It turns out, that sometimes the file format allows the path
|
||||||
@@ -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
|
/* 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
|
date AND that if the cookie requires we're secure we must only
|
||||||
continue if we are! */
|
continue if we are! */
|
||||||
if( (!co->expires || (co->expires > now)) &&
|
if((!co->expires || (co->expires > now)) &&
|
||||||
(co->secure?secure:TRUE) ) {
|
(co->secure?secure:TRUE)) {
|
||||||
|
|
||||||
/* now check if the domain is correct */
|
/* now check if the domain is correct */
|
||||||
if(!co->domain ||
|
if(!co->domain ||
|
||||||
@@ -877,7 +876,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* alloc an array and store all cookie pointers */
|
/* alloc an array and store all cookie pointers */
|
||||||
array = (struct Cookie **)malloc(sizeof(struct Cookie *) * matches);
|
array = malloc(sizeof(struct Cookie *) * matches);
|
||||||
if(!array)
|
if(!array)
|
||||||
goto fail;
|
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
|
* Writes all internally known cookies to the specified file. Specify
|
||||||
* "-" as file name to write to stdout.
|
* "-" as file name to write to stdout.
|
||||||
*
|
*
|
||||||
* The function returns non-zero on write failure.
|
* 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;
|
struct Cookie *co;
|
||||||
FILE *out;
|
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);
|
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 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",
|
infof(data, "WARNING: failed to save cookies in %s\n",
|
||||||
data->set.str[STRING_COOKIEJAR]);
|
data->set.str[STRING_COOKIEJAR]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef __COOKIE_H
|
#ifndef HEADER_CURL_COOKIE_H
|
||||||
#define __COOKIE_H
|
#define HEADER_CURL_COOKIE_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* 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_freelist(struct Cookie *cookies, bool cookiestoo);
|
||||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||||
void Curl_cookie_clearsess(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)
|
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||||
#define Curl_cookie_list(x) NULL
|
#define Curl_cookie_list(x) NULL
|
||||||
#define Curl_cookie_loadfiles(x) do { } while (0)
|
#define Curl_cookie_loadfiles(x) do { } while (0)
|
||||||
#define Curl_cookie_init(x,y,z,w) NULL
|
#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)
|
#define Curl_flush_cookies(x,y)
|
||||||
#else
|
#else
|
||||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
|
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);
|
void Curl_cookie_loadfiles(struct SessionHandle *data);
|
||||||
#endif
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
#include "curl_addrinfo.h"
|
#include "curl_addrinfo.h"
|
||||||
#include "inet_pton.h"
|
#include "inet_pton.h"
|
||||||
|
#include "warnless.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -294,7 +295,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
|||||||
|
|
||||||
size_t ss_size;
|
size_t ss_size;
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if (he->h_addrtype == AF_INET6)
|
if(he->h_addrtype == AF_INET6)
|
||||||
ss_size = sizeof (struct sockaddr_in6);
|
ss_size = sizeof (struct sockaddr_in6);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
/* lib/curl_config.h.in. Generated from configure.ac by autoheader. */
|
/* 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 */
|
/* when building libcurl itself */
|
||||||
#cmakedefine BUILDING_LIBCURL ${BUILDING_LIBCURL}
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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 };
|
unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
for (;;) {
|
for(;;) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case CURLFNM_LOOP_DEFAULT:
|
case CURLFNM_LOOP_DEFAULT:
|
||||||
if(*p == '*') {
|
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)
|
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||||
{
|
{
|
||||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
(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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
p += n - 1;
|
||||||
|
|
||||||
while (p >= q) {
|
while(p >= q) {
|
||||||
if (*p == (unsigned char)c)
|
if(*p == (unsigned char)c)
|
||||||
return (void *)p;
|
return (void *)p;
|
||||||
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_do(struct connectdata *conn, bool *done);
|
||||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
|
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_recv rtmp_recv;
|
||||||
static Curl_send rtmp_send;
|
static Curl_send rtmp_send;
|
||||||
@@ -73,6 +73,7 @@ const struct Curl_handler Curl_handler_rtmp = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMP, /* defport */
|
PORT_RTMP, /* defport */
|
||||||
CURLPROTO_RTMP, /* protocol */
|
CURLPROTO_RTMP, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
@@ -91,6 +92,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMPT, /* defport */
|
PORT_RTMPT, /* defport */
|
||||||
CURLPROTO_RTMPT, /* protocol */
|
CURLPROTO_RTMPT, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
@@ -109,6 +111,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMP, /* defport */
|
PORT_RTMP, /* defport */
|
||||||
CURLPROTO_RTMPE, /* protocol */
|
CURLPROTO_RTMPE, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
@@ -127,6 +130,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMPT, /* defport */
|
PORT_RTMPT, /* defport */
|
||||||
CURLPROTO_RTMPTE, /* protocol */
|
CURLPROTO_RTMPTE, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
@@ -145,10 +149,12 @@ const struct Curl_handler Curl_handler_rtmps = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMPS, /* defport */
|
PORT_RTMPS, /* defport */
|
||||||
CURLPROTO_RTMPS, /* protocol */
|
CURLPROTO_RTMPS, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct Curl_handler Curl_handler_rtmpts = {
|
const struct Curl_handler Curl_handler_rtmpts = {
|
||||||
"RTMPTS", /* scheme */
|
"RTMPTS", /* scheme */
|
||||||
rtmp_setup, /* setup_connection */
|
rtmp_setup, /* setup_connection */
|
||||||
@@ -162,6 +168,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
rtmp_disconnect, /* disconnect */
|
rtmp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_RTMPS, /* defport */
|
PORT_RTMPS, /* defport */
|
||||||
CURLPROTO_RTMPTS, /* protocol */
|
CURLPROTO_RTMPTS, /* protocol */
|
||||||
PROTOPT_NONE /* flags*/
|
PROTOPT_NONE /* flags*/
|
||||||
@@ -171,12 +178,12 @@ static CURLcode rtmp_setup(struct connectdata *conn)
|
|||||||
{
|
{
|
||||||
RTMP *r = RTMP_Alloc();
|
RTMP *r = RTMP_Alloc();
|
||||||
|
|
||||||
if (!r)
|
if(!r)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
RTMP_Init(r);
|
RTMP_Init(r);
|
||||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||||
if (!RTMP_SetupURL(r, conn->data->change.url)) {
|
if(!RTMP_SetupURL(r, conn->data->change.url)) {
|
||||||
RTMP_Free(r);
|
RTMP_Free(r);
|
||||||
return CURLE_URL_MALFORMAT;
|
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
|
/* We have to know if it's a write before we send the
|
||||||
* connect request packet
|
* connect request packet
|
||||||
*/
|
*/
|
||||||
if (conn->data->set.upload)
|
if(conn->data->set.upload)
|
||||||
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
||||||
|
|
||||||
/* For plain streams, use the buffer toggle trick to keep data flowing */
|
/* 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;
|
r->Link.lFlags |= RTMP_LF_BUFX;
|
||||||
|
|
||||||
curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
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;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
/* Clients must send a periodic BytesReceived report to the server */
|
/* 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;
|
RTMP *r = conn->proto.generic;
|
||||||
|
|
||||||
if (!RTMP_ConnectStream(r, 0))
|
if(!RTMP_ConnectStream(r, 0))
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
if (conn->data->set.upload) {
|
if(conn->data->set.upload) {
|
||||||
Curl_pgrsSetUploadSize(conn->data, conn->data->set.infilesize);
|
Curl_pgrsSetUploadSize(conn->data, conn->data->set.infilesize);
|
||||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
||||||
*done = TRUE;
|
*done = TRUE;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -247,7 +257,7 @@ static CURLcode rtmp_disconnect(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
RTMP *r = conn->proto.generic;
|
RTMP *r = conn->proto.generic;
|
||||||
(void)dead_connection;
|
(void)dead_connection;
|
||||||
if (r) {
|
if(r) {
|
||||||
conn->proto.generic = NULL;
|
conn->proto.generic = NULL;
|
||||||
RTMP_Close(r);
|
RTMP_Close(r);
|
||||||
RTMP_Free(r);
|
RTMP_Free(r);
|
||||||
@@ -264,12 +274,13 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
(void)sockindex; /* unused */
|
(void)sockindex; /* unused */
|
||||||
|
|
||||||
nread = RTMP_Read(r, buf, len);
|
nread = RTMP_Read(r, buf, len);
|
||||||
if (nread < 0) {
|
if(nread < 0) {
|
||||||
if (r->m_read.status == RTMP_READ_COMPLETE ||
|
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||||
r->m_read.status == RTMP_READ_EOF) {
|
r->m_read.status == RTMP_READ_EOF) {
|
||||||
conn->data->req.size = conn->data->req.bytecount;
|
conn->data->req.size = conn->data->req.bytecount;
|
||||||
nread = 0;
|
nread = 0;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
*err = CURLE_RECV_ERROR;
|
*err = CURLE_RECV_ERROR;
|
||||||
}
|
}
|
||||||
return nread;
|
return nread;
|
||||||
@@ -284,9 +295,9 @@ static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
|
|||||||
(void)sockindex; /* unused */
|
(void)sockindex; /* unused */
|
||||||
|
|
||||||
num = RTMP_Write(r, (char *)buf, len);
|
num = RTMP_Write(r, (char *)buf, len);
|
||||||
if (num < 0) {
|
if(num < 0)
|
||||||
*err = CURLE_SEND_ERROR;
|
*err = CURLE_SEND_ERROR;
|
||||||
}
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
#endif /* USE_LIBRTMP */
|
#endif /* USE_LIBRTMP */
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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)
|
#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
|
#ifdef _WIN32_WCE
|
||||||
return CreateThread(NULL, 0, func, arg, 0, NULL);
|
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;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_FILESYSTEM
|
||||||
/* load trusted cacert */
|
/* load trusted cacert */
|
||||||
if(data->set.str[STRING_SSL_CAFILE]) {
|
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||||
if (!SSL_CTX_load_verify_locations(conssl->ctx,
|
if(!SSL_CTX_load_verify_locations(conssl->ctx,
|
||||||
data->set.str[STRING_SSL_CAFILE],
|
data->set.str[STRING_SSL_CAFILE],
|
||||||
data->set.str[STRING_SSL_CAPATH])) {
|
data->set.str[STRING_SSL_CAPATH])) {
|
||||||
if (data->set.ssl.verifypeer) {
|
if(data->set.ssl.verifypeer) {
|
||||||
/* Fail if we insiste on successfully verifying the server. */
|
/* Fail if we insiste on successfully verifying the server. */
|
||||||
failf(data,"error setting certificate verify locations:\n"
|
failf(data,"error setting certificate verify locations:\n"
|
||||||
" CAfile: %s\n CApath: %s\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]) {
|
if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
|
||||||
int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
|
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) {
|
file_type) != 1) {
|
||||||
failf(data, "unable to use client certificate (no key or wrong pass"
|
failf(data, "unable to use client certificate (no key or wrong pass"
|
||||||
" phrase?)");
|
" phrase?)");
|
||||||
@@ -169,12 +170,17 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
|
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) {
|
file_type) != 1) {
|
||||||
failf(data, "unable to set private key");
|
failf(data, "unable to set private key");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
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
|
/* 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
|
* fail to connect if the verification fails, or if it should continue
|
||||||
@@ -185,10 +191,10 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Let's make an SSL structure */
|
/* Let's make an SSL structure */
|
||||||
if (conssl->handle)
|
if(conssl->handle)
|
||||||
SSL_free(conssl->handle);
|
SSL_free(conssl->handle);
|
||||||
conssl->handle = SSL_new(conssl->ctx);
|
conssl->handle = SSL_new(conssl->ctx);
|
||||||
if (!conssl->handle) {
|
if(!conssl->handle) {
|
||||||
failf(data, "SSL: couldn't create a context (handle)!");
|
failf(data, "SSL: couldn't create a context (handle)!");
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -206,7 +212,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* pass the raw socket into the SSL layer */
|
/* 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");
|
failf(data, "SSL: SSL_set_fd failed");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -231,16 +237,16 @@ cyassl_connect_step2(struct connectdata *conn,
|
|||||||
conn->send[sockindex] = cyassl_send;
|
conn->send[sockindex] = cyassl_send;
|
||||||
|
|
||||||
ret = SSL_connect(conssl->handle);
|
ret = SSL_connect(conssl->handle);
|
||||||
if (ret != 1) {
|
if(ret != 1) {
|
||||||
char error_buffer[80];
|
char error_buffer[80];
|
||||||
int detail = SSL_get_error(conssl->handle, ret);
|
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;
|
conssl->connecting_state = ssl_connect_2_reading;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_ERROR_WANT_WRITE == detail) {
|
if(SSL_ERROR_WANT_WRITE == detail) {
|
||||||
conssl->connecting_state = ssl_connect_2_writing;
|
conssl->connecting_state = ssl_connect_2_writing;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -273,14 +279,14 @@ cyassl_connect_step3(struct connectdata *conn,
|
|||||||
our_ssl_sessionid = SSL_get_session(connssl->handle);
|
our_ssl_sessionid = SSL_get_session(connssl->handle);
|
||||||
|
|
||||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||||
if (incache) {
|
if(incache) {
|
||||||
if (old_ssl_sessionid != our_ssl_sessionid) {
|
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||||
infof(data, "old SSL session ID is stale, removing\n");
|
infof(data, "old SSL session ID is stale, removing\n");
|
||||||
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||||
incache = FALSE;
|
incache = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!incache) {
|
if(!incache) {
|
||||||
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
||||||
0 /* unknown size */);
|
0 /* unknown size */);
|
||||||
if(retcode) {
|
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 memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||||
int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
|
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);
|
int err = SSL_get_error(conn->ssl[sockindex].handle, rc);
|
||||||
|
|
||||||
switch(err) {
|
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 buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
|
||||||
int nread = SSL_read(conn->ssl[num].handle, buf, buffsize);
|
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);
|
int err = SSL_get_error(conn->ssl[num].handle, nread);
|
||||||
|
|
||||||
switch(err) {
|
switch(err) {
|
||||||
@@ -405,7 +411,7 @@ int Curl_cyassl_init(void)
|
|||||||
|
|
||||||
bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex)
|
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));
|
return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -484,8 +490,7 @@ cyassl_connect_common(struct connectdata *conn,
|
|||||||
curl_socket_t readfd = ssl_connect_2_reading==
|
curl_socket_t readfd = ssl_connect_2_reading==
|
||||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||||
|
|
||||||
what = Curl_socket_ready(readfd, writefd,
|
what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
|
||||||
nonblocking?0:(int)timeout_ms);
|
|
||||||
if(what < 0) {
|
if(what < 0) {
|
||||||
/* fatal error */
|
/* fatal error */
|
||||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
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, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_DICT, /* defport */
|
PORT_DICT, /* defport */
|
||||||
CURLPROTO_DICT, /* protocol */
|
CURLPROTO_DICT, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -279,7 +280,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
ppath++;
|
ppath++;
|
||||||
for (i = 0; ppath[i]; i++) {
|
for(i = 0; ppath[i]; i++) {
|
||||||
if(ppath[i] == ':')
|
if(ppath[i] == ':')
|
||||||
ppath[i] = ' ';
|
ppath[i] = ' ';
|
||||||
}
|
}
|
||||||
|
|||||||
33
lib/easy.c
33
lib/easy.c
@@ -86,6 +86,7 @@
|
|||||||
#include "slist.h"
|
#include "slist.h"
|
||||||
#include "curl_rand.h"
|
#include "curl_rand.h"
|
||||||
#include "non-ascii.h"
|
#include "non-ascii.h"
|
||||||
|
#include "warnless.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -133,8 +134,8 @@ static CURLcode win32_init(void)
|
|||||||
/* wVersionRequested in wVersion. wHighVersion contains the */
|
/* wVersionRequested in wVersion. wHighVersion contains the */
|
||||||
/* highest supported version. */
|
/* highest supported version. */
|
||||||
|
|
||||||
if( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
||||||
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
||||||
/* Tell the user that we couldn't find a useable */
|
/* Tell the user that we couldn't find a useable */
|
||||||
|
|
||||||
/* winsock.dll. */
|
/* winsock.dll. */
|
||||||
@@ -147,7 +148,7 @@ static CURLcode win32_init(void)
|
|||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
{
|
{
|
||||||
CURLcode err = Curl_sspi_global_init();
|
CURLcode err = Curl_sspi_global_init();
|
||||||
if (err != CURLE_OK)
|
if(err != CURLE_OK)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -269,12 +270,10 @@ CURLcode curl_global_init(long flags)
|
|||||||
idna_init();
|
idna_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
if(Curl_resolver_global_init() != CURLE_OK) {
|
||||||
if(ares_library_init(ARES_LIB_INIT_ALL)) {
|
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||||
DEBUGF(fprintf(stderr, "Error: ares_library_init failed\n"));
|
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
|
#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
|
||||||
if(libssh2_init(0)) {
|
if(libssh2_init(0)) {
|
||||||
@@ -307,7 +306,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
|||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
/* Already initialized, don't do it again */
|
/* Already initialized, don't do it again */
|
||||||
if( initialized )
|
if(initialized)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
/* Call the actual init function first */
|
/* Call the actual init function first */
|
||||||
@@ -340,9 +339,7 @@ void curl_global_cleanup(void)
|
|||||||
if(init_flags & CURL_GLOBAL_SSL)
|
if(init_flags & CURL_GLOBAL_SSL)
|
||||||
Curl_ssl_cleanup();
|
Curl_ssl_cleanup();
|
||||||
|
|
||||||
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
|
Curl_resolver_global_cleanup();
|
||||||
ares_library_cleanup();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(init_flags & CURL_GLOBAL_WIN32)
|
if(init_flags & CURL_GLOBAL_WIN32)
|
||||||
win32_cleanup();
|
win32_cleanup();
|
||||||
@@ -510,7 +507,7 @@ CURLcode curl_easy_perform(CURL *curl)
|
|||||||
if(!data)
|
if(!data)
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
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 */
|
/* this handle is not using a shared dns cache */
|
||||||
|
|
||||||
if(data->set.global_dns_cache &&
|
if(data->set.global_dns_cache &&
|
||||||
@@ -676,12 +673,10 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
|||||||
outcurl->change.referer_alloc = TRUE;
|
outcurl->change.referer_alloc = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ARES
|
/* Clone the resolver handle, if present, for the new handle */
|
||||||
/* If we use ares, we clone the ares channel for the new handle */
|
if(Curl_resolver_duphandle(&outcurl->state.resolver,
|
||||||
if(ARES_SUCCESS != ares_dup(&outcurl->state.areschannel,
|
data->state.resolver) != CURLE_OK)
|
||||||
data->state.areschannel))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
|
||||||
|
|
||||||
Curl_convert_setup(outcurl);
|
Curl_convert_setup(outcurl);
|
||||||
|
|
||||||
@@ -770,8 +765,8 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
|||||||
k->keepon = newstate;
|
k->keepon = newstate;
|
||||||
|
|
||||||
if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
|
if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
|
||||||
/* we have a buffer for sending that we now seem to be able to deliver since
|
/* we have a buffer for sending that we now seem to be able to deliver
|
||||||
the receive pausing is lifted! */
|
since the receive pausing is lifted! */
|
||||||
|
|
||||||
/* get the pointer, type and length in local copies since the function may
|
/* 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
|
return PAUSE again and then we'll get a new copy allocted and stored in
|
||||||
|
|||||||
11
lib/escape.c
11
lib/escape.c
@@ -89,6 +89,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
|||||||
size_t newlen = alloc;
|
size_t newlen = alloc;
|
||||||
int strindex=0;
|
int strindex=0;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
ns = malloc(alloc);
|
ns = malloc(alloc);
|
||||||
if(!ns)
|
if(!ns)
|
||||||
@@ -98,10 +99,9 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
|||||||
while(length--) {
|
while(length--) {
|
||||||
in = *string;
|
in = *string;
|
||||||
|
|
||||||
if (Curl_isunreserved(in)) {
|
if(Curl_isunreserved(in))
|
||||||
/* just copy this */
|
/* just copy this */
|
||||||
ns[strindex++]=in;
|
ns[strindex++]=in;
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
/* encode it */
|
/* encode it */
|
||||||
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
||||||
@@ -117,7 +117,8 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Curl_convert_to_network(handle, &in, 1)) {
|
res = Curl_convert_to_network(handle, &in, 1);
|
||||||
|
if(res) {
|
||||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||||
free(ns);
|
free(ns);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -147,6 +148,7 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
|||||||
unsigned char in;
|
unsigned char in;
|
||||||
int strindex=0;
|
int strindex=0;
|
||||||
unsigned long hex;
|
unsigned long hex;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
if(!ns)
|
if(!ns)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -165,7 +167,8 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
|||||||
|
|
||||||
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
||||||
|
|
||||||
if(Curl_convert_from_network(handle, &in, 1)) {
|
res = Curl_convert_from_network(handle, &in, 1);
|
||||||
|
if(res) {
|
||||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||||
free(ns);
|
free(ns);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
23
lib/file.c
23
lib/file.c
@@ -90,7 +90,8 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#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
|
#define DOS_FILESYSTEM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -126,9 +127,10 @@ const struct Curl_handler Curl_handler_file = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
0, /* defport */
|
0, /* defport */
|
||||||
CURLPROTO_FILE, /* protocol */
|
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;
|
actual_path = real_path;
|
||||||
if((actual_path[0] == '/') &&
|
if((actual_path[0] == '/') &&
|
||||||
actual_path[1] &&
|
actual_path[1] &&
|
||||||
(actual_path[2] == ':' || actual_path[2] == '|'))
|
(actual_path[2] == ':' || actual_path[2] == '|')) {
|
||||||
{
|
|
||||||
actual_path[2] = ':';
|
actual_path[2] = ':';
|
||||||
actual_path++;
|
actual_path++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
|
/* 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] == '/')
|
if(actual_path[i] == '/')
|
||||||
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;
|
file->path = actual_path;
|
||||||
#else
|
#else
|
||||||
fd = open_readonly(real_path, O_RDONLY);
|
fd = open_readonly(real_path, O_RDONLY);
|
||||||
@@ -377,7 +378,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
|||||||
|
|
||||||
/*skip bytes before resume point*/
|
/*skip bytes before resume point*/
|
||||||
if(data->state.resume_from) {
|
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;
|
data->state.resume_from -= nread;
|
||||||
nread = 0;
|
nread = 0;
|
||||||
buf2 = buf;
|
buf2 = buf;
|
||||||
@@ -456,7 +457,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
|||||||
fd = conn->data->state.proto.file->fd;
|
fd = conn->data->state.proto.file->fd;
|
||||||
|
|
||||||
/* VMS: This only works reliable for STREAMLF files */
|
/* 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 */
|
/* we could stat it, then read out the size */
|
||||||
expected_size = statbuf.st_size;
|
expected_size = statbuf.st_size;
|
||||||
/* and store the modification time */
|
/* 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... */
|
/* 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;
|
expected_size = data->req.maxdownload;
|
||||||
|
|
||||||
if(fstated && (expected_size == 0))
|
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;
|
bytestoread = (expected_size < BUFSIZE-1)?(size_t)expected_size:BUFSIZE-1;
|
||||||
nread = read(fd, buf, bytestoread);
|
nread = read(fd, buf, bytestoread);
|
||||||
|
|
||||||
if( nread > 0)
|
if(nread > 0)
|
||||||
buf[nread] = 0;
|
buf[nread] = 0;
|
||||||
|
|
||||||
if (nread <= 0 || expected_size == 0)
|
if(nread <= 0 || expected_size == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bytecount += nread;
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
342
lib/formdata.c
342
lib/formdata.c
@@ -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 "setup.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
@@ -382,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_NULL if a null pointer was given for a char
|
||||||
* CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
* CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
||||||
* CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
|
* 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 a HttpPost struct cannot be allocated
|
||||||
* CURL_FORMADD_MEMORY if some allocation for string copying failed.
|
* CURL_FORMADD_MEMORY if some allocation for string copying failed.
|
||||||
* CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
* CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
||||||
@@ -422,7 +341,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
while(return_value == CURL_FORMADD_OK) {
|
while(return_value == CURL_FORMADD_OK) {
|
||||||
|
|
||||||
/* first see if we have more parts of the array param */
|
/* 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 */
|
/* get the upcoming option from the given array */
|
||||||
option = forms->option;
|
option = forms->option;
|
||||||
array_value = (char *)forms->value;
|
array_value = (char *)forms->value;
|
||||||
@@ -679,7 +598,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
(struct curl_slist*)array_value:
|
(struct curl_slist*)array_value:
|
||||||
va_arg(params, struct curl_slist*);
|
va_arg(params, struct curl_slist*);
|
||||||
|
|
||||||
if( current_form->contentheader )
|
if(current_form->contentheader)
|
||||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||||
else
|
else
|
||||||
current_form->contentheader = list;
|
current_form->contentheader = list;
|
||||||
@@ -690,7 +609,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
{
|
{
|
||||||
const char *filename = array_state?array_value:
|
const char *filename = array_state?array_value:
|
||||||
va_arg(params, char *);
|
va_arg(params, char *);
|
||||||
if( current_form->showfilename )
|
if(current_form->showfilename)
|
||||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||||
else {
|
else {
|
||||||
current_form->showfilename = strdup(filename);
|
current_form->showfilename = strdup(filename);
|
||||||
@@ -714,26 +633,26 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
for(form = first_form;
|
for(form = first_form;
|
||||||
form != NULL;
|
form != NULL;
|
||||||
form = form->more) {
|
form = form->more) {
|
||||||
if( ((!form->name || !form->value) && !post) ||
|
if(((!form->name || !form->value) && !post) ||
|
||||||
( (form->contentslength) &&
|
( (form->contentslength) &&
|
||||||
(form->flags & HTTPPOST_FILENAME) ) ||
|
(form->flags & HTTPPOST_FILENAME) ) ||
|
||||||
( (form->flags & HTTPPOST_FILENAME) &&
|
( (form->flags & HTTPPOST_FILENAME) &&
|
||||||
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
|
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
|
||||||
|
|
||||||
( (!form->buffer) &&
|
( (!form->buffer) &&
|
||||||
(form->flags & HTTPPOST_BUFFER) &&
|
(form->flags & HTTPPOST_BUFFER) &&
|
||||||
(form->flags & HTTPPOST_PTRBUFFER) ) ||
|
(form->flags & HTTPPOST_PTRBUFFER) ) ||
|
||||||
|
|
||||||
( (form->flags & HTTPPOST_READFILE) &&
|
( (form->flags & HTTPPOST_READFILE) &&
|
||||||
(form->flags & HTTPPOST_PTRCONTENTS) )
|
(form->flags & HTTPPOST_PTRCONTENTS) )
|
||||||
) {
|
) {
|
||||||
return_value = CURL_FORMADD_INCOMPLETE;
|
return_value = CURL_FORMADD_INCOMPLETE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( ((form->flags & HTTPPOST_FILENAME) ||
|
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||||
(form->flags & HTTPPOST_BUFFER)) &&
|
(form->flags & HTTPPOST_BUFFER)) &&
|
||||||
!form->contenttype ) {
|
!form->contenttype ) {
|
||||||
/* our contenttype is missing */
|
/* our contenttype is missing */
|
||||||
form->contenttype
|
form->contenttype
|
||||||
= strdup(ContentTypeForFilename(form->value, prevtype));
|
= strdup(ContentTypeForFilename(form->value, prevtype));
|
||||||
@@ -743,8 +662,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
}
|
}
|
||||||
form->contenttype_alloc = TRUE;
|
form->contenttype_alloc = TRUE;
|
||||||
}
|
}
|
||||||
if( !(form->flags & HTTPPOST_PTRNAME) &&
|
if(!(form->flags & HTTPPOST_PTRNAME) &&
|
||||||
(form == first_form) ) {
|
(form == first_form) ) {
|
||||||
/* Note that there's small risk that form->name is NULL here if the
|
/* 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. */
|
app passed in a bad combo, so we better check for that first. */
|
||||||
if(form->name)
|
if(form->name)
|
||||||
@@ -756,9 +675,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
}
|
}
|
||||||
form->name_alloc = TRUE;
|
form->name_alloc = TRUE;
|
||||||
}
|
}
|
||||||
if( !(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||||
HTTPPOST_CALLBACK)) ) {
|
HTTPPOST_CALLBACK)) ) {
|
||||||
/* copy value (without strdup; possibly contains null characters) */
|
/* copy value (without strdup; possibly contains null characters) */
|
||||||
form->value = memdup(form->value, form->contentslength);
|
form->value = memdup(form->value, form->contentslength);
|
||||||
if(!form->value) {
|
if(!form->value) {
|
||||||
@@ -818,6 +737,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* curl_formadd() is a public API to add a section to the multipart formpost.
|
* curl_formadd() is a public API to add a section to the multipart formpost.
|
||||||
|
*
|
||||||
|
* @unittest: 1308
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
@@ -939,6 +860,8 @@ void Curl_formclean(struct FormData **form_ptr)
|
|||||||
* curl_formget()
|
* curl_formget()
|
||||||
* Serialize a curl_httppost struct.
|
* Serialize a curl_httppost struct.
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
|
*
|
||||||
|
* @unittest: 1308
|
||||||
*/
|
*/
|
||||||
int curl_formget(struct curl_httppost *form, void *arg,
|
int curl_formget(struct curl_httppost *form, void *arg,
|
||||||
curl_formget_callback append)
|
curl_formget_callback append)
|
||||||
@@ -951,8 +874,8 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
|||||||
if(rc != CURLE_OK)
|
if(rc != CURLE_OK)
|
||||||
return (int)rc;
|
return (int)rc;
|
||||||
|
|
||||||
for (ptr = data; ptr; ptr = ptr->next) {
|
for(ptr = data; ptr; ptr = ptr->next) {
|
||||||
if(ptr->type == FORM_FILE) {
|
if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
|
||||||
char buffer[8192];
|
char buffer[8192];
|
||||||
size_t nread;
|
size_t nread;
|
||||||
struct Form temp;
|
struct Form temp;
|
||||||
@@ -968,7 +891,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
|||||||
Curl_formclean(&data);
|
Curl_formclean(&data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while(nread == sizeof(buffer));
|
} while(nread);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(ptr->length != append(arg, ptr->line, ptr->length)) {
|
if(ptr->length != append(arg, ptr->line, ptr->length)) {
|
||||||
@@ -1000,10 +923,10 @@ void curl_formfree(struct curl_httppost *form)
|
|||||||
if(form->more)
|
if(form->more)
|
||||||
curl_formfree(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 */
|
free(form->name); /* free the name */
|
||||||
if( !(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
|
if(!(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
|
||||||
form->contents)
|
form->contents)
|
||||||
free(form->contents); /* free the contents */
|
free(form->contents); /* free the contents */
|
||||||
if(form->contenttype)
|
if(form->contenttype)
|
||||||
free(form->contenttype); /* free the content type */
|
free(form->contenttype); /* free the content type */
|
||||||
@@ -1211,15 +1134,17 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
/* it should be noted that for the HTTPPOST_FILENAME and
|
/* it should be noted that for the HTTPPOST_FILENAME and
|
||||||
HTTPPOST_CALLBACK cases the ->showfilename struct member is always
|
HTTPPOST_CALLBACK cases the ->showfilename struct member is always
|
||||||
assigned at this point */
|
assigned at this point */
|
||||||
char *filebasename=
|
if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
|
||||||
(!post->showfilename)?strippath(post->contents):NULL;
|
char *filebasename=
|
||||||
|
(!post->showfilename)?strippath(post->contents):NULL;
|
||||||
|
|
||||||
result = AddFormDataf(&form, &size,
|
result = AddFormDataf(&form, &size,
|
||||||
"; filename=\"%s\"",
|
"; filename=\"%s\"",
|
||||||
(post->showfilename?post->showfilename:
|
(post->showfilename?post->showfilename:
|
||||||
filebasename));
|
filebasename));
|
||||||
if(filebasename)
|
if(filebasename)
|
||||||
free(filebasename);
|
free(filebasename);
|
||||||
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
break;
|
break;
|
||||||
@@ -1235,7 +1160,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
curList = file->contentheader;
|
curList = file->contentheader;
|
||||||
while( curList ) {
|
while(curList) {
|
||||||
/* Process the additional headers specified for this form */
|
/* Process the additional headers specified for this form */
|
||||||
result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
|
result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
|
||||||
if(result)
|
if(result)
|
||||||
@@ -1378,8 +1303,17 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
|||||||
size_t nread;
|
size_t nread;
|
||||||
bool callback = (bool)(form->data->type == FORM_CALLBACK);
|
bool callback = (bool)(form->data->type == FORM_CALLBACK);
|
||||||
|
|
||||||
if(callback)
|
if(callback) {
|
||||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
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 {
|
else {
|
||||||
if(!form->fp) {
|
if(!form->fp) {
|
||||||
/* this file hasn't yet been opened */
|
/* this file hasn't yet been opened */
|
||||||
@@ -1389,9 +1323,9 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
|||||||
}
|
}
|
||||||
nread = fread(buffer, 1, size, form->fp);
|
nread = fread(buffer, 1, size, form->fp);
|
||||||
}
|
}
|
||||||
if(!nread || nread > size) {
|
if(!nread) {
|
||||||
/* this is the last chunk from the file, move on */
|
/* this is the last chunk from the file, move on */
|
||||||
if(!callback) {
|
if(form->fp) {
|
||||||
fclose(form->fp);
|
fclose(form->fp);
|
||||||
form->fp = NULL;
|
form->fp = NULL;
|
||||||
}
|
}
|
||||||
@@ -1431,7 +1365,7 @@ size_t Curl_FormReader(char *buffer,
|
|||||||
}
|
}
|
||||||
do {
|
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,
|
memcpy(buffer + gotsize , form->data->line + form->sent,
|
||||||
wantedsize - gotsize);
|
wantedsize - gotsize);
|
||||||
@@ -1478,168 +1412,6 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
|||||||
return header;
|
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 */
|
#else /* CURL_DISABLE_HTTP */
|
||||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
struct curl_httppost **last_post,
|
||||||
|
|||||||
129
lib/ftp.c
129
lib/ftp.c
@@ -178,9 +178,10 @@ const struct Curl_handler Curl_handler_ftp = {
|
|||||||
ftp_getsock, /* doing_getsock */
|
ftp_getsock, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ftp_disconnect, /* disconnect */
|
ftp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_FTP, /* defport */
|
PORT_FTP, /* defport */
|
||||||
CURLPROTO_FTP, /* protocol */
|
CURLPROTO_FTP, /* protocol */
|
||||||
PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
|
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -202,9 +203,11 @@ const struct Curl_handler Curl_handler_ftps = {
|
|||||||
ftp_getsock, /* doing_getsock */
|
ftp_getsock, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ftp_disconnect, /* disconnect */
|
ftp_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_FTPS, /* defport */
|
PORT_FTPS, /* defport */
|
||||||
CURLPROTO_FTP | CURLPROTO_FTPS, /* protocol */
|
CURLPROTO_FTP | CURLPROTO_FTPS, /* protocol */
|
||||||
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
|
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
|
||||||
|
PROTOPT_NEEDSPWD /* flags */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -226,6 +229,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_FTP, /* defport */
|
PORT_FTP, /* defport */
|
||||||
CURLPROTO_HTTP, /* protocol */
|
CURLPROTO_HTTP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -250,6 +254,7 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_FTPS, /* defport */
|
PORT_FTPS, /* defport */
|
||||||
CURLPROTO_HTTP, /* protocol */
|
CURLPROTO_HTTP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -274,7 +279,7 @@ static void freedirs(struct ftp_conn *ftpc)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if(ftpc->dirs) {
|
if(ftpc->dirs) {
|
||||||
for (i=0; i < ftpc->dirdepth; i++){
|
for(i=0; i < ftpc->dirdepth; i++){
|
||||||
if(ftpc->dirs[i]) {
|
if(ftpc->dirs[i]) {
|
||||||
free(ftpc->dirs[i]);
|
free(ftpc->dirs[i]);
|
||||||
ftpc->dirs[i]=NULL;
|
ftpc->dirs[i]=NULL;
|
||||||
@@ -338,7 +343,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
|||||||
if(timeout_ms < interval_ms)
|
if(timeout_ms < interval_ms)
|
||||||
interval_ms = timeout_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 */
|
case -1: /* error */
|
||||||
/* let's die here */
|
/* let's die here */
|
||||||
failf(data, "Error while waiting for server connect");
|
failf(data, "Error while waiting for server connect");
|
||||||
@@ -352,7 +357,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
|||||||
|
|
||||||
s=accept(sock, (struct sockaddr *) &add, &size);
|
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) {
|
if(CURL_SOCKET_BAD == s) {
|
||||||
failf(data, "Error accept()ing server connect");
|
failf(data, "Error accept()ing server connect");
|
||||||
@@ -512,7 +517,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
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 */
|
case -1: /* select() error, stop reading */
|
||||||
failf(data, "FTP response aborted due to select/poll error: %d",
|
failf(data, "FTP response aborted due to select/poll error: %d",
|
||||||
SOCKERRNO);
|
SOCKERRNO);
|
||||||
@@ -741,7 +746,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
char *port_sep = NULL;
|
char *port_sep = NULL;
|
||||||
|
|
||||||
addr = calloc(addrlen+1, 1);
|
addr = calloc(addrlen+1, 1);
|
||||||
if (!addr)
|
if(!addr)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
@@ -753,11 +758,11 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if( *string_ftpport == ':') {
|
if(*string_ftpport == ':') {
|
||||||
/* :port */
|
/* :port */
|
||||||
ip_end = string_ftpport;
|
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) */
|
/* either ipv6 or (ipv4|domain|interface):port(-range) */
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
|
if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
|
||||||
@@ -765,19 +770,18 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
port_min = port_max = 0;
|
port_min = port_max = 0;
|
||||||
strcpy(addr, string_ftpport);
|
strcpy(addr, string_ftpport);
|
||||||
ip_end = NULL; /* this got no port ! */
|
ip_end = NULL; /* this got no port ! */
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
/* (ipv4|domain|interface):port(-range) */
|
/* (ipv4|domain|interface):port(-range) */
|
||||||
strncpy(addr, string_ftpport, ip_end - ip_start );
|
strncpy(addr, string_ftpport, ip_end - ip_start );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* ipv4|interface */
|
/* ipv4|interface */
|
||||||
strcpy(addr, string_ftpport);
|
strcpy(addr, string_ftpport);
|
||||||
|
|
||||||
/* parse the port */
|
/* parse the port */
|
||||||
if( ip_end != NULL ) {
|
if(ip_end != NULL) {
|
||||||
if((port_start = strchr(ip_end, ':')) != NULL) {
|
if((port_start = strchr(ip_end, ':')) != NULL) {
|
||||||
port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
|
port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
|
||||||
if((port_sep = strchr(port_start, '-')) != NULL) {
|
if((port_sep = strchr(port_start, '-')) != NULL) {
|
||||||
@@ -819,20 +823,19 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||||
failf(data, "getsockname() failed: %s",
|
failf(data, "getsockname() failed: %s",
|
||||||
Curl_strerror(conn, SOCKERRNO) );
|
Curl_strerror(conn, SOCKERRNO) );
|
||||||
if (addr)
|
if(addr)
|
||||||
free(addr);
|
free(addr);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
switch(sa->sa_family)
|
switch(sa->sa_family) {
|
||||||
{
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
|
Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
|
Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
host = hbuf; /* use this host name */
|
host = hbuf; /* use this host name */
|
||||||
}
|
}
|
||||||
@@ -840,7 +843,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
/* resolv ip/host to ip */
|
/* resolv ip/host to ip */
|
||||||
rc = Curl_resolv(conn, host, 0, &h);
|
rc = Curl_resolv(conn, host, 0, &h);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
(void)Curl_wait_for_resolv(conn, &h);
|
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||||
if(h) {
|
if(h) {
|
||||||
res = h->addr;
|
res = h->addr;
|
||||||
/* when we return from this function, we can forget about this entry
|
/* when we return from this function, we can forget about this entry
|
||||||
@@ -850,10 +853,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
res = NULL; /* failure! */
|
res = NULL; /* failure! */
|
||||||
|
|
||||||
if (addr)
|
if(addr)
|
||||||
free(addr);
|
free(addr);
|
||||||
|
|
||||||
if (res == NULL) {
|
if(res == NULL) {
|
||||||
failf(data, "Curl_resolv failed, we can not recover!");
|
failf(data, "Curl_resolv failed, we can not recover!");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
@@ -862,7 +865,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
|
|
||||||
portsock = CURL_SOCKET_BAD;
|
portsock = CURL_SOCKET_BAD;
|
||||||
error = 0;
|
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):
|
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
|
||||||
*/
|
*/
|
||||||
@@ -886,8 +889,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
||||||
sslen = ai->ai_addrlen;
|
sslen = ai->ai_addrlen;
|
||||||
|
|
||||||
for( port = port_min; port <= port_max; ) {
|
for(port = port_min; port <= port_max;) {
|
||||||
if( sa->sa_family == AF_INET )
|
if(sa->sa_family == AF_INET)
|
||||||
sa4->sin_port = htons(port);
|
sa4->sin_port = htons(port);
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
else
|
else
|
||||||
@@ -909,7 +912,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||||
failf(data, "getsockname() failed: %s",
|
failf(data, "getsockname() failed: %s",
|
||||||
Curl_strerror(conn, SOCKERRNO) );
|
Curl_strerror(conn, SOCKERRNO) );
|
||||||
sclose(portsock);
|
Curl_closesocket(conn, portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
port = port_min;
|
port = port_min;
|
||||||
@@ -918,7 +921,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
else if(error != EADDRINUSE && error != EACCES) {
|
else if(error != EADDRINUSE && error != EACCES) {
|
||||||
failf(data, "bind(port=%hu) failed: %s", port,
|
failf(data, "bind(port=%hu) failed: %s", port,
|
||||||
Curl_strerror(conn, error) );
|
Curl_strerror(conn, error) );
|
||||||
sclose(portsock);
|
Curl_closesocket(conn, portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -929,9 +932,9 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* maybe all ports were in use already*/
|
/* maybe all ports were in use already*/
|
||||||
if (port > port_max) {
|
if(port > port_max) {
|
||||||
failf(data, "bind() failed, we ran out of ports!");
|
failf(data, "bind() failed, we ran out of ports!");
|
||||||
sclose(portsock);
|
Curl_closesocket(conn, portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +944,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
|
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
|
||||||
failf(data, "getsockname() failed: %s",
|
failf(data, "getsockname() failed: %s",
|
||||||
Curl_strerror(conn, SOCKERRNO) );
|
Curl_strerror(conn, SOCKERRNO) );
|
||||||
sclose(portsock);
|
Curl_closesocket(conn, portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,7 +952,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
|
|
||||||
if(listen(portsock, 1)) {
|
if(listen(portsock, 1)) {
|
||||||
failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
|
failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
|
||||||
sclose(portsock);
|
Curl_closesocket(conn, portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,7 +969,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
conn->bits.ftp_use_eprt = TRUE;
|
conn->bits.ftp_use_eprt = TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (; fcmd != DONE; fcmd++) {
|
for(; fcmd != DONE; fcmd++) {
|
||||||
|
|
||||||
if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
|
if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
|
||||||
/* if disabled, goto next */
|
/* if disabled, goto next */
|
||||||
@@ -1035,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
|
the cleanup function will close it in case we fail before the true
|
||||||
secondary stuff is made */
|
secondary stuff is made */
|
||||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
||||||
sclose(conn->sock[SECONDARYSOCKET]);
|
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
conn->sock[SECONDARYSOCKET] = portsock;
|
conn->sock[SECONDARYSOCKET] = portsock;
|
||||||
|
|
||||||
/* this tcpconnect assignment below is a hackish work-around to make the
|
/* this tcpconnect assignment below is a hackish work-around to make the
|
||||||
@@ -1556,10 +1559,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
newport = (unsigned short)(num & 0xffff);
|
newport = (unsigned short)(num & 0xffff);
|
||||||
|
|
||||||
if(conn->bits.tunnel_proxy ||
|
if(conn->bits.tunnel_proxy ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||||
@@ -1612,10 +1615,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
ip[0], ip[1], ip[2], ip[3],
|
ip[0], ip[1], ip[2], ip[3],
|
||||||
conn->ip_addr_str);
|
conn->ip_addr_str);
|
||||||
if(conn->bits.tunnel_proxy ||
|
if(conn->bits.tunnel_proxy ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||||
@@ -1656,7 +1659,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||||
case of failure */
|
case of failure */
|
||||||
(void)Curl_wait_for_resolv(conn, &addr);
|
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||||
|
|
||||||
connectport =
|
connectport =
|
||||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||||
@@ -1672,7 +1675,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
rc = Curl_resolv(conn, newhost, newport, &addr);
|
rc = Curl_resolv(conn, newhost, newport, &addr);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
(void)Curl_wait_for_resolv(conn, &addr);
|
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||||
|
|
||||||
connectport = newport; /* we connect to the remote port */
|
connectport = newport; /* we connect to the remote port */
|
||||||
|
|
||||||
@@ -1717,7 +1720,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
/* this just dumps information about this second connection */
|
/* this just dumps information about this second connection */
|
||||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
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
|
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||||
* FALSE */
|
* FALSE */
|
||||||
case CURLPROXY_SOCKS5:
|
case CURLPROXY_SOCKS5:
|
||||||
@@ -2114,7 +2117,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
|||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
/* PORT means we are now awaiting the server to connect to us. */
|
/* PORT means we are now awaiting the server to connect to us. */
|
||||||
result = AllowServerConnect(conn);
|
result = AllowServerConnect(conn);
|
||||||
if( result )
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2171,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).
|
150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
|
||||||
|
|
||||||
D:
|
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:
|
E:
|
||||||
125 Data connection already open; Transfer starting. */
|
125 Data connection already open; Transfer starting. */
|
||||||
@@ -2228,7 +2231,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
|||||||
if(data->set.ftp_use_port) {
|
if(data->set.ftp_use_port) {
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
result = AllowServerConnect(conn);
|
result = AllowServerConnect(conn);
|
||||||
if( result )
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2583,7 +2586,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
if('\"' == *ptr) {
|
if('\"' == *ptr) {
|
||||||
/* it started good */
|
/* it started good */
|
||||||
ptr++;
|
ptr++;
|
||||||
for (store = dir; *ptr;) {
|
for(store = dir; *ptr;) {
|
||||||
if('\"' == *ptr) {
|
if('\"' == *ptr) {
|
||||||
if('\"' == ptr[1]) {
|
if('\"' == ptr[1]) {
|
||||||
/* "quote-doubling" */
|
/* "quote-doubling" */
|
||||||
@@ -2649,9 +2652,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
/* Reply format is like
|
/* Reply format is like
|
||||||
215<space><OS-name><space><commentary>
|
215<space><OS-name><space><commentary>
|
||||||
*/
|
*/
|
||||||
while (*ptr == ' ')
|
while(*ptr == ' ')
|
||||||
ptr++;
|
ptr++;
|
||||||
for (store = os; *ptr && *ptr != ' ';)
|
for(store = os; *ptr && *ptr != ' ';)
|
||||||
*store++ = *ptr++;
|
*store++ = *ptr++;
|
||||||
*store = '\0'; /* zero terminate */
|
*store = '\0'; /* zero terminate */
|
||||||
ftpc->server_os = os;
|
ftpc->server_os = os;
|
||||||
@@ -2770,7 +2773,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
|
|
||||||
case FTP_PRET:
|
case FTP_PRET:
|
||||||
if(ftpcode != 200) {
|
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);
|
failf(data, "PRET command not accepted: %03d", ftpcode);
|
||||||
return CURLE_FTP_PRET_FAILED;
|
return CURLE_FTP_PRET_FAILED;
|
||||||
}
|
}
|
||||||
@@ -2948,10 +2951,8 @@ static CURLcode ftp_connect(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->handler->protocol & CURLPROTO_FTPS) {
|
if(conn->handler->flags & PROTOPT_SSL) {
|
||||||
/* BLOCKING */
|
/* 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);
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -3099,7 +3100,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
|||||||
still requested to use SSL */
|
still requested to use SSL */
|
||||||
}
|
}
|
||||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
|
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
|
||||||
sclose(conn->sock[SECONDARYSOCKET]);
|
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3511,7 +3512,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wildcard->pattern = strdup(last_slash);
|
wildcard->pattern = strdup(last_slash);
|
||||||
if (!wildcard->pattern)
|
if(!wildcard->pattern)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
last_slash[0] = '\0'; /* cut file from path */
|
last_slash[0] = '\0'; /* cut file from path */
|
||||||
}
|
}
|
||||||
@@ -3519,7 +3520,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
|||||||
else { /* there is only 'wildcard pattern' or nothing */
|
else { /* there is only 'wildcard pattern' or nothing */
|
||||||
if(path[0]) {
|
if(path[0]) {
|
||||||
wildcard->pattern = strdup(path);
|
wildcard->pattern = strdup(path);
|
||||||
if (!wildcard->pattern)
|
if(!wildcard->pattern)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
path[0] = '\0';
|
path[0] = '\0';
|
||||||
}
|
}
|
||||||
@@ -3561,7 +3562,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
|||||||
|
|
||||||
/* backup old write_function */
|
/* backup old write_function */
|
||||||
ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
|
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;
|
conn->data->set.fwrite_func = Curl_ftp_parselist;
|
||||||
/* backup old file descriptor */
|
/* backup old file descriptor */
|
||||||
ftp_tmp->backup.file_descriptor = conn->data->set.out;
|
ftp_tmp->backup.file_descriptor = conn->data->set.out;
|
||||||
@@ -4005,14 +4006,14 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
|||||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||||
if(++ftpc->dirdepth >= ftpc->diralloc) {
|
if(++ftpc->dirdepth >= ftpc->diralloc) {
|
||||||
/* enlarge array */
|
/* enlarge array */
|
||||||
char *bigger;
|
char **bigger;
|
||||||
ftpc->diralloc *= 2; /* double the size each time */
|
ftpc->diralloc *= 2; /* double the size each time */
|
||||||
bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
|
bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
|
||||||
if(!bigger) {
|
if(!bigger) {
|
||||||
freedirs(ftpc);
|
freedirs(ftpc);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
ftpc->dirs = (char **)bigger;
|
ftpc->dirs = bigger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4079,7 +4080,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
|||||||
|
|
||||||
if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
|
if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
|
||||||
/* Failure detected, close the second socket if it was created already */
|
/* 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;
|
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||||
return result;
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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_STOR_TYPE, /* set type when about to STOR a file */
|
||||||
FTP_SIZE, /* get the remote file's size for head-like request */
|
FTP_SIZE, /* get the remote file's size for head-like request */
|
||||||
FTP_RETR_SIZE, /* get the remote file's size for RETR */
|
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_REST, /* when used to check if the server supports it in head-like */
|
||||||
FTP_RETR_REST, /* when asking for "resume" in for RETR */
|
FTP_RETR_REST, /* when asking for "resume" in for RETR */
|
||||||
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
|
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
|
||||||
@@ -93,7 +93,8 @@ struct ftp_wc_tmpdata {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
|
FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
|
||||||
FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */
|
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;
|
} curl_ftpfile;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -147,7 +148,8 @@ struct ftp_conn {
|
|||||||
ftpstate state; /* always use ftp.c:state() to change state! */
|
ftpstate state; /* always use ftp.c:state() to change state! */
|
||||||
char * server_os; /* The target server operating system. */
|
char * server_os; /* The target server operating system. */
|
||||||
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
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 */
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
compare = Curl_fnmatch;
|
||||||
|
|
||||||
/* filter pattern-corresponding filenames */
|
/* 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 " -> " */
|
/* discard symlink which is containing multiple " -> " */
|
||||||
if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
|
if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
|
||||||
(strstr(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.main = PL_UNIX_TIME;
|
||||||
parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
|
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);
|
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
}
|
}
|
||||||
@@ -960,7 +961,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
finfo->size = curlx_strtoofft(finfo->b_data + parser->item_offset,
|
finfo->size = curlx_strtoofft(finfo->b_data +
|
||||||
|
parser->item_offset,
|
||||||
&endptr, 10);
|
&endptr, 10);
|
||||||
if(!*endptr) {
|
if(!*endptr) {
|
||||||
if(finfo->size == CURL_OFF_T_MAX ||
|
if(finfo->size == CURL_OFF_T_MAX ||
|
||||||
|
|||||||
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, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_GOPHER, /* defport */
|
PORT_GOPHER, /* defport */
|
||||||
CURLPROTO_GOPHER, /* protocol */
|
CURLPROTO_GOPHER, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -132,7 +133,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
*done = TRUE; /* unconditionally */
|
*done = TRUE; /* unconditionally */
|
||||||
|
|
||||||
/* Create selector. Degenerate cases: / and /1 => convert to "" */
|
/* Create selector. Degenerate cases: / and /1 => convert to "" */
|
||||||
if (strlen(path) <= 2)
|
if(strlen(path) <= 2)
|
||||||
sel = (char *)"";
|
sel = (char *)"";
|
||||||
else {
|
else {
|
||||||
char *newp;
|
char *newp;
|
||||||
@@ -151,7 +152,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
/* ... and finally unescape */
|
/* ... and finally unescape */
|
||||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||||
if (!sel)
|
if(!sel)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
sel_org = sel;
|
sel_org = sel;
|
||||||
}
|
}
|
||||||
@@ -162,7 +163,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
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);
|
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_safefree(sel_org);
|
Curl_safefree(sel_org);
|
||||||
@@ -170,7 +171,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
k -= amount;
|
k -= amount;
|
||||||
sel += amount;
|
sel += amount;
|
||||||
if (k < 1)
|
if(k < 1)
|
||||||
break; /* but it did write it all */
|
break; /* but it did write it all */
|
||||||
}
|
}
|
||||||
else {
|
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
|
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||||
save allocing another string/doing another _write loop. */
|
save allocing another string/doing another _write loop. */
|
||||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||||
if (result != CURLE_OK) {
|
if(result != CURLE_OK) {
|
||||||
failf(data, "Failed sending Gopher request");
|
failf(data, "Failed sending Gopher request");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
59
lib/gtls.c
59
lib/gtls.c
@@ -197,14 +197,14 @@ static gnutls_datum load_file (const char *file)
|
|||||||
long filelen;
|
long filelen;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
if (!(f = fopen(file, "r")))
|
if(!(f = fopen(file, "r")))
|
||||||
return loaded_file;
|
return loaded_file;
|
||||||
if (fseek(f, 0, SEEK_END) != 0
|
if(fseek(f, 0, SEEK_END) != 0
|
||||||
|| (filelen = ftell(f)) < 0
|
|| (filelen = ftell(f)) < 0
|
||||||
|| fseek(f, 0, SEEK_SET) != 0
|
|| fseek(f, 0, SEEK_SET) != 0
|
||||||
|| !(ptr = malloc((size_t)filelen)))
|
|| !(ptr = malloc((size_t)filelen)))
|
||||||
goto out;
|
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);
|
free(ptr);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,8 @@ static CURLcode handshake(struct connectdata *conn,
|
|||||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||||
|
|
||||||
what = Curl_socket_ready(readfd, writefd,
|
what = Curl_socket_ready(readfd, writefd,
|
||||||
nonblocking?0:(int)timeout_ms?1000:timeout_ms);
|
nonblocking?0:
|
||||||
|
timeout_ms?timeout_ms:1000);
|
||||||
if(what < 0) {
|
if(what < 0) {
|
||||||
/* fatal error */
|
/* fatal error */
|
||||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||||
@@ -282,7 +283,7 @@ static CURLcode handshake(struct connectdata *conn,
|
|||||||
if(nonblocking)
|
if(nonblocking)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
else if (rc < 0) {
|
else if(rc < 0) {
|
||||||
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
|
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -357,7 +358,8 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
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.username,
|
||||||
data->set.ssl.password);
|
data->set.ssl.password);
|
||||||
if(rc != GNUTLS_E_SUCCESS) {
|
if(rc != GNUTLS_E_SUCCESS) {
|
||||||
@@ -412,13 +414,13 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
/* convenient assign */
|
/* convenient assign */
|
||||||
session = conn->ssl[sockindex].session;
|
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
|
#ifdef ENABLE_IPV6
|
||||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||||
#endif
|
#endif
|
||||||
sni &&
|
sni &&
|
||||||
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
|
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
|
||||||
strlen(conn->host.name)) < 0))
|
strlen(conn->host.name)) < 0))
|
||||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||||
"TLS extension\n");
|
"TLS extension\n");
|
||||||
|
|
||||||
@@ -442,12 +444,13 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
|
||||||
if(data->set.str[STRING_CERT]) {
|
if(data->set.str[STRING_CERT]) {
|
||||||
if( gnutls_certificate_set_x509_key_file(
|
if(gnutls_certificate_set_x509_key_file(
|
||||||
conn->ssl[sockindex].cred,
|
conn->ssl[sockindex].cred,
|
||||||
data->set.str[STRING_CERT],
|
data->set.str[STRING_CERT],
|
||||||
data->set.str[STRING_KEY] ?
|
data->set.str[STRING_KEY] ?
|
||||||
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
||||||
do_file_type(data->set.str[STRING_CERT_TYPE]) ) != GNUTLS_E_SUCCESS) {
|
do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
|
||||||
|
GNUTLS_E_SUCCESS) {
|
||||||
failf(data, "error reading X.509 key or certificate file");
|
failf(data, "error reading X.509 key or certificate file");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -458,10 +461,10 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
||||||
conn->ssl[sockindex].srp_client_cred);
|
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));
|
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
|
||||||
}
|
}
|
||||||
} else
|
else
|
||||||
#endif
|
#endif
|
||||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||||
conn->ssl[sockindex].cred);
|
conn->ssl[sockindex].cred);
|
||||||
@@ -586,13 +589,13 @@ gtls_connect_step3(struct connectdata *conn,
|
|||||||
gnutls_x509_crt_t format */
|
gnutls_x509_crt_t format */
|
||||||
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
|
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);
|
gnutls_x509_crt_init(&x509_issuer);
|
||||||
issuerp = load_file(data->set.ssl.issuercert);
|
issuerp = load_file(data->set.ssl.issuercert);
|
||||||
gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
|
gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
|
||||||
rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
|
rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
|
||||||
unload_file(issuerp);
|
unload_file(issuerp);
|
||||||
if (rc <= 0) {
|
if(rc <= 0) {
|
||||||
failf(data, "server certificate issuer check failed (IssuerCert: %s)",
|
failf(data, "server certificate issuer check failed (IssuerCert: %s)",
|
||||||
data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
|
data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
|
||||||
return CURLE_SSL_ISSUER_ERROR;
|
return CURLE_SSL_ISSUER_ERROR;
|
||||||
@@ -743,7 +746,7 @@ after_server_cert_verification:
|
|||||||
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
|
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
|
||||||
|
|
||||||
incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
|
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
|
/* 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 */
|
previous one was rejected, we just kill that and store the new */
|
||||||
Curl_ssl_delsessionid(conn, ssl_sessionid);
|
Curl_ssl_delsessionid(conn, ssl_sessionid);
|
||||||
@@ -869,7 +872,7 @@ static void close_one(struct connectdata *conn,
|
|||||||
conn->ssl[idx].cred = NULL;
|
conn->ssl[idx].cred = NULL;
|
||||||
}
|
}
|
||||||
#ifdef USE_TLS_SRP
|
#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);
|
gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
|
||||||
conn->ssl[idx].srp_client_cred = NULL;
|
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) {
|
if(conn->ssl[sockindex].session) {
|
||||||
while(!done) {
|
while(!done) {
|
||||||
int what = Curl_socket_ready(conn->sock[sockindex],
|
int what = Curl_socket_ready(conn->sock[sockindex],
|
||||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||||
if(what > 0) {
|
if(what > 0) {
|
||||||
/* Something to read, let's do it and hope that it is the close
|
/* Something to read, let's do it and hope that it is the close
|
||||||
notify alert from the server */
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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 *));
|
h->table = malloc(slots * sizeof(struct curl_llist *));
|
||||||
if(h->table) {
|
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);
|
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
||||||
if(!h->table[i]) {
|
if(!h->table[i]) {
|
||||||
while(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)]
|
#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,
|
/* 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 *
|
void *
|
||||||
Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
|
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_element *le;
|
||||||
struct curl_llist *l = FETCH_LIST (h, key, key_len);
|
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;
|
he = (struct curl_hash_element *) le->ptr;
|
||||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||||
Curl_llist_remove(l, le, (void *)h);
|
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_hash_element *he;
|
||||||
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
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;
|
he = le->ptr;
|
||||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||||
Curl_llist_remove(l, le, (void *) h);
|
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_hash_element *he;
|
||||||
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
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;
|
he = le->ptr;
|
||||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||||
return he->ptr;
|
return he->ptr;
|
||||||
@@ -218,10 +221,10 @@ Curl_hash_apply(curl_hash *h, void *user,
|
|||||||
struct curl_llist_element *le;
|
struct curl_llist_element *le;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < h->slots; ++i) {
|
for(i = 0; i < h->slots; ++i) {
|
||||||
for (le = (h->table[i])->head;
|
for(le = (h->table[i])->head;
|
||||||
le;
|
le;
|
||||||
le = le->next) {
|
le = le->next) {
|
||||||
curl_hash_element *el = le->ptr;
|
curl_hash_element *el = le->ptr;
|
||||||
cb(user, el->ptr);
|
cb(user, el->ptr);
|
||||||
}
|
}
|
||||||
@@ -234,7 +237,7 @@ Curl_hash_clean(struct curl_hash *h)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < h->slots; ++i) {
|
for(i = 0; i < h->slots; ++i) {
|
||||||
Curl_llist_destroy(h->table[i], (void *) h);
|
Curl_llist_destroy(h->table[i], (void *) h);
|
||||||
h->table[i] = NULL;
|
h->table[i] = NULL;
|
||||||
}
|
}
|
||||||
@@ -251,7 +254,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
|||||||
struct curl_llist *list;
|
struct curl_llist *list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < h->slots; ++i) {
|
for(i = 0; i < h->slots; ++i) {
|
||||||
list = h->table[i];
|
list = h->table[i];
|
||||||
le = list->head; /* get first list entry */
|
le = list->head; /* get first list entry */
|
||||||
while(le) {
|
while(le) {
|
||||||
@@ -319,7 +322,7 @@ void Curl_hash_print(struct curl_hash *h,
|
|||||||
|
|
||||||
fprintf(stderr, "=Hash dump=\n");
|
fprintf(stderr, "=Hash dump=\n");
|
||||||
|
|
||||||
for (i = 0; i < h->slots; i++) {
|
for(i = 0; i < h->slots; i++) {
|
||||||
list = h->table[i];
|
list = h->table[i];
|
||||||
le = list->head; /* get first list entry */
|
le = list->head; /* get first list entry */
|
||||||
if(le) {
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
unsigned char b;
|
||||||
|
|
||||||
/* Create HMAC context. */
|
/* 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);
|
ctxt = malloc(i);
|
||||||
|
|
||||||
if(!ctxt)
|
if(!ctxt)
|
||||||
@@ -84,14 +85,14 @@ Curl_HMAC_init(const HMAC_params * hashparams,
|
|||||||
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
|
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
|
||||||
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
|
(*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
|
||||||
|
|
||||||
for (i = 0; i < keylen; i++) {
|
for(i = 0; i < keylen; i++) {
|
||||||
b = (unsigned char)(*key ^ hmac_ipad);
|
b = (unsigned char)(*key ^ hmac_ipad);
|
||||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
|
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
|
||||||
b = (unsigned char)(*key++ ^ hmac_opad);
|
b = (unsigned char)(*key++ ^ hmac_opad);
|
||||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
|
(*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_hashctxt1, &hmac_ipad, 1);
|
||||||
(*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 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;
|
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)
|
if(!result)
|
||||||
result = (unsigned char *) ctxt->hmac_hashctxt2 +
|
result = (unsigned char *) ctxt->hmac_hashctxt2 +
|
||||||
|
|||||||
114
lib/hostasyn.c
114
lib/hostasyn.c
@@ -72,20 +72,6 @@
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef CURLRES_ASYNCH
|
#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()
|
* Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
|
||||||
* or getaddrinfo_thread() when we got the name resolved (or not!).
|
* or getaddrinfo_thread() when we got the name resolved (or not!).
|
||||||
@@ -109,24 +95,6 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
|||||||
if(ai) {
|
if(ai) {
|
||||||
struct SessionHandle *data = conn->data;
|
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)
|
if(data->share)
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
@@ -143,52 +111,9 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
|||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
}
|
}
|
||||||
else {
|
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;
|
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;
|
conn->async.dns = dns;
|
||||||
|
|
||||||
@@ -202,4 +127,43 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
|||||||
return rc;
|
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 */
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -110,11 +110,13 @@
|
|||||||
* hostip.c - method-independent resolver functions and utility functions
|
* hostip.c - method-independent resolver functions and utility functions
|
||||||
* hostasyn.c - functions for asynchronous name resolves
|
* hostasyn.c - functions for asynchronous name resolves
|
||||||
* hostsyn.c - functions for synchronous 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
|
* hostip4.c - ipv4-specific functions
|
||||||
* hostip6.c - ipv6-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
|
* 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.
|
* 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;
|
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
|
/* cache forever means never prune, and NULL hostcache means
|
||||||
we can't do it */
|
we can't do it */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -296,7 +298,7 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
|||||||
time(&user.now);
|
time(&user.now);
|
||||||
user.cache_timeout = data->set.dns_cache_timeout;
|
user.cache_timeout = data->set.dns_cache_timeout;
|
||||||
|
|
||||||
if( !hostcache_timestamp_remove(&user,dns) )
|
if(!hostcache_timestamp_remove(&user,dns) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Curl_hash_clean_with_criterium(data->dns.hostcache,
|
Curl_hash_clean_with_criterium(data->dns.hostcache,
|
||||||
@@ -426,7 +428,7 @@ int Curl_resolv(struct connectdata *conn,
|
|||||||
free(entry_id);
|
free(entry_id);
|
||||||
|
|
||||||
/* See whether the returned entry is stale. Done before we release lock */
|
/* 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 */
|
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
@@ -464,7 +466,7 @@ int Curl_resolv(struct connectdata *conn,
|
|||||||
/* the response to our resolve call will come asynchronously at
|
/* the response to our resolve call will come asynchronously at
|
||||||
a later time, good or bad */
|
a later time, good or bad */
|
||||||
/* First, check that we haven't received the info by now */
|
/* 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 */
|
if(result) /* error detected */
|
||||||
return CURLRESOLV_ERROR;
|
return CURLRESOLV_ERROR;
|
||||||
if(dns)
|
if(dns)
|
||||||
@@ -559,7 +561,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
|||||||
*entry = NULL;
|
*entry = NULL;
|
||||||
|
|
||||||
#ifdef USE_ALARM_TIMEOUT
|
#ifdef USE_ALARM_TIMEOUT
|
||||||
if (data->set.no_signal)
|
if(data->set.no_signal)
|
||||||
/* Ignore the timeout when signals are disabled */
|
/* Ignore the timeout when signals are disabled */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
else
|
else
|
||||||
@@ -689,7 +691,7 @@ void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
|||||||
dns->inuse--;
|
dns->inuse--;
|
||||||
/* only free if nobody is using AND it is not in hostcache (timestamp ==
|
/* only free if nobody is using AND it is not in hostcache (timestamp ==
|
||||||
0) */
|
0) */
|
||||||
if (dns->inuse == 0 && dns->timestamp == 0) {
|
if(dns->inuse == 0 && dns->timestamp == 0) {
|
||||||
Curl_freeaddrinfo(dns->addr);
|
Curl_freeaddrinfo(dns->addr);
|
||||||
free(dns);
|
free(dns);
|
||||||
}
|
}
|
||||||
@@ -707,7 +709,7 @@ static void freednsentry(void *freethis)
|
|||||||
|
|
||||||
/* mark the entry as not in hostcache */
|
/* mark the entry as not in hostcache */
|
||||||
p->timestamp = 0;
|
p->timestamp = 0;
|
||||||
if (p->inuse == 0) {
|
if(p->inuse == 0) {
|
||||||
Curl_freeaddrinfo(p->addr);
|
Curl_freeaddrinfo(p->addr);
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|||||||
56
lib/hostip.h
56
lib/hostip.h
@@ -25,6 +25,7 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "curl_addrinfo.h"
|
#include "curl_addrinfo.h"
|
||||||
|
#include "asyn.h"
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
@@ -35,14 +36,6 @@
|
|||||||
#define in_addr_t unsigned long
|
#define in_addr_t unsigned long
|
||||||
#endif
|
#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
|
/* Allocate enough memory to hold the full name information structs and
|
||||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||||
* required for storing all possible aliases and IP numbers is according to
|
* 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
|
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
||||||
many seconds for a name resolve */
|
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 CURL_ASYNC_SUCCESS CURLE_OK
|
||||||
#define ares_cancel(x) do {} while(0)
|
|
||||||
#define ares_destroy(x) do {} while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
struct hostent;
|
struct hostent;
|
||||||
struct SessionHandle;
|
struct SessionHandle;
|
||||||
struct connectdata;
|
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.
|
* 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
|
* 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);
|
bool Curl_ipvalid(struct connectdata *conn);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_getaddrinfo() is the generic low-level name resolve API within this
|
* Curl_getaddrinfo() is the generic low-level name resolve API within this
|
||||||
* source file. There are several versions of this function - for different
|
* 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 port,
|
||||||
int *waitp);
|
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 */
|
/* unlock a previously resolved dns entry */
|
||||||
void Curl_resolv_unlock(struct SessionHandle *data,
|
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 */
|
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
||||||
Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
|
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.
|
* Curl_addrinfo_callback() is used when we build with any asynch specialty.
|
||||||
* Handles end of async request processing. Inserts ai into hostcache when
|
* Handles end of async request processing. Inserts ai into hostcache when
|
||||||
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
||||||
* request completed wether successful or failed.
|
* request completed whether successful or failed.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||||
int status,
|
int status,
|
||||||
@@ -209,13 +180,6 @@ struct Curl_dns_entry *
|
|||||||
Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
||||||
const char *hostname, int port);
|
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
|
#ifndef INADDR_NONE
|
||||||
#define CURL_INADDR_NONE (in_addr_t) ~0
|
#define CURL_INADDR_NONE (in_addr_t) ~0
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ bool Curl_ipvalid(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CURLRES_SYNCH
|
#ifdef CURLRES_SYNCH
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_getaddrinfo() - the ipv4 synchronous version.
|
* Curl_getaddrinfo() - the ipv4 synchronous version.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ bool Curl_ipv6works(void)
|
|||||||
ipv6_works = 0;
|
ipv6_works = 0;
|
||||||
else {
|
else {
|
||||||
ipv6_works = 1;
|
ipv6_works = 1;
|
||||||
sclose(s);
|
Curl_closesocket(NULL, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (ipv6_works>0)?TRUE:FALSE;
|
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)
|
static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||||
{
|
{
|
||||||
printf("dump_addrinfo:\n");
|
printf("dump_addrinfo:\n");
|
||||||
for ( ; ai; ai = ai->ai_next) {
|
for(; ai; ai = ai->ai_next) {
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
printf(" fam %2d, CNAME %s, ",
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -72,52 +72,5 @@
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef CURLRES_SYNCH
|
#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 */
|
#endif /* truly sync */
|
||||||
|
|||||||
99
lib/http.c
99
lib/http.c
@@ -96,7 +96,6 @@
|
|||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
#include "content_encoding.h"
|
#include "content_encoding.h"
|
||||||
#include "rtsp.h"
|
|
||||||
#include "http_proxy.h"
|
#include "http_proxy.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "non-ascii.h"
|
#include "non-ascii.h"
|
||||||
@@ -114,6 +113,8 @@
|
|||||||
static int http_getsock_do(struct connectdata *conn,
|
static int http_getsock_do(struct connectdata *conn,
|
||||||
curl_socket_t *socks,
|
curl_socket_t *socks,
|
||||||
int numsocks);
|
int numsocks);
|
||||||
|
static int http_should_fail(struct connectdata *conn);
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||||
static int https_getsock(struct connectdata *conn,
|
static int https_getsock(struct connectdata *conn,
|
||||||
@@ -139,6 +140,7 @@ const struct Curl_handler Curl_handler_http = {
|
|||||||
http_getsock_do, /* doing_getsock */
|
http_getsock_do, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_HTTP, /* defport */
|
PORT_HTTP, /* defport */
|
||||||
CURLPROTO_HTTP, /* protocol */
|
CURLPROTO_HTTP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -161,6 +163,7 @@ const struct Curl_handler Curl_handler_https = {
|
|||||||
http_getsock_do, /* doing_getsock */
|
http_getsock_do, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_HTTPS, /* defport */
|
PORT_HTTPS, /* defport */
|
||||||
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
|
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
|
||||||
PROTOPT_SSL /* flags */
|
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
|
* case of allocation failure. Returns an empty string if the header value
|
||||||
* consists entirely of whitespace.
|
* 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 *start;
|
||||||
const char *end;
|
const char *end;
|
||||||
@@ -202,10 +205,10 @@ char *Curl_copy_header_value(const char *h)
|
|||||||
DEBUGASSERT(h);
|
DEBUGASSERT(h);
|
||||||
|
|
||||||
/* Find the end of the header name */
|
/* Find the end of the header name */
|
||||||
while (*h && (*h != ':'))
|
while(*h && (*h != ':'))
|
||||||
++h;
|
++h;
|
||||||
|
|
||||||
if (*h)
|
if(*h)
|
||||||
/* Skip over colon */
|
/* Skip over colon */
|
||||||
++h;
|
++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 SessionHandle *data = conn->data;
|
||||||
struct HTTP *http = data->state.proto.http;
|
struct HTTP *http = data->state.proto.http;
|
||||||
curl_off_t bytessent;
|
curl_off_t bytessent;
|
||||||
curl_off_t expectsend = -1; /* default is unknown */
|
curl_off_t expectsend = -1; /* default is unknown */
|
||||||
|
|
||||||
if(!http || !(conn->handler->protocol & CURLPROTO_HTTP))
|
if(!http)
|
||||||
/* If this is still NULL, we have not reach very far and we can
|
/* If this is still NULL, we have not reach very far and we can safely
|
||||||
safely skip this rewinding stuff, or this is attempted to get used
|
skip this rewinding stuff */
|
||||||
when HTTP isn't activated */
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
switch(data->set.httpreq) {
|
switch(data->set.httpreq) {
|
||||||
@@ -475,7 +477,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|||||||
if((data->set.httpreq != HTTPREQ_GET) &&
|
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||||
(data->set.httpreq != HTTPREQ_HEAD) &&
|
(data->set.httpreq != HTTPREQ_HEAD) &&
|
||||||
!conn->bits.rewindaftersend) {
|
!conn->bits.rewindaftersend) {
|
||||||
code = Curl_http_perhapsrewind(conn);
|
code = http_perhapsrewind(conn);
|
||||||
if(code)
|
if(code)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
@@ -496,7 +498,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|||||||
data->state.authhost.done = TRUE;
|
data->state.authhost.done = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Curl_http_should_fail(conn)) {
|
if(http_should_fail(conn)) {
|
||||||
failf (data, "The requested URL returned error: %d",
|
failf (data, "The requested URL returned error: %d",
|
||||||
data->req.httpcode);
|
data->req.httpcode);
|
||||||
code = CURLE_HTTP_RETURNED_ERROR;
|
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.
|
* into an error state or not.
|
||||||
*
|
*
|
||||||
* @param conn all information about the current connection
|
* @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
|
* @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;
|
struct SessionHandle *data;
|
||||||
int httpcode;
|
int httpcode;
|
||||||
@@ -886,16 +888,6 @@ int Curl_http_should_fail(struct connectdata *conn)
|
|||||||
** the client needs to reauthenticate. Once that info is
|
** the client needs to reauthenticate. Once that info is
|
||||||
** available, use it here.
|
** 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
|
** Either we're not authenticating, or we're supposed to
|
||||||
@@ -1024,7 +1016,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
/* 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
|
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
|
needs to fit into the normal read-callback buffer later on and that
|
||||||
@@ -1303,7 +1295,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
#endif /* CURL_DISABLE_PROXY */
|
#endif /* CURL_DISABLE_PROXY */
|
||||||
|
|
||||||
if(conn->given->protocol & CURLPROTO_HTTPS) {
|
if(conn->given->flags & PROTOPT_SSL) {
|
||||||
/* perform SSL initialization */
|
/* perform SSL initialization */
|
||||||
if(data->state.used_interface == Curl_if_multi) {
|
if(data->state.used_interface == Curl_if_multi) {
|
||||||
result = https_connecting(conn, done);
|
result = https_connecting(conn, done);
|
||||||
@@ -1342,7 +1334,7 @@ static int http_getsock_do(struct connectdata *conn,
|
|||||||
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
DEBUGASSERT((conn) && (conn->handler->protocol & CURLPROTO_HTTPS));
|
DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
|
||||||
|
|
||||||
/* perform SSL initialization for this socket */
|
/* perform SSL initialization for this socket */
|
||||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
|
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
|
||||||
@@ -1360,7 +1352,7 @@ static int https_getsock(struct connectdata *conn,
|
|||||||
curl_socket_t *socks,
|
curl_socket_t *socks,
|
||||||
int numsocks)
|
int numsocks)
|
||||||
{
|
{
|
||||||
if(conn->handler->protocol & CURLPROTO_HTTPS) {
|
if(conn->handler->flags & PROTOPT_SSL) {
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||||
|
|
||||||
if(!numsocks)
|
if(!numsocks)
|
||||||
@@ -1485,7 +1477,7 @@ static CURLcode expect100(struct SessionHandle *data,
|
|||||||
100-continue to the headers which actually speeds up post operations
|
100-continue to the headers which actually speeds up post operations
|
||||||
(as there is one packet coming back from the web server) */
|
(as there is one packet coming back from the web server) */
|
||||||
ptr = Curl_checkheaders(data, "Expect:");
|
ptr = Curl_checkheaders(data, "Expect:");
|
||||||
if (ptr) {
|
if(ptr) {
|
||||||
data->state.expect100header =
|
data->state.expect100header =
|
||||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||||
}
|
}
|
||||||
@@ -1657,8 +1649,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
||||||
data->set.upload) {
|
data->set.upload) {
|
||||||
httpreq = HTTPREQ_PUT;
|
httpreq = HTTPREQ_PUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1796,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
|
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
|
redirected request is being out on thin ice. Except if the host name
|
||||||
is the same as the first one! */
|
is the same as the first one! */
|
||||||
char *cookiehost = Curl_copy_header_value(ptr);
|
char *cookiehost = copy_header_value(ptr);
|
||||||
if (!cookiehost)
|
if(!cookiehost)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if (!*cookiehost)
|
if(!*cookiehost)
|
||||||
/* ignore empty data */
|
/* ignore empty data */
|
||||||
free(cookiehost);
|
free(cookiehost);
|
||||||
else {
|
else {
|
||||||
char *colon = strchr(cookiehost, ':');
|
char *colon = strchr(cookiehost, ':');
|
||||||
if (colon)
|
if(colon)
|
||||||
*colon = 0; /* The host must not include an embedded port number */
|
*colon = 0; /* The host must not include an embedded port number */
|
||||||
Curl_safefree(conn->allocptr.cookiehost);
|
Curl_safefree(conn->allocptr.cookiehost);
|
||||||
conn->allocptr.cookiehost = cookiehost;
|
conn->allocptr.cookiehost = cookiehost;
|
||||||
@@ -1882,7 +1874,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
ppath = data->change.url;
|
ppath = data->change.url;
|
||||||
if(checkprefix("ftp://", ppath)) {
|
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 */
|
/* when doing ftp, append ;type=<a|i> if not present */
|
||||||
char *type = strstr(ppath, ";type=");
|
char *type = strstr(ppath, ";type=");
|
||||||
if(type && type[6] && type[7] == 0) {
|
if(type && type[6] && type[7] == 0) {
|
||||||
@@ -1899,14 +1891,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
char *p = ftp_typecode;
|
char *p = ftp_typecode;
|
||||||
/* avoid sending invalid URLs like ftp://example.com;type=i if the
|
/* avoid sending invalid URLs like ftp://example.com;type=i if the
|
||||||
* user specified ftp://example.com without the slash */
|
* 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++ = '/';
|
*p++ = '/';
|
||||||
}
|
}
|
||||||
snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
|
snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
|
||||||
data->set.prefer_ascii ? 'a' : 'i');
|
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;
|
paste_ftp_userpwd = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2062,17 +2054,17 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
/* add the main request stuff */
|
/* add the main request stuff */
|
||||||
/* GET/HEAD/POST/PUT */
|
/* GET/HEAD/POST/PUT */
|
||||||
result = Curl_add_bufferf(req_buffer, "%s ", request);
|
result = Curl_add_bufferf(req_buffer, "%s ", request);
|
||||||
if (result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* url */
|
/* url */
|
||||||
if (paste_ftp_userpwd)
|
if(paste_ftp_userpwd)
|
||||||
result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
|
result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
|
||||||
conn->user, conn->passwd,
|
conn->user, conn->passwd,
|
||||||
ppath + sizeof("ftp://") - 1);
|
ppath + sizeof("ftp://") - 1);
|
||||||
else
|
else
|
||||||
result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
|
result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
|
||||||
if (result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = Curl_add_bufferf(req_buffer,
|
result = Curl_add_bufferf(req_buffer,
|
||||||
@@ -2802,7 +2794,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
* When all the headers have been parsed, see if we should give
|
* When all the headers have been parsed, see if we should give
|
||||||
* up and return an error.
|
* up and return an error.
|
||||||
*/
|
*/
|
||||||
if(Curl_http_should_fail(conn)) {
|
if(http_should_fail(conn)) {
|
||||||
failf (data, "The requested URL returned error: %d",
|
failf (data, "The requested URL returned error: %d",
|
||||||
k->httpcode);
|
k->httpcode);
|
||||||
return CURLE_HTTP_RETURNED_ERROR;
|
return CURLE_HTTP_RETURNED_ERROR;
|
||||||
@@ -2983,8 +2975,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
data->info.httpcode = k->httpcode;
|
data->info.httpcode = k->httpcode;
|
||||||
|
|
||||||
data->info.httpversion = conn->httpversion;
|
data->info.httpversion = conn->httpversion;
|
||||||
if (!data->state.httpversion ||
|
if(!data->state.httpversion ||
|
||||||
data->state.httpversion > conn->httpversion)
|
data->state.httpversion > conn->httpversion)
|
||||||
/* store the lowest server version we encounter */
|
/* store the lowest server version we encounter */
|
||||||
data->state.httpversion = conn->httpversion;
|
data->state.httpversion = conn->httpversion;
|
||||||
|
|
||||||
@@ -3094,10 +3086,10 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
/* check for Content-Type: header lines to get the MIME-type */
|
/* check for Content-Type: header lines to get the MIME-type */
|
||||||
else if(checkprefix("Content-Type:", k->p)) {
|
else if(checkprefix("Content-Type:", k->p)) {
|
||||||
char *contenttype = Curl_copy_header_value(k->p);
|
char *contenttype = copy_header_value(k->p);
|
||||||
if (!contenttype)
|
if(!contenttype)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if (!*contenttype)
|
if(!*contenttype)
|
||||||
/* ignore empty data */
|
/* ignore empty data */
|
||||||
free(contenttype);
|
free(contenttype);
|
||||||
else {
|
else {
|
||||||
@@ -3166,7 +3158,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
/* Find the first non-space letter */
|
/* Find the first non-space letter */
|
||||||
start = k->p + 18;
|
start = k->p + 18;
|
||||||
|
|
||||||
do {
|
for(;;) {
|
||||||
/* skip whitespaces and commas */
|
/* skip whitespaces and commas */
|
||||||
while(*start && (ISSPACE(*start) || (*start == ',')))
|
while(*start && (ISSPACE(*start) || (*start == ',')))
|
||||||
start++;
|
start++;
|
||||||
@@ -3212,7 +3204,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
/* unknown! */
|
/* unknown! */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} while(1);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(checkprefix("Content-Encoding:", k->p) &&
|
else if(checkprefix("Content-Encoding:", k->p) &&
|
||||||
@@ -3300,10 +3292,10 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
checkprefix("Location:", k->p) &&
|
checkprefix("Location:", k->p) &&
|
||||||
!data->req.location) {
|
!data->req.location) {
|
||||||
/* this is the URL that the server advises us to use instead */
|
/* this is the URL that the server advises us to use instead */
|
||||||
char *location = Curl_copy_header_value(k->p);
|
char *location = copy_header_value(k->p);
|
||||||
if (!location)
|
if(!location)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if (!*location)
|
if(!*location)
|
||||||
/* ignore empty data */
|
/* ignore empty data */
|
||||||
free(location);
|
free(location);
|
||||||
else {
|
else {
|
||||||
@@ -3317,19 +3309,18 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
|
|
||||||
/* some cases of POST and PUT etc needs to rewind the data
|
/* some cases of POST and PUT etc needs to rewind the data
|
||||||
stream at this point */
|
stream at this point */
|
||||||
result = Curl_http_perhapsrewind(conn);
|
result = http_perhapsrewind(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef CURL_DISABLE_RTSP
|
|
||||||
else if(conn->handler->protocol & CURLPROTO_RTSP) {
|
else if(conn->handler->protocol & CURLPROTO_RTSP) {
|
||||||
result = Curl_rtsp_parseheader(conn, k->p);
|
result = Curl_rtsp_parseheader(conn, k->p);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* End of header-checks. Write them to the client.
|
* 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_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
|
* 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_auth_act(struct connectdata *conn);
|
||||||
CURLcode Curl_http_perhapsrewind(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
|
/* 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
|
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
|
to not having one selected. The other CURLAUTH_* defines are present in the
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
|||||||
case IDENTITY:
|
case IDENTITY:
|
||||||
#endif
|
#endif
|
||||||
if(!k->ignorebody) {
|
if(!k->ignorebody) {
|
||||||
if( !data->set.http_te_skip )
|
if(!data->set.http_te_skip)
|
||||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
|
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
|
||||||
piece);
|
piece);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -49,6 +49,8 @@
|
|||||||
#define MAX_VALUE_LENGTH 256
|
#define MAX_VALUE_LENGTH 256
|
||||||
#define MAX_CONTENT_LENGTH 1024
|
#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.
|
* 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;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
if(!starts_with_quote) {
|
if(!starts_with_quote) {
|
||||||
/* this signals the end of the content if we didn't get a starting quote
|
/* this signals the end of the content if we didn't get a starting
|
||||||
and then we do "sloppy" parsing */
|
quote and then we do "sloppy" parsing */
|
||||||
c=0; /* the end */
|
c=0; /* the end */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -156,7 +158,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
before = TRUE;
|
before = TRUE;
|
||||||
|
|
||||||
/* clear off any former leftovers and init to defaults */
|
/* clear off any former leftovers and init to defaults */
|
||||||
Curl_digest_cleanup_one(d);
|
digest_cleanup_one(d);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
char value[MAX_VALUE_LENGTH];
|
char value[MAX_VALUE_LENGTH];
|
||||||
@@ -539,7 +541,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_digest_cleanup_one(struct digestdata *d)
|
static void digest_cleanup_one(struct digestdata *d)
|
||||||
{
|
{
|
||||||
if(d->nonce)
|
if(d->nonce)
|
||||||
free(d->nonce);
|
free(d->nonce);
|
||||||
@@ -573,8 +575,8 @@ void Curl_digest_cleanup_one(struct digestdata *d)
|
|||||||
|
|
||||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
Curl_digest_cleanup_one(&data->state.digest);
|
digest_cleanup_one(&data->state.digest);
|
||||||
Curl_digest_cleanup_one(&data->state.proxydigest);
|
digest_cleanup_one(&data->state.proxydigest);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -46,7 +46,6 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
bool proxy,
|
bool proxy,
|
||||||
const unsigned char *request,
|
const unsigned char *request,
|
||||||
const unsigned char *uripath);
|
const unsigned char *uripath);
|
||||||
void Curl_digest_cleanup_one(struct digestdata *dig);
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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
|
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 maj_stat, min_stat;
|
||||||
OM_uint32 msg_ctx = 0;
|
OM_uint32 msg_ctx = 0;
|
||||||
@@ -192,47 +193,47 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
|
|
||||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||||
if(checkprefix("Negotiate", header)) {
|
if(checkprefix("Negotiate", header)) {
|
||||||
ASN1_OBJECT * object = NULL;
|
ASN1_OBJECT * object = NULL;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
unsigned char * spnegoToken = NULL;
|
unsigned char * spnegoToken = NULL;
|
||||||
size_t spnegoTokenLength = 0;
|
size_t spnegoTokenLength = 0;
|
||||||
unsigned char * mechToken = NULL;
|
unsigned char * mechToken = NULL;
|
||||||
size_t mechTokenLength = 0;
|
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)
|
if(input_token.value == NULL)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
spnegoToken = malloc(input_token.length);
|
memcpy(input_token.value, mechToken,mechTokenLength);
|
||||||
if(spnegoToken == NULL)
|
input_token.length = mechTokenLength;
|
||||||
return CURLE_OUT_OF_MEMORY;
|
free(mechToken);
|
||||||
|
mechToken = NULL;
|
||||||
spnegoTokenLength = input_token.length;
|
infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
|
||||||
|
}
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -242,7 +243,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
&neg_ctx->context,
|
&neg_ctx->context,
|
||||||
neg_ctx->server_name,
|
neg_ctx->server_name,
|
||||||
GSS_C_NO_OID,
|
GSS_C_NO_OID,
|
||||||
GSS_C_DELEG_FLAG,
|
0,
|
||||||
0,
|
0,
|
||||||
GSS_C_NO_CHANNEL_BINDINGS,
|
GSS_C_NO_CHANNEL_BINDINGS,
|
||||||
&input_token,
|
&input_token,
|
||||||
@@ -289,7 +290,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
|||||||
size_t responseTokenLength = 0;
|
size_t responseTokenLength = 0;
|
||||||
|
|
||||||
responseToken = malloc(neg_ctx->output_token.length);
|
responseToken = malloc(neg_ctx->output_token.length);
|
||||||
if( responseToken == NULL)
|
if(responseToken == NULL)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
memcpy(responseToken, neg_ctx->output_token.value,
|
memcpy(responseToken, neg_ctx->output_token.value,
|
||||||
neg_ctx->output_token.length);
|
neg_ctx->output_token.length);
|
||||||
|
|||||||
@@ -133,17 +133,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
(ret = get_gss_name(conn, proxy, neg_ctx->server_name)))
|
(ret = get_gss_name(conn, proxy, neg_ctx->server_name)))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!neg_ctx->max_token_length) {
|
if(!neg_ctx->output_token) {
|
||||||
PSecPkgInfo SecurityPackage;
|
PSecPkgInfo SecurityPackage;
|
||||||
ret = s_pSecFn->QuerySecurityPackageInfo((SEC_CHAR *)"Negotiate",
|
ret = s_pSecFn->QuerySecurityPackageInfo((SEC_CHAR *)"Negotiate",
|
||||||
&SecurityPackage);
|
&SecurityPackage);
|
||||||
if (ret != SEC_E_OK)
|
if(ret != SEC_E_OK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Allocate input and output buffers according to the max token size
|
/* Allocate input and output buffers according to the max token size
|
||||||
as indicated by the security package */
|
as indicated by the security package */
|
||||||
neg_ctx->max_token_length = SecurityPackage->cbMaxToken;
|
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);
|
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,25 +153,14 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
header++;
|
header++;
|
||||||
|
|
||||||
len = strlen(header);
|
len = strlen(header);
|
||||||
if(len > 0) {
|
if(!len) {
|
||||||
input_token = malloc(neg_ctx->max_token_length);
|
/* first call in a new negotation, we have to acquire credentials,
|
||||||
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 negotiation, we have to require credentials,
|
|
||||||
and allocate memory for the context */
|
and allocate memory for the context */
|
||||||
|
|
||||||
neg_ctx->credentials = (CredHandle *)malloc(sizeof(CredHandle));
|
neg_ctx->credentials = malloc(sizeof(CredHandle));
|
||||||
neg_ctx->context = (CtxtHandle *)malloc(sizeof(CtxtHandle));
|
neg_ctx->context = malloc(sizeof(CtxtHandle));
|
||||||
|
|
||||||
if ( !neg_ctx->credentials || !neg_ctx->context)
|
if(!neg_ctx->credentials || !neg_ctx->context)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
neg_ctx->status =
|
neg_ctx->status =
|
||||||
@@ -179,7 +168,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
||||||
NULL, NULL, neg_ctx->credentials,
|
NULL, NULL, neg_ctx->credentials,
|
||||||
&lifetime);
|
&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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +192,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
||||||
|
|
||||||
|
|
||||||
if (input_token) {
|
if(input_token) {
|
||||||
in_buff_desc.ulVersion = 0;
|
in_buff_desc.ulVersion = 0;
|
||||||
in_buff_desc.cBuffers = 1;
|
in_buff_desc.cBuffers = 1;
|
||||||
in_buff_desc.pBuffers = &out_sec_buff;
|
in_buff_desc.pBuffers = &out_sec_buff;
|
||||||
@@ -217,14 +216,14 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
&context_attributes,
|
&context_attributes,
|
||||||
&lifetime);
|
&lifetime);
|
||||||
|
|
||||||
if ( GSS_ERROR(neg_ctx->status) )
|
if(GSS_ERROR(neg_ctx->status))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
|
if(neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
|
||||||
neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE ) {
|
neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE) {
|
||||||
neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
|
neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
|
||||||
&out_buff_desc);
|
&out_buff_desc);
|
||||||
if ( GSS_ERROR(neg_ctx->status) )
|
if(GSS_ERROR(neg_ctx->status))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +279,8 @@ static void cleanup(struct negotiatedata *neg_ctx)
|
|||||||
free(neg_ctx->output_token);
|
free(neg_ctx->output_token);
|
||||||
neg_ctx->output_token = 0;
|
neg_ctx->output_token = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neg_ctx->max_token_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||||
|
|||||||
134
lib/http_ntlm.c
134
lib/http_ntlm.c
@@ -25,10 +25,6 @@
|
|||||||
|
|
||||||
http://davenport.sourceforge.net/ntlm.html
|
http://davenport.sourceforge.net/ntlm.html
|
||||||
http://www.innovation.ch/java/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
|
#ifndef CURL_DISABLE_HTTP
|
||||||
@@ -87,6 +83,10 @@
|
|||||||
# include <rand.h>
|
# include <rand.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
#ifndef OPENSSL_VERSION_NUMBER
|
||||||
|
#error "OPENSSL_VERSION_NUMBER not defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||||
#define DES_key_schedule des_key_schedule
|
#define DES_key_schedule des_key_schedule
|
||||||
#define DES_cblock des_cblock
|
#define DES_cblock des_cblock
|
||||||
@@ -516,6 +516,7 @@ static void mk_lm_hash(struct SessionHandle *data,
|
|||||||
const char *password,
|
const char *password,
|
||||||
unsigned char *lmbuffer /* 21 bytes */)
|
unsigned char *lmbuffer /* 21 bytes */)
|
||||||
{
|
{
|
||||||
|
CURLcode res;
|
||||||
unsigned char pw[14];
|
unsigned char pw[14];
|
||||||
static const unsigned char magic[] = {
|
static const unsigned char magic[] = {
|
||||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||||
@@ -529,7 +530,8 @@ static void mk_lm_hash(struct SessionHandle *data,
|
|||||||
* The LanManager hashed password needs to be created using the
|
* The LanManager hashed password needs to be created using the
|
||||||
* password in the network encoding not the host encoding.
|
* password in the network encoding not the host encoding.
|
||||||
*/
|
*/
|
||||||
if(Curl_convert_to_network(data, (char *)pw, 14))
|
res = Curl_convert_to_network(data, (char *)pw, 14);
|
||||||
|
if(res)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -571,7 +573,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
|||||||
size_t srclen)
|
size_t srclen)
|
||||||
{
|
{
|
||||||
size_t i;
|
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] = (unsigned char)src[i];
|
||||||
dest[2*i+1] = '\0';
|
dest[2*i+1] = '\0';
|
||||||
}
|
}
|
||||||
@@ -658,6 +660,20 @@ ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
|||||||
|
|
||||||
#define HOSTNAME_MAX 1024
|
#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 */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||||
bool proxy)
|
bool proxy)
|
||||||
@@ -718,10 +734,10 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
passwdp="";
|
passwdp="";
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
if (s_hSecDll == NULL) {
|
if(s_hSecDll == NULL) {
|
||||||
/* not thread safe and leaks - use curl_global_init() to avoid */
|
/* not thread safe and leaks - use curl_global_init() to avoid */
|
||||||
CURLcode err = Curl_sspi_global_init();
|
CURLcode err = Curl_sspi_global_init();
|
||||||
if (s_hSecDll == NULL)
|
if(s_hSecDll == NULL)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -875,25 +891,26 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_OUT({
|
DEBUG_OUT({
|
||||||
fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
|
||||||
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
|
"0x%08.8x ",
|
||||||
NTLMFLAG_REQUEST_TARGET|
|
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
|
||||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
NTLM2FLAG|
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
NTLM2FLAG|
|
||||||
NTLMFLAG_NEGOTIATE_OEM|
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||||
NTLMFLAG_REQUEST_TARGET|
|
NTLMFLAG_NEGOTIATE_OEM|
|
||||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
NTLM2FLAG|
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
NTLM2FLAG|
|
||||||
print_flags(stderr,
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||||
NTLMFLAG_NEGOTIATE_OEM|
|
print_flags(stderr,
|
||||||
NTLMFLAG_REQUEST_TARGET|
|
NTLMFLAG_NEGOTIATE_OEM|
|
||||||
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
NTLM2FLAG|
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
NTLM2FLAG|
|
||||||
fprintf(stderr, "\n****\n");
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||||
});
|
fprintf(stderr, "\n****\n");
|
||||||
|
});
|
||||||
|
|
||||||
/* now size is the size of the base64 encoded package size */
|
/* now size is the size of the base64 encoded package size */
|
||||||
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
|
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
|
||||||
@@ -949,14 +966,17 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
type_3.pvBuffer = ntlmbuf;
|
type_3.pvBuffer = ntlmbuf;
|
||||||
type_3.cbBuffer = sizeof(ntlmbuf);
|
type_3.cbBuffer = sizeof(ntlmbuf);
|
||||||
|
|
||||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, &ntlm->c_handle,
|
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
|
||||||
(char *) host,
|
&ntlm->c_handle,
|
||||||
ISC_REQ_CONFIDENTIALITY |
|
(char *) host,
|
||||||
ISC_REQ_REPLAY_DETECT |
|
ISC_REQ_CONFIDENTIALITY |
|
||||||
ISC_REQ_CONNECTION,
|
ISC_REQ_REPLAY_DETECT |
|
||||||
0, SECURITY_NETWORK_DREP, &type_2_desc,
|
ISC_REQ_CONNECTION,
|
||||||
0, &ntlm->c_handle, &type_3_desc,
|
0, SECURITY_NETWORK_DREP,
|
||||||
&attrs, &tsDummy);
|
&type_2_desc,
|
||||||
|
0, &ntlm->c_handle,
|
||||||
|
&type_3_desc,
|
||||||
|
&attrs, &tsDummy);
|
||||||
|
|
||||||
if(status != SEC_E_OK)
|
if(status != SEC_E_OK)
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
@@ -972,9 +992,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
int ntrespoff;
|
int ntrespoff;
|
||||||
unsigned char ntresp[24]; /* fixed-size */
|
unsigned char ntresp[24]; /* fixed-size */
|
||||||
#endif
|
#endif
|
||||||
|
bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE)?TRUE:FALSE;
|
||||||
size_t useroff;
|
size_t useroff;
|
||||||
const char *user;
|
const char *user;
|
||||||
size_t userlen;
|
size_t userlen;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
user = strchr(userp, '\\');
|
user = strchr(userp, '\\');
|
||||||
if(!user)
|
if(!user)
|
||||||
@@ -1004,6 +1026,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
hostlen = strlen(host);
|
hostlen = strlen(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(unicode) {
|
||||||
|
domlen = domlen * 2;
|
||||||
|
userlen = userlen * 2;
|
||||||
|
hostlen = hostlen * 2;
|
||||||
|
}
|
||||||
|
|
||||||
#if USE_NTLM2SESSION
|
#if USE_NTLM2SESSION
|
||||||
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||||
@@ -1063,7 +1091,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
#if USE_NTRESPONSES
|
#if USE_NTRESPONSES
|
||||||
unsigned char ntbuffer[0x18];
|
unsigned char ntbuffer[0x18];
|
||||||
@@ -1093,13 +1121,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
useroff = domoff + domlen;
|
useroff = domoff + domlen;
|
||||||
hostoff = useroff + userlen;
|
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 */
|
/* Create the big type-3 message binary blob */
|
||||||
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
||||||
NTLMSSP_SIGNATURE "%c"
|
NTLMSSP_SIGNATURE "%c"
|
||||||
@@ -1205,14 +1226,14 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_OUT({
|
DEBUG_OUT({
|
||||||
fprintf(stderr, "\n ntresp=");
|
fprintf(stderr, "\n ntresp=");
|
||||||
print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
|
print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_OUT({
|
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);
|
LONGQUARTET(ntlm->flags), ntlm->flags);
|
||||||
print_flags(stderr, ntlm->flags);
|
print_flags(stderr, ntlm->flags);
|
||||||
fprintf(stderr, "\n****\n");
|
fprintf(stderr, "\n****\n");
|
||||||
@@ -1227,20 +1248,33 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUGASSERT(size == domoff);
|
DEBUGASSERT(size == domoff);
|
||||||
memcpy(&ntlmbuf[size], domain, domlen);
|
if(unicode)
|
||||||
|
unicodecpy(&ntlmbuf[size], domain, domlen/2);
|
||||||
|
else
|
||||||
|
memcpy(&ntlmbuf[size], domain, domlen);
|
||||||
|
|
||||||
size += domlen;
|
size += domlen;
|
||||||
|
|
||||||
DEBUGASSERT(size == useroff);
|
DEBUGASSERT(size == useroff);
|
||||||
memcpy(&ntlmbuf[size], user, userlen);
|
if(unicode)
|
||||||
|
unicodecpy(&ntlmbuf[size], user, userlen/2);
|
||||||
|
else
|
||||||
|
memcpy(&ntlmbuf[size], user, userlen);
|
||||||
|
|
||||||
size += userlen;
|
size += userlen;
|
||||||
|
|
||||||
DEBUGASSERT(size == hostoff);
|
DEBUGASSERT(size == hostoff);
|
||||||
memcpy(&ntlmbuf[size], host, hostlen);
|
if(unicode)
|
||||||
|
unicodecpy(&ntlmbuf[size], host, hostlen/2);
|
||||||
|
else
|
||||||
|
memcpy(&ntlmbuf[size], host, hostlen);
|
||||||
|
|
||||||
size += hostlen;
|
size += hostlen;
|
||||||
|
|
||||||
/* convert domain, user, and host to ASCII but leave the rest as-is */
|
/* convert domain, user, and host to ASCII but leave the rest as-is */
|
||||||
if(Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff],
|
res = Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff],
|
||||||
size-domoff))
|
size-domoff);
|
||||||
|
if(res)
|
||||||
return CURLE_CONV_FAILED;
|
return CURLE_CONV_FAILED;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "non-ascii.h"
|
#include "non-ascii.h"
|
||||||
|
#include "connect.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -164,8 +165,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
|
|
||||||
if(CURLE_OK == result) {
|
if(CURLE_OK == result) {
|
||||||
/* Now send off the request */
|
/* Now send off the request */
|
||||||
result = Curl_add_buffer_send(req_buffer, conn,
|
result =
|
||||||
&data->info.request_size, 0, sockindex);
|
Curl_add_buffer_send(req_buffer, conn,
|
||||||
|
&data->info.request_size, 0, sockindex);
|
||||||
}
|
}
|
||||||
req_buffer = NULL;
|
req_buffer = NULL;
|
||||||
if(result)
|
if(result)
|
||||||
@@ -242,7 +244,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
|
|
||||||
/* loop every second at least, less if the timeout is near */
|
/* loop every second at least, less if the timeout is near */
|
||||||
switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
|
switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
|
||||||
check<1000L?(int)check:1000)) {
|
check<1000L?check:1000)) {
|
||||||
case -1: /* select() error, stop reading */
|
case -1: /* select() error, stop reading */
|
||||||
error = SELECT_ERROR;
|
error = SELECT_ERROR;
|
||||||
failf(data, "Proxy CONNECT aborted due to select/poll error");
|
failf(data, "Proxy CONNECT aborted due to select/poll error");
|
||||||
@@ -481,7 +483,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
|
|
||||||
if(closeConnection && data->req.newurl) {
|
if(closeConnection && data->req.newurl) {
|
||||||
/* Connection closed by server. Don't use it anymore */
|
/* 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;
|
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#ifndef HEADER_CURL_HTTP_PROXY_H
|
||||||
|
#define HEADER_CURL_HTTP_PROXY_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
@@ -31,3 +33,5 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
#else
|
#else
|
||||||
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
|
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
|
||||||
#endif
|
#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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -25,27 +25,27 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#if defined(WIN32) && defined(USE_WIN32_IDN)
|
#if defined(WIN32) && defined(USE_WIN32_IDN)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#ifdef HAVE_NORMALIZATION_H
|
|
||||||
#define __in
|
|
||||||
#define __in_ecount(x)
|
|
||||||
#define __out_ecount(x)
|
|
||||||
#include <normalization.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <tchar.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
|
#define IDN_MAX_LENGTH 255
|
||||||
|
|
||||||
static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
|
static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
|
||||||
{
|
{
|
||||||
wchar_t *str_w = NULL;
|
wchar_t *str_w = NULL;
|
||||||
|
|
||||||
if (str_utf8) {
|
if(str_utf8) {
|
||||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||||
str_utf8, -1, NULL, 0);
|
str_utf8, -1, NULL, 0);
|
||||||
if (str_w_len) {
|
if(str_w_len) {
|
||||||
str_w = (wchar_t *) malloc(str_w_len * sizeof(wchar_t));
|
str_w = malloc(str_w_len * sizeof(wchar_t));
|
||||||
if (str_w) {
|
if(str_w) {
|
||||||
if (MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||||
str_w_len) == 0) {
|
str_w_len) == 0) {
|
||||||
free(str_w);
|
free(str_w);
|
||||||
str_w = NULL;
|
str_w = NULL;
|
||||||
@@ -61,13 +61,13 @@ static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
|
|||||||
{
|
{
|
||||||
char *str_utf8 = NULL;
|
char *str_utf8 = NULL;
|
||||||
|
|
||||||
if (str_w) {
|
if(str_w) {
|
||||||
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||||
0, NULL, NULL);
|
0, NULL, NULL);
|
||||||
if (str_utf8_len) {
|
if(str_utf8_len) {
|
||||||
str_utf8 = (char *) malloc(str_utf8_len * sizeof(wchar_t));
|
str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
|
||||||
if (str_utf8) {
|
if(str_utf8) {
|
||||||
if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||||
NULL, FALSE) == 0) {
|
NULL, FALSE) == 0) {
|
||||||
(void) GetLastError();
|
(void) GetLastError();
|
||||||
free((void *)str_utf8);
|
free((void *)str_utf8);
|
||||||
@@ -86,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)
|
int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||||
{
|
{
|
||||||
wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
|
wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
|
||||||
if (in_w) {
|
if(in_w) {
|
||||||
wchar_t punycode[IDN_MAX_LENGTH];
|
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());
|
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||||
free(in_w);
|
free(in_w);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -96,7 +96,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out)
|
|||||||
free(in_w);
|
free(in_w);
|
||||||
|
|
||||||
*out = (char *)_curl_win32_wchar_to_UTF8(punycode);
|
*out = (char *)_curl_win32_wchar_to_UTF8(punycode);
|
||||||
if (!(*out)) {
|
if(!(*out)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,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)
|
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];
|
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());
|
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
|
const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
|
||||||
if (!out_utf8) {
|
if(!out_utf8) {
|
||||||
return 0;
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
struct ifaddrs *iface, *head;
|
||||||
char *ip=NULL;
|
char *ip=NULL;
|
||||||
|
|
||||||
if (getifaddrs(&head) >= 0) {
|
if(getifaddrs(&head) >= 0) {
|
||||||
for (iface=head; iface != NULL; iface=iface->ifa_next) {
|
for(iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||||
if ((iface->ifa_addr != NULL) &&
|
if((iface->ifa_addr != NULL) &&
|
||||||
(iface->ifa_addr->sa_family == af) &&
|
(iface->ifa_addr->sa_family == af) &&
|
||||||
curl_strequal(iface->ifa_name, interface)) {
|
curl_strequal(iface->ifa_name, interface)) {
|
||||||
void *addr;
|
void *addr;
|
||||||
char scope[12]="";
|
char scope[12]="";
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if (af == AF_INET6) {
|
if(af == AF_INET6) {
|
||||||
unsigned int scopeid = 0;
|
unsigned int scopeid = 0;
|
||||||
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
|
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
/* Include the scope of this interface as part of the address */
|
/* Include the scope of this interface as part of the address */
|
||||||
scopeid = ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
|
scopeid = ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
|
||||||
#endif
|
#endif
|
||||||
if (scopeid)
|
if(scopeid)
|
||||||
snprintf(scope, sizeof(scope), "%%%u", scopeid);
|
snprintf(scope, sizeof(scope), "%%%u", scopeid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
20
lib/imap.c
20
lib/imap.c
@@ -99,7 +99,7 @@ static CURLcode imap_do(struct connectdata *conn, bool *done);
|
|||||||
static CURLcode imap_done(struct connectdata *conn,
|
static CURLcode imap_done(struct connectdata *conn,
|
||||||
CURLcode, bool premature);
|
CURLcode, bool premature);
|
||||||
static CURLcode imap_connect(struct connectdata *conn, bool *done);
|
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 CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
|
||||||
static int imap_getsock(struct connectdata *conn,
|
static int imap_getsock(struct connectdata *conn,
|
||||||
curl_socket_t *socks,
|
curl_socket_t *socks,
|
||||||
@@ -126,9 +126,10 @@ const struct Curl_handler Curl_handler_imap = {
|
|||||||
imap_getsock, /* doing_getsock */
|
imap_getsock, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
imap_disconnect, /* disconnect */
|
imap_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_IMAP, /* defport */
|
PORT_IMAP, /* defport */
|
||||||
CURLPROTO_IMAP, /* protocol */
|
CURLPROTO_IMAP, /* protocol */
|
||||||
PROTOPT_CLOSEACTION /* flags */
|
PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -150,9 +151,10 @@ const struct Curl_handler Curl_handler_imaps = {
|
|||||||
imap_getsock, /* doing_getsock */
|
imap_getsock, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
imap_disconnect, /* disconnect */
|
imap_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_IMAPS, /* defport */
|
PORT_IMAPS, /* defport */
|
||||||
CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
|
CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
|
||||||
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
|
PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD /* flags */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -174,6 +176,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_IMAP, /* defport */
|
PORT_IMAP, /* defport */
|
||||||
CURLPROTO_HTTP, /* protocol */
|
CURLPROTO_HTTP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -198,6 +201,7 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_IMAPS, /* defport */
|
PORT_IMAPS, /* defport */
|
||||||
CURLPROTO_HTTP, /* protocol */
|
CURLPROTO_HTTP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -629,12 +633,10 @@ static CURLcode imap_multi_statemach(struct connectdata *conn,
|
|||||||
struct imap_conn *imapc = &conn->proto.imapc;
|
struct imap_conn *imapc = &conn->proto.imapc;
|
||||||
CURLcode result;
|
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);
|
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
result = Curl_pp_multi_statemach(&imapc->pp);
|
result = Curl_pp_multi_statemach(&imapc->pp);
|
||||||
}
|
|
||||||
|
|
||||||
*done = (bool)(imapc->state == IMAP_STOP);
|
*done = (bool)(imapc->state == IMAP_STOP);
|
||||||
|
|
||||||
@@ -744,11 +746,9 @@ static CURLcode imap_connect(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((conn->handler->protocol & CURLPROTO_IMAPS) &&
|
if((conn->handler->flags & PROTOPT_SSL) &&
|
||||||
data->state.used_interface != Curl_if_multi) {
|
data->state.used_interface != Curl_if_multi) {
|
||||||
/* BLOCKING */
|
/* 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);
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return 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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -33,7 +33,8 @@ typedef enum {
|
|||||||
a connect */
|
a connect */
|
||||||
IMAP_LOGIN,
|
IMAP_LOGIN,
|
||||||
IMAP_STARTTLS,
|
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_SELECT,
|
||||||
IMAP_FETCH,
|
IMAP_FETCH,
|
||||||
IMAP_LOGOUT,
|
IMAP_LOGOUT,
|
||||||
@@ -48,7 +49,7 @@ struct imap_conn {
|
|||||||
imapstate state; /* always use imap.c:state() to change state! */
|
imapstate state; /* always use imap.c:state() to change state! */
|
||||||
int cmdid; /* id number/index */
|
int cmdid; /* id number/index */
|
||||||
const char *idstr; /* pointer to a string for which to wait for as id */
|
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;
|
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);
|
((int)((unsigned char)src[3])) & 0xff);
|
||||||
|
|
||||||
len = strlen(tmp);
|
len = strlen(tmp);
|
||||||
if(len == 0 || len >= size)
|
if(len == 0 || len >= size) {
|
||||||
{
|
|
||||||
SET_ERRNO(ENOSPC);
|
SET_ERRNO(ENOSPC);
|
||||||
return (NULL);
|
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.
|
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||||
*/
|
*/
|
||||||
memset(words, '\0', sizeof(words));
|
memset(words, '\0', sizeof(words));
|
||||||
for (i = 0; i < IN6ADDRSZ; i++)
|
for(i = 0; i < IN6ADDRSZ; i++)
|
||||||
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||||
|
|
||||||
best.base = -1;
|
best.base = -1;
|
||||||
cur.base = -1;
|
cur.base = -1;
|
||||||
best.len = 0;
|
best.len = 0;
|
||||||
cur.len = 0;
|
cur.len = 0;
|
||||||
|
|
||||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||||
{
|
if(words[i] == 0) {
|
||||||
if(words[i] == 0)
|
|
||||||
{
|
|
||||||
if(cur.base == -1)
|
if(cur.base == -1)
|
||||||
cur.base = i, cur.len = 1;
|
cur.base = i, cur.len = 1;
|
||||||
else
|
else
|
||||||
cur.len++;
|
cur.len++;
|
||||||
}
|
}
|
||||||
else if(cur.base != -1)
|
else if(cur.base != -1) {
|
||||||
{
|
|
||||||
if(best.base == -1 || cur.len > best.len)
|
if(best.base == -1 || cur.len > best.len)
|
||||||
best = cur;
|
best = cur;
|
||||||
cur.base = -1;
|
cur.base = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||||
best = cur;
|
best = cur;
|
||||||
if(best.base != -1 && best.len < 2)
|
if(best.base != -1 && best.len < 2)
|
||||||
best.base = -1;
|
best.base = -1;
|
||||||
|
/* Format the result. */
|
||||||
/* Format the result.
|
|
||||||
*/
|
|
||||||
tp = tmp;
|
tp = tmp;
|
||||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||||
{
|
/* Are we inside the best run of 0x00's? */
|
||||||
/* Are we inside the best run of 0x00's?
|
if(best.base != -1 && i >= best.base && i < (best.base + best.len)) {
|
||||||
*/
|
|
||||||
if(best.base != -1 && i >= best.base && i < (best.base + best.len))
|
|
||||||
{
|
|
||||||
if(i == best.base)
|
if(i == best.base)
|
||||||
*tp++ = ':';
|
*tp++ = ':';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are we following an initial run of 0x00s or any real hex?
|
/* Are we following an initial run of 0x00s or any real hex?
|
||||||
*/
|
*/
|
||||||
if(i != 0)
|
if(i != 0)
|
||||||
*tp++ = ':';
|
*tp++ = ':';
|
||||||
|
|
||||||
/* Is this address an encapsulated IPv4?
|
/* Is this address an encapsulated IPv4?
|
||||||
*/
|
*/
|
||||||
if(i == 6 && best.base == 0 &&
|
if(i == 6 && best.base == 0 &&
|
||||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||||
{
|
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
|
||||||
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
|
||||||
{
|
|
||||||
SET_ERRNO(ENOSPC);
|
SET_ERRNO(ENOSPC);
|
||||||
return (NULL);
|
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.
|
/* Check for overflow, copy, and we're done.
|
||||||
*/
|
*/
|
||||||
if((size_t)(tp - tmp) > size)
|
if((size_t)(tp - tmp) > size) {
|
||||||
{
|
|
||||||
SET_ERRNO(ENOSPC);
|
SET_ERRNO(ENOSPC);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ inet_pton6(const char *src, unsigned char *dst)
|
|||||||
|
|
||||||
if(tp == endp)
|
if(tp == endp)
|
||||||
return (0);
|
return (0);
|
||||||
for (i = 1; i <= n; i++) {
|
for(i = 1; i <= n; i++) {
|
||||||
*(endp - i) = *(colonp + n - i);
|
*(endp - i) = *(colonp + n - i);
|
||||||
*(colonp + n - i) = 0;
|
*(colonp + n - i) = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* Copyright (c) 2004 - 2010 Daniel Stenberg
|
* Copyright (c) 2004 - 2011 Daniel Stenberg
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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;
|
size_t n;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
for (p = dst, n = 0;
|
for(p = dst, n = 0;
|
||||||
n + 1 < dst_sz && *src != '\0';
|
n + 1 < dst_sz && *src != '\0';
|
||||||
++p, ++src, ++n)
|
++p, ++src, ++n)
|
||||||
*p = *src;
|
*p = *src;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if(*src == '\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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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
|
#endif
|
||||||
|
|
||||||
CURLcode Curl_krb_kauth(struct connectdata *conn);
|
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 *);
|
void Curl_sec_end (struct connectdata *);
|
||||||
CURLcode Curl_sec_login (struct connectdata *);
|
CURLcode Curl_sec_login (struct connectdata *);
|
||||||
int Curl_sec_request_prot (struct connectdata *conn, const char *level);
|
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)
|
if(maj != GSS_S_COMPLETE)
|
||||||
return -1;
|
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);
|
*to = malloc(enc.length);
|
||||||
if(!*to)
|
if(!*to)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -222,7 +223,8 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
|||||||
if(maj != GSS_S_COMPLETE) {
|
if(maj != GSS_S_COMPLETE) {
|
||||||
gss_release_name(&min, &gssname);
|
gss_release_name(&min, &gssname);
|
||||||
if(service == srv_host) {
|
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;
|
return AUTH_ERROR;
|
||||||
}
|
}
|
||||||
service = srv_host;
|
service = srv_host;
|
||||||
@@ -327,7 +329,7 @@ static void krb5_end(void *app_data)
|
|||||||
{
|
{
|
||||||
OM_uint32 maj, min;
|
OM_uint32 maj, min;
|
||||||
gss_ctx_id_t *context = app_data;
|
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);
|
maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
|
||||||
DEBUGASSERT(maj == GSS_S_COMPLETE);
|
DEBUGASSERT(maj == GSS_S_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|||||||
77
lib/ldap.c
77
lib/ldap.c
@@ -46,7 +46,8 @@
|
|||||||
#ifdef CURL_LDAP_WIN /* Use Windows LDAP implementation. */
|
#ifdef CURL_LDAP_WIN /* Use Windows LDAP implementation. */
|
||||||
# include <winldap.h>
|
# include <winldap.h>
|
||||||
# ifndef LDAP_VENDOR_NAME
|
# 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
|
# else
|
||||||
# include <winber.h>
|
# include <winber.h>
|
||||||
# endif
|
# endif
|
||||||
@@ -139,6 +140,7 @@ const struct Curl_handler Curl_handler_ldap = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_LDAP, /* defport */
|
PORT_LDAP, /* defport */
|
||||||
CURLPROTO_LDAP, /* protocol */
|
CURLPROTO_LDAP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -162,6 +164,7 @@ const struct Curl_handler Curl_handler_ldaps = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ZERO_NULL, /* disconnect */
|
ZERO_NULL, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_LDAPS, /* defport */
|
PORT_LDAPS, /* defport */
|
||||||
CURLPROTO_LDAP | CURLPROTO_LDAPS, /* protocol */
|
CURLPROTO_LDAP | CURLPROTO_LDAPS, /* protocol */
|
||||||
PROTOPT_SSL /* flags */
|
PROTOPT_SSL /* flags */
|
||||||
@@ -205,7 +208,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the URL scheme ( either ldap or ldaps ) */
|
/* Get the URL scheme ( either ldap or ldaps ) */
|
||||||
if(conn->given->protocol & CURLPROTO_LDAPS)
|
if(conn->given->flags & PROTOPT_SSL)
|
||||||
ldap_ssl = 1;
|
ldap_ssl = 1;
|
||||||
infof(data, "LDAP local: trying to establish %s connection\n",
|
infof(data, "LDAP local: trying to establish %s connection\n",
|
||||||
ldap_ssl ? "encrypted" : "cleartext");
|
ldap_ssl ? "encrypted" : "cleartext");
|
||||||
@@ -255,9 +258,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
ldap_option = LDAPSSL_VERIFY_SERVER;
|
ldap_option = LDAPSSL_VERIFY_SERVER;
|
||||||
} else {
|
|
||||||
ldap_option = LDAPSSL_VERIFY_NONE;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ldap_option = LDAPSSL_VERIFY_NONE;
|
||||||
rc = ldapssl_set_verify_mode(ldap_option);
|
rc = ldapssl_set_verify_mode(ldap_option);
|
||||||
if(rc != LDAP_SUCCESS) {
|
if(rc != LDAP_SUCCESS) {
|
||||||
failf(data, "LDAP local: ERROR setting cert verify mode: %s",
|
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. */
|
/* OpenLDAP SDK supports BASE64 files. */
|
||||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||||
(!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
(!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;
|
status = CURLE_SSL_CERTPROBLEM;
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
@@ -295,9 +298,10 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
ldap_option = LDAP_OPT_X_TLS_DEMAND;
|
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);
|
rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
|
||||||
if(rc != LDAP_SUCCESS) {
|
if(rc != LDAP_SUCCESS) {
|
||||||
failf(data, "LDAP local: ERROR setting cert verify mode: %s",
|
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
|
#endif
|
||||||
#endif /* CURL_LDAP_USE_SSL */
|
#endif /* CURL_LDAP_USE_SSL */
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
server = ldap_init(conn->host.name, (int)conn->port);
|
server = ldap_init(conn->host.name, (int)conn->port);
|
||||||
if(server == NULL) {
|
if(server == NULL) {
|
||||||
failf(data, "LDAP local: Cannot connect to %s:%hu",
|
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);
|
conn->bits.user_passwd ? conn->passwd : NULL);
|
||||||
}
|
}
|
||||||
if(rc != 0) {
|
if(rc != 0) {
|
||||||
failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
|
failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
|
||||||
status = CURLE_LDAP_CANNOT_BIND;
|
status = CURLE_LDAP_CANNOT_BIND;
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
|
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);
|
for(num = 0, entryIterator = ldap_first_entry(server, result);
|
||||||
entryIterator;
|
entryIterator;
|
||||||
entryIterator = ldap_next_entry(server, entryIterator), num++)
|
entryIterator = ldap_next_entry(server, entryIterator), num++) {
|
||||||
{
|
|
||||||
BerElement *ber = NULL;
|
BerElement *ber = NULL;
|
||||||
char *attribute; /*! suspicious that this isn't 'const' */
|
char *attribute; /*! suspicious that this isn't 'const' */
|
||||||
char *dn = ldap_get_dn(server, entryIterator);
|
char *dn = ldap_get_dn(server, entryIterator);
|
||||||
@@ -392,16 +396,13 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
dlsize += strlen(dn)+5;
|
dlsize += strlen(dn)+5;
|
||||||
|
|
||||||
for (attribute = ldap_first_attribute(server, entryIterator, &ber);
|
for(attribute = ldap_first_attribute(server, entryIterator, &ber);
|
||||||
attribute;
|
attribute;
|
||||||
attribute = ldap_next_attribute(server, entryIterator, ber))
|
attribute = ldap_next_attribute(server, entryIterator, ber)) {
|
||||||
{
|
|
||||||
BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);
|
BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);
|
||||||
|
|
||||||
if(vals != NULL)
|
if(vals != NULL) {
|
||||||
{
|
for(i = 0; (vals[i] != NULL); i++) {
|
||||||
for (i = 0; (vals[i] != NULL); i++)
|
|
||||||
{
|
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
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 *) attribute, 0);
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
||||||
@@ -515,15 +516,15 @@ static char **split_str (char *str)
|
|||||||
char **res, *lasts, *s;
|
char **res, *lasts, *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 2, s = strchr(str,','); s; i++)
|
for(i = 2, s = strchr(str,','); s; i++)
|
||||||
s = strchr(++s,',');
|
s = strchr(++s,',');
|
||||||
|
|
||||||
res = calloc(i, sizeof(char*));
|
res = calloc(i, sizeof(char*));
|
||||||
if(!res)
|
if(!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0, s = strtok_r(str, ",", &lasts); s;
|
for(i = 0, s = strtok_r(str, ",", &lasts); s;
|
||||||
s = strtok_r(NULL, ",", &lasts), i++)
|
s = strtok_r(NULL, ",", &lasts), i++)
|
||||||
res[i] = s;
|
res[i] = s;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -541,16 +542,16 @@ static bool unescape_elements (void *data, LDAPURLDesc *ludp)
|
|||||||
return (FALSE);
|
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);
|
ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
|
||||||
if(!ludp->lud_attrs[i])
|
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);
|
ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
|
||||||
if(!ludp->lud_exts[i])
|
if(!ludp->lud_exts[i])
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ludp->lud_dn) {
|
if(ludp->lud_dn) {
|
||||||
@@ -620,7 +621,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
|||||||
if(!ludp->lud_attrs)
|
if(!ludp->lud_attrs)
|
||||||
return LDAP_NO_MEMORY;
|
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]));
|
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)
|
if(!ludp->lud_exts)
|
||||||
return LDAP_NO_MEMORY;
|
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]));
|
LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
|
||||||
|
|
||||||
success:
|
success:
|
||||||
@@ -699,23 +700,23 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(!ludp)
|
if(!ludp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ludp->lud_dn)
|
if(ludp->lud_dn)
|
||||||
free(ludp->lud_dn);
|
free(ludp->lud_dn);
|
||||||
|
|
||||||
if(ludp->lud_filter)
|
if(ludp->lud_filter)
|
||||||
free(ludp->lud_filter);
|
free(ludp->lud_filter);
|
||||||
|
|
||||||
if(ludp->lud_attrs) {
|
if(ludp->lud_attrs) {
|
||||||
for (i = 0; ludp->lud_attrs[i]; i++)
|
for(i = 0; ludp->lud_attrs[i]; i++)
|
||||||
free(ludp->lud_attrs[i]);
|
free(ludp->lud_attrs[i]);
|
||||||
free(ludp->lud_attrs);
|
free(ludp->lud_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ludp->lud_exts) {
|
if(ludp->lud_exts) {
|
||||||
for (i = 0; ludp->lud_exts[i]; i++)
|
for(i = 0; ludp->lud_exts[i]; i++)
|
||||||
free(ludp->lud_exts[i]);
|
free(ludp->lud_exts[i]);
|
||||||
free(ludp->lud_exts);
|
free(ludp->lud_exts);
|
||||||
}
|
}
|
||||||
free (ludp);
|
free (ludp);
|
||||||
|
|||||||
19
lib/llist.c
19
lib/llist.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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -31,6 +31,9 @@
|
|||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unittest: 1300
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||||
{
|
{
|
||||||
@@ -62,6 +65,8 @@ Curl_llist_alloc(curl_llist_dtor dtor)
|
|||||||
* inserted first in the list.
|
* inserted first in the list.
|
||||||
*
|
*
|
||||||
* Returns: 1 on success and 0 on failure.
|
* Returns: 1 on success and 0 on failure.
|
||||||
|
*
|
||||||
|
* @unittest: 1300
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
@@ -101,6 +106,9 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unittest: 1300
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
void *user)
|
void *user)
|
||||||
@@ -115,7 +123,8 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
|||||||
list->tail = NULL;
|
list->tail = NULL;
|
||||||
else
|
else
|
||||||
e->next->prev = NULL;
|
e->next->prev = NULL;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
e->prev->next = e->next;
|
e->prev->next = e->next;
|
||||||
if(!e->next)
|
if(!e->next)
|
||||||
list->tail = e->prev;
|
list->tail = e->prev;
|
||||||
@@ -148,8 +157,12 @@ Curl_llist_count(struct curl_llist *list)
|
|||||||
return list->size;
|
return list->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unittest: 1300
|
||||||
|
*/
|
||||||
int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
|
int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
struct curl_llist *to_list, struct curl_llist_element *to_e)
|
struct curl_llist *to_list,
|
||||||
|
struct curl_llist_element *to_e)
|
||||||
{
|
{
|
||||||
/* Remove element from list */
|
/* Remove element from list */
|
||||||
if(e == NULL || list->size == 0)
|
if(e == NULL || list->size == 0)
|
||||||
|
|||||||
15
lib/md4.c
15
lib/md4.c
@@ -113,19 +113,19 @@ static void MD4Update(MD4_CTX *context, const unsigned char *input,
|
|||||||
/* Compute number of bytes mod 64 */
|
/* Compute number of bytes mod 64 */
|
||||||
bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||||
/* Update number of bits */
|
/* Update number of bits */
|
||||||
if ((context->count[0] += ((UINT4)inputLen << 3))
|
if((context->count[0] += ((UINT4)inputLen << 3))
|
||||||
< ((UINT4)inputLen << 3))
|
< ((UINT4)inputLen << 3))
|
||||||
context->count[1]++;
|
context->count[1]++;
|
||||||
context->count[1] += ((UINT4)inputLen >> 29);
|
context->count[1] += ((UINT4)inputLen >> 29);
|
||||||
|
|
||||||
partLen = 64 - bufindex;
|
partLen = 64 - bufindex;
|
||||||
/* Transform as many times as possible.
|
/* Transform as many times as possible.
|
||||||
*/
|
*/
|
||||||
if (inputLen >= partLen) {
|
if(inputLen >= partLen) {
|
||||||
memcpy(&context->buffer[bufindex], input, partLen);
|
memcpy(&context->buffer[bufindex], input, partLen);
|
||||||
MD4Transform (context->state, context->buffer);
|
MD4Transform (context->state, context->buffer);
|
||||||
|
|
||||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
for(i = partLen; i + 63 < inputLen; i += 64)
|
||||||
MD4Transform (context->state, &input[i]);
|
MD4Transform (context->state, &input[i]);
|
||||||
|
|
||||||
bufindex = 0;
|
bufindex = 0;
|
||||||
@@ -251,7 +251,7 @@ static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
|
|||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
for(i = 0, j = 0; j < len; i++, j += 4) {
|
||||||
output[j] = (unsigned char)(input[i] & 0xff);
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
@@ -262,11 +262,12 @@ static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
|
|||||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||||
a multiple of 4.
|
a multiple of 4.
|
||||||
*/
|
*/
|
||||||
static void Decode (UINT4 *output, const unsigned char *input, unsigned int len)
|
static void Decode (UINT4 *output, const unsigned char *input,
|
||||||
|
unsigned int len)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
for(i = 0, j = 0; j < len; i++, j += 4)
|
||||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -208,7 +208,7 @@ static void MD5_Update (struct md5_ctx *context, /* context */
|
|||||||
memcpy(&context->buffer[bufindex], input, partLen);
|
memcpy(&context->buffer[bufindex], input, partLen);
|
||||||
MD5Transform(context->state, context->buffer);
|
MD5Transform(context->state, context->buffer);
|
||||||
|
|
||||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
for(i = partLen; i + 63 < inputLen; i += 64)
|
||||||
MD5Transform(context->state, &input[i]);
|
MD5Transform(context->state, &input[i]);
|
||||||
|
|
||||||
bufindex = 0;
|
bufindex = 0;
|
||||||
@@ -345,7 +345,7 @@ static void Encode (unsigned char *output,
|
|||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
for(i = 0, j = 0; j < len; i++, j += 4) {
|
||||||
output[j] = (unsigned char)(input[i] & 0xff);
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
@@ -362,7 +362,7 @@ static void Decode (UINT4 *output,
|
|||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
for(i = 0, j = 0; j < len; i++, j += 4)
|
||||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -47,8 +47,10 @@ extern FILE *logfile;
|
|||||||
|
|
||||||
/* memory functions */
|
/* memory functions */
|
||||||
CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
|
CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
|
||||||
CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line, const char *source);
|
CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
|
||||||
CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line, const char *source);
|
const char *source);
|
||||||
|
CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
|
||||||
|
const char *source);
|
||||||
CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
|
CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
|
||||||
CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
|
CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
|
||||||
CURL_EXTERN void curl_memdebug(const char *logname);
|
CURL_EXTERN void curl_memdebug(const char *logname);
|
||||||
|
|||||||
156
lib/mprintf.c
156
lib/mprintf.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1999 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -547,67 +547,65 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Read the arg list parameters into our data list */
|
/* Read the arg list parameters into our data list */
|
||||||
for (i=0; i<max_param; i++) {
|
for(i=0; i<max_param; i++) {
|
||||||
if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH))
|
if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) {
|
||||||
{
|
/* Width/precision arguments must be read before the main argument
|
||||||
/* Width/precision arguments must be read before the main argument
|
* they are attached to
|
||||||
* they are attached to
|
*/
|
||||||
*/
|
vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
|
||||||
vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (vto[i].type)
|
switch (vto[i].type) {
|
||||||
{
|
case FORMAT_STRING:
|
||||||
case FORMAT_STRING:
|
vto[i].data.str = va_arg(arglist, char *);
|
||||||
vto[i].data.str = va_arg(arglist, char *);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case FORMAT_INTPTR:
|
case FORMAT_INTPTR:
|
||||||
case FORMAT_UNKNOWN:
|
case FORMAT_UNKNOWN:
|
||||||
case FORMAT_PTR:
|
case FORMAT_PTR:
|
||||||
vto[i].data.ptr = va_arg(arglist, void *);
|
vto[i].data.ptr = va_arg(arglist, void *);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_INT:
|
case FORMAT_INT:
|
||||||
#ifdef HAVE_LONG_LONG_TYPE
|
#ifdef HAVE_LONG_LONG_TYPE
|
||||||
if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
|
if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
|
||||||
vto[i].data.num.as_unsigned =
|
vto[i].data.num.as_unsigned =
|
||||||
(mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
|
(mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
|
||||||
else if(vto[i].flags & FLAGS_LONGLONG)
|
else if(vto[i].flags & FLAGS_LONGLONG)
|
||||||
vto[i].data.num.as_signed =
|
vto[i].data.num.as_signed =
|
||||||
(mp_intmax_t)va_arg(arglist, mp_intmax_t);
|
(mp_intmax_t)va_arg(arglist, mp_intmax_t);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
|
if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
|
||||||
vto[i].data.num.as_unsigned =
|
vto[i].data.num.as_unsigned =
|
||||||
(mp_uintmax_t)va_arg(arglist, unsigned long);
|
(mp_uintmax_t)va_arg(arglist, unsigned long);
|
||||||
else if(vto[i].flags & FLAGS_LONG)
|
else if(vto[i].flags & FLAGS_LONG)
|
||||||
vto[i].data.num.as_signed =
|
vto[i].data.num.as_signed =
|
||||||
(mp_intmax_t)va_arg(arglist, long);
|
(mp_intmax_t)va_arg(arglist, long);
|
||||||
else if(vto[i].flags & FLAGS_UNSIGNED)
|
else if(vto[i].flags & FLAGS_UNSIGNED)
|
||||||
vto[i].data.num.as_unsigned =
|
vto[i].data.num.as_unsigned =
|
||||||
(mp_uintmax_t)va_arg(arglist, unsigned int);
|
(mp_uintmax_t)va_arg(arglist, unsigned int);
|
||||||
else
|
else
|
||||||
vto[i].data.num.as_signed =
|
vto[i].data.num.as_signed =
|
||||||
(mp_intmax_t)va_arg(arglist, int);
|
(mp_intmax_t)va_arg(arglist, int);
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FORMAT_DOUBLE:
|
|
||||||
vto[i].data.dnum = va_arg(arglist, double);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FORMAT_WIDTH:
|
|
||||||
/* Argument has been read. Silently convert it into an integer
|
|
||||||
* for later use
|
|
||||||
*/
|
|
||||||
vto[i].type = FORMAT_INT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT_DOUBLE:
|
||||||
|
vto[i].data.dnum = va_arg(arglist, double);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT_WIDTH:
|
||||||
|
/* Argument has been read. Silently convert it into an integer
|
||||||
|
* for later use
|
||||||
|
*/
|
||||||
|
vto[i].type = FORMAT_INT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return max_param;
|
return max_param;
|
||||||
@@ -853,7 +851,7 @@ static int dprintf_formatf(
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
str = (char *) p->data.str;
|
str = (char *) p->data.str;
|
||||||
if( str == NULL) {
|
if(str == NULL) {
|
||||||
/* Write null[] if there's space. */
|
/* Write null[] if there's space. */
|
||||||
if(prec == -1 || prec >= (long) sizeof(null) - 1) {
|
if(prec == -1 || prec >= (long) sizeof(null) - 1) {
|
||||||
str = null;
|
str = null;
|
||||||
@@ -914,7 +912,7 @@ static int dprintf_formatf(
|
|||||||
if(p->flags & FLAGS_LEFT)
|
if(p->flags & FLAGS_LEFT)
|
||||||
while(width-- > 0)
|
while(width-- > 0)
|
||||||
OUTCHAR(' ');
|
OUTCHAR(' ');
|
||||||
for (point = strnil; *point != '\0'; ++point)
|
for(point = strnil; *point != '\0'; ++point)
|
||||||
OUTCHAR(*point);
|
OUTCHAR(*point);
|
||||||
if(! (p->flags & FLAGS_LEFT))
|
if(! (p->flags & FLAGS_LEFT))
|
||||||
while(width-- > 0)
|
while(width-- > 0)
|
||||||
@@ -1202,45 +1200,3 @@ int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
|
|||||||
{
|
{
|
||||||
return dprintf_formatf(whereto, fputc, format, ap_save);
|
return dprintf_formatf(whereto, fputc, format, ap_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DPRINTF_DEBUG
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
char buffer[129];
|
|
||||||
char *ptr;
|
|
||||||
#ifdef HAVE_LONG_LONG_TYPE
|
|
||||||
LONG_LONG_TYPE one=99;
|
|
||||||
LONG_LONG_TYPE two=100;
|
|
||||||
LONG_LONG_TYPE test = 0x1000000000LL;
|
|
||||||
curl_mprintf("%lld %lld %lld\n", one, two, test);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
curl_mprintf("%3d %5d\n", 10, 1998);
|
|
||||||
|
|
||||||
ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a kiss in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
|
|
||||||
|
|
||||||
puts(ptr);
|
|
||||||
|
|
||||||
memset(ptr, 55, strlen(ptr)+1);
|
|
||||||
|
|
||||||
free(ptr);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988);
|
|
||||||
puts(buffer);
|
|
||||||
|
|
||||||
curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65);
|
|
||||||
|
|
||||||
printf("%s %#08x\n", "dummy", 65);
|
|
||||||
{
|
|
||||||
double tryout = 3.14156592;
|
|
||||||
curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout);
|
|
||||||
puts(buffer);
|
|
||||||
printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
95
lib/multi.c
95
lib/multi.c
@@ -674,7 +674,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
|||||||
|
|
||||||
/* we must call Curl_done() here (if we still "own it") so that we don't
|
/* we must call Curl_done() here (if we still "own it") so that we don't
|
||||||
leave a half-baked one around */
|
leave a half-baked one around */
|
||||||
if (easy_owns_conn) {
|
if(easy_owns_conn) {
|
||||||
|
|
||||||
/* Curl_done() clears the conn->data field to lose the association
|
/* Curl_done() clears the conn->data field to lose the association
|
||||||
between the easy handle and the connection
|
between the easy handle and the connection
|
||||||
@@ -855,7 +855,7 @@ static int multi_getsock(struct Curl_one_easy *easy,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case CURLM_STATE_WAITRESOLVE:
|
case CURLM_STATE_WAITRESOLVE:
|
||||||
return Curl_resolv_getsock(easy->easy_conn, socks, numsocks);
|
return Curl_resolver_getsock(easy->easy_conn, socks, numsocks);
|
||||||
|
|
||||||
case CURLM_STATE_PROTOCONNECT:
|
case CURLM_STATE_PROTOCONNECT:
|
||||||
return Curl_protocol_getsock(easy->easy_conn, socks, numsocks);
|
return Curl_protocol_getsock(easy->easy_conn, socks, numsocks);
|
||||||
@@ -1071,7 +1071,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
|
|
||||||
/* check if we have the name resolved by now */
|
/* check if we have the name resolved by now */
|
||||||
easy->result = Curl_is_resolved(easy->easy_conn, &dns);
|
easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns);
|
||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
/* Update sockets here. Mainly because the socket(s) may have been
|
/* Update sockets here. Mainly because the socket(s) may have been
|
||||||
@@ -1128,7 +1128,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
multistate(easy, CURLM_STATE_CONNECT);
|
multistate(easy, CURLM_STATE_CONNECT);
|
||||||
}
|
}
|
||||||
else if (CURLE_OK == easy->result) {
|
else if(CURLE_OK == easy->result) {
|
||||||
if(!easy->easy_conn->bits.tunnel_connecting)
|
if(!easy->easy_conn->bits.tunnel_connecting)
|
||||||
multistate(easy, CURLM_STATE_WAITCONNECT);
|
multistate(easy, CURLM_STATE_WAITCONNECT);
|
||||||
}
|
}
|
||||||
@@ -1141,8 +1141,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
FIRSTSOCKET,
|
FIRSTSOCKET,
|
||||||
&connected);
|
&connected);
|
||||||
if(connected) {
|
if(connected) {
|
||||||
/* see if we need to do any proxy magic first once we connected */
|
|
||||||
easy->result = Curl_connected_proxy(easy->easy_conn);
|
|
||||||
|
|
||||||
if(!easy->result)
|
if(!easy->result)
|
||||||
/* if everything is still fine we do the protocol-specific connect
|
/* if everything is still fine we do the protocol-specific connect
|
||||||
@@ -1265,8 +1263,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((CURLE_SEND_ERROR == easy->result) &&
|
else if((CURLE_SEND_ERROR == easy->result) &&
|
||||||
easy->easy_conn->bits.reuse) {
|
easy->easy_conn->bits.reuse) {
|
||||||
/*
|
/*
|
||||||
* In this situation, a connection that we were trying to use
|
* In this situation, a connection that we were trying to use
|
||||||
* may have unexpectedly died. If possible, send the connection
|
* may have unexpectedly died. If possible, send the connection
|
||||||
@@ -1292,7 +1290,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
/* When set to retry the connection, we must to go back to
|
/* When set to retry the connection, we must to go back to
|
||||||
* the CONNECT state */
|
* the CONNECT state */
|
||||||
if(retry) {
|
if(retry) {
|
||||||
if ((drc == CURLE_OK) || (drc == CURLE_SEND_ERROR)) {
|
if((drc == CURLE_OK) || (drc == CURLE_SEND_ERROR)) {
|
||||||
follow = FOLLOW_RETRY;
|
follow = FOLLOW_RETRY;
|
||||||
drc = Curl_follow(data, newurl, follow);
|
drc = Curl_follow(data, newurl, follow);
|
||||||
if(drc == CURLE_OK) {
|
if(drc == CURLE_OK) {
|
||||||
@@ -1415,17 +1413,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
|
case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
|
||||||
/* if both rates are within spec, resume transfer */
|
/* if both rates are within spec, resume transfer */
|
||||||
Curl_pgrsUpdate(easy->easy_conn);
|
Curl_pgrsUpdate(easy->easy_conn);
|
||||||
if( ( (data->set.max_send_speed == 0) ||
|
if(( (data->set.max_send_speed == 0) ||
|
||||||
(data->progress.ulspeed < data->set.max_send_speed )) &&
|
(data->progress.ulspeed < data->set.max_send_speed )) &&
|
||||||
( (data->set.max_recv_speed == 0) ||
|
( (data->set.max_recv_speed == 0) ||
|
||||||
(data->progress.dlspeed < data->set.max_recv_speed) ) )
|
(data->progress.dlspeed < data->set.max_recv_speed)))
|
||||||
multistate(easy, CURLM_STATE_PERFORM);
|
multistate(easy, CURLM_STATE_PERFORM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLM_STATE_PERFORM:
|
case CURLM_STATE_PERFORM:
|
||||||
/* check if over send speed */
|
/* check if over send speed */
|
||||||
if( (data->set.max_send_speed > 0) &&
|
if((data->set.max_send_speed > 0) &&
|
||||||
(data->progress.ulspeed > data->set.max_send_speed) ) {
|
(data->progress.ulspeed > data->set.max_send_speed)) {
|
||||||
int buffersize;
|
int buffersize;
|
||||||
|
|
||||||
multistate(easy, CURLM_STATE_TOOFAST);
|
multistate(easy, CURLM_STATE_TOOFAST);
|
||||||
@@ -1440,8 +1438,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if over recv speed */
|
/* check if over recv speed */
|
||||||
if( (data->set.max_recv_speed > 0) &&
|
if((data->set.max_recv_speed > 0) &&
|
||||||
(data->progress.dlspeed > data->set.max_recv_speed) ) {
|
(data->progress.dlspeed > data->set.max_recv_speed)) {
|
||||||
int buffersize;
|
int buffersize;
|
||||||
|
|
||||||
multistate(easy, CURLM_STATE_TOOFAST);
|
multistate(easy, CURLM_STATE_TOOFAST);
|
||||||
@@ -1535,11 +1533,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
|
|
||||||
/* but first check to see if we got a location info even though we're
|
/* but first check to see if we got a location info even though we're
|
||||||
not following redirects */
|
not following redirects */
|
||||||
if (data->req.location) {
|
if(data->req.location) {
|
||||||
newurl = data->req.location;
|
newurl = data->req.location;
|
||||||
data->req.location = NULL;
|
data->req.location = NULL;
|
||||||
easy->result = Curl_follow(data, newurl, FOLLOW_FAKE);
|
easy->result = Curl_follow(data, newurl, FOLLOW_FAKE);
|
||||||
if (easy->result)
|
if(easy->result)
|
||||||
free(newurl);
|
free(newurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1577,7 +1575,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
* access free'd data, if the connection is free'd and the handle
|
* access free'd data, if the connection is free'd and the handle
|
||||||
* removed before we perform the processing in CURLM_STATE_COMPLETED
|
* removed before we perform the processing in CURLM_STATE_COMPLETED
|
||||||
*/
|
*/
|
||||||
if (easy->easy_conn)
|
if(easy->easy_conn)
|
||||||
easy->easy_conn = NULL;
|
easy->easy_conn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1710,7 +1708,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
|
|
||||||
do
|
do
|
||||||
result = multi_runsingle(multi, now, easy);
|
result = multi_runsingle(multi, now, easy);
|
||||||
while (CURLM_CALL_MULTI_PERFORM == result);
|
while(CURLM_CALL_MULTI_PERFORM == result);
|
||||||
|
|
||||||
if(easy->easy_handle->set.wildcardmatch) {
|
if(easy->easy_handle->set.wildcardmatch) {
|
||||||
/* destruct wildcard structures if it is needed */
|
/* destruct wildcard structures if it is needed */
|
||||||
@@ -1744,7 +1742,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
|
|
||||||
*running_handles = multi->num_alive;
|
*running_handles = multi->num_alive;
|
||||||
|
|
||||||
if( CURLM_OK >= returncode )
|
if(CURLM_OK >= returncode)
|
||||||
update_timer(multi);
|
update_timer(multi);
|
||||||
|
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -1954,29 +1952,29 @@ static void singlesocket(struct Curl_multi *multi,
|
|||||||
easy_by_hash = entry->easy->multi_pos;
|
easy_by_hash = entry->easy->multi_pos;
|
||||||
easy_conn = easy_by_hash->easy_conn;
|
easy_conn = easy_by_hash->easy_conn;
|
||||||
if(easy_conn) {
|
if(easy_conn) {
|
||||||
if (easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
|
if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
|
||||||
/* the handle should not be removed from the pipe yet */
|
/* the handle should not be removed from the pipe yet */
|
||||||
remove_sock_from_hash = FALSE;
|
remove_sock_from_hash = FALSE;
|
||||||
|
|
||||||
/* Update the sockhash entry to instead point to the next in line
|
/* Update the sockhash entry to instead point to the next in line
|
||||||
for the recv_pipe, or the first (in case this particular easy
|
for the recv_pipe, or the first (in case this particular easy
|
||||||
isn't already) */
|
isn't already) */
|
||||||
if (entry->easy == easy->easy_handle) {
|
if(entry->easy == easy->easy_handle) {
|
||||||
if (isHandleAtHead(easy->easy_handle, easy_conn->recv_pipe))
|
if(isHandleAtHead(easy->easy_handle, easy_conn->recv_pipe))
|
||||||
entry->easy = easy_conn->recv_pipe->head->next->ptr;
|
entry->easy = easy_conn->recv_pipe->head->next->ptr;
|
||||||
else
|
else
|
||||||
entry->easy = easy_conn->recv_pipe->head->ptr;
|
entry->easy = easy_conn->recv_pipe->head->ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
|
if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
|
||||||
/* the handle should not be removed from the pipe yet */
|
/* the handle should not be removed from the pipe yet */
|
||||||
remove_sock_from_hash = FALSE;
|
remove_sock_from_hash = FALSE;
|
||||||
|
|
||||||
/* Update the sockhash entry to instead point to the next in line
|
/* Update the sockhash entry to instead point to the next in line
|
||||||
for the send_pipe, or the first (in case this particular easy
|
for the send_pipe, or the first (in case this particular easy
|
||||||
isn't already) */
|
isn't already) */
|
||||||
if (entry->easy == easy->easy_handle) {
|
if(entry->easy == easy->easy_handle) {
|
||||||
if (isHandleAtHead(easy->easy_handle, easy_conn->send_pipe))
|
if(isHandleAtHead(easy->easy_handle, easy_conn->send_pipe))
|
||||||
entry->easy = easy_conn->send_pipe->head->next->ptr;
|
entry->easy = easy_conn->send_pipe->head->next->ptr;
|
||||||
else
|
else
|
||||||
entry->easy = easy_conn->send_pipe->head->ptr;
|
entry->easy = easy_conn->send_pipe->head->ptr;
|
||||||
@@ -1994,7 +1992,7 @@ static void singlesocket(struct Curl_multi *multi,
|
|||||||
either since it never got to know about it */
|
either since it never got to know about it */
|
||||||
remove_sock_from_hash = FALSE;
|
remove_sock_from_hash = FALSE;
|
||||||
|
|
||||||
if (remove_sock_from_hash) {
|
if(remove_sock_from_hash) {
|
||||||
multi->socket_cb(easy->easy_handle,
|
multi->socket_cb(easy->easy_handle,
|
||||||
s,
|
s,
|
||||||
CURL_POLL_REMOVE,
|
CURL_POLL_REMOVE,
|
||||||
@@ -2116,13 +2114,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
the pipeline. If we should write into the socket, take the send_pipe
|
the pipeline. If we should write into the socket, take the send_pipe
|
||||||
head. If we should read from the socket, take the recv_pipe head. */
|
head. If we should read from the socket, take the recv_pipe head. */
|
||||||
if(data->set.one_easy->easy_conn) {
|
if(data->set.one_easy->easy_conn) {
|
||||||
if ((ev_bitmask & CURL_POLL_OUT) &&
|
if((ev_bitmask & CURL_POLL_OUT) &&
|
||||||
data->set.one_easy->easy_conn->send_pipe &&
|
data->set.one_easy->easy_conn->send_pipe &&
|
||||||
data->set.one_easy->easy_conn->send_pipe->head)
|
data->set.one_easy->easy_conn->send_pipe->head)
|
||||||
data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
|
data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
|
||||||
else if ((ev_bitmask & CURL_POLL_IN) &&
|
else if((ev_bitmask & CURL_POLL_IN) &&
|
||||||
data->set.one_easy->easy_conn->recv_pipe &&
|
data->set.one_easy->easy_conn->recv_pipe &&
|
||||||
data->set.one_easy->easy_conn->recv_pipe->head)
|
data->set.one_easy->easy_conn->recv_pipe->head)
|
||||||
data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
|
data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2133,7 +2131,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
|
|
||||||
do
|
do
|
||||||
result = multi_runsingle(multi, now, data->set.one_easy);
|
result = multi_runsingle(multi, now, data->set.one_easy);
|
||||||
while (CURLM_CALL_MULTI_PERFORM == result);
|
while(CURLM_CALL_MULTI_PERFORM == result);
|
||||||
|
|
||||||
if(data->set.one_easy->easy_conn &&
|
if(data->set.one_easy->easy_conn &&
|
||||||
!(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
|
!(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
|
||||||
@@ -2171,7 +2169,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
if(data) {
|
if(data) {
|
||||||
do
|
do
|
||||||
result = multi_runsingle(multi, now, data->set.one_easy);
|
result = multi_runsingle(multi, now, data->set.one_easy);
|
||||||
while (CURLM_CALL_MULTI_PERFORM == result);
|
while(CURLM_CALL_MULTI_PERFORM == result);
|
||||||
|
|
||||||
if(CURLM_OK >= result)
|
if(CURLM_OK >= result)
|
||||||
/* get the socket(s) and check if the state has been changed since
|
/* get the socket(s) and check if the state has been changed since
|
||||||
@@ -2327,7 +2325,7 @@ static int update_timer(struct Curl_multi *multi)
|
|||||||
if(multi_timeout(multi, &timeout_ms)) {
|
if(multi_timeout(multi, &timeout_ms)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( timeout_ms < 0 ) {
|
if(timeout_ms < 0) {
|
||||||
static const struct timeval none={0,0};
|
static const struct timeval none={0,0};
|
||||||
if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
|
if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
|
||||||
multi->timer_lastcall = none;
|
multi->timer_lastcall = none;
|
||||||
@@ -2371,14 +2369,14 @@ static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
|
|||||||
|
|
||||||
rc = Curl_addHandleToPipeline(handle, pipeline);
|
rc = Curl_addHandleToPipeline(handle, pipeline);
|
||||||
|
|
||||||
if (pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
||||||
/* this is a new one as head, expire it */
|
/* this is a new one as head, expire it */
|
||||||
conn->writechannel_inuse = FALSE; /* not in use yet */
|
conn->writechannel_inuse = FALSE; /* not in use yet */
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
infof(conn->data, "%p is at send pipe head!\n",
|
infof(conn->data, "%p is at send pipe head!\n",
|
||||||
conn->send_pipe->head->ptr);
|
conn->send_pipe->head->ptr);
|
||||||
#endif
|
#endif
|
||||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2390,7 +2388,7 @@ static int checkPendPipeline(struct connectdata *conn)
|
|||||||
struct curl_llist_element *sendhead = conn->send_pipe->head;
|
struct curl_llist_element *sendhead = conn->send_pipe->head;
|
||||||
|
|
||||||
size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
|
size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
|
||||||
if (conn->server_supports_pipelining || pipeLen == 0) {
|
if(conn->server_supports_pipelining || pipeLen == 0) {
|
||||||
struct curl_llist_element *curr = conn->pend_pipe->head;
|
struct curl_llist_element *curr = conn->pend_pipe->head;
|
||||||
const size_t maxPipeLen =
|
const size_t maxPipeLen =
|
||||||
conn->server_supports_pipelining ? MAX_PIPELINE_LENGTH : 1;
|
conn->server_supports_pipelining ? MAX_PIPELINE_LENGTH : 1;
|
||||||
@@ -2405,7 +2403,7 @@ static int checkPendPipeline(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if(result) {
|
||||||
conn->now = Curl_tvnow();
|
conn->now = Curl_tvnow();
|
||||||
/* something moved, check for a new send pipeline leader */
|
/* something moved, check for a new send pipeline leader */
|
||||||
if(sendhead != conn->send_pipe->head) {
|
if(sendhead != conn->send_pipe->head) {
|
||||||
@@ -2746,7 +2744,8 @@ static CURLMcode add_closure(struct Curl_multi *multi,
|
|||||||
else
|
else
|
||||||
multi->closure = n;
|
multi->closure = n;
|
||||||
free(cl);
|
free(cl);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if(cl->easy_handle == data)
|
if(cl->easy_handle == data)
|
||||||
add = FALSE;
|
add = FALSE;
|
||||||
|
|
||||||
@@ -2756,7 +2755,7 @@ static CURLMcode add_closure(struct Curl_multi *multi,
|
|||||||
cl = n;
|
cl = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add) {
|
if(add) {
|
||||||
cl = calloc(1, sizeof(struct closure));
|
cl = calloc(1, sizeof(struct closure));
|
||||||
if(!cl)
|
if(!cl)
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
|
|||||||
@@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -61,6 +61,9 @@ enum host_lookup_state {
|
|||||||
HOSTEND /* LAST enum */
|
HOSTEND /* LAST enum */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unittest: 1304
|
||||||
|
*/
|
||||||
int Curl_parsenetrc(const char *host,
|
int Curl_parsenetrc(const char *host,
|
||||||
char *login,
|
char *login,
|
||||||
char *password,
|
char *password,
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
|||||||
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
failf(data,
|
failf(data,
|
||||||
"The Curl_convert_from_network iconv call failed with errno %i: %s",
|
"Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||||
error, strerror(error));
|
error, strerror(error));
|
||||||
return CURLE_CONV_FAILED;
|
return CURLE_CONV_FAILED;
|
||||||
}
|
}
|
||||||
@@ -296,13 +296,13 @@ void Curl_convert_close(struct SessionHandle *data)
|
|||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
/* close iconv conversion descriptors */
|
/* close iconv conversion descriptors */
|
||||||
if(data->inbound_cd != (iconv_t)-1) {
|
if(data->inbound_cd != (iconv_t)-1) {
|
||||||
iconv_close(data->inbound_cd);
|
iconv_close(data->inbound_cd);
|
||||||
}
|
}
|
||||||
if(data->outbound_cd != (iconv_t)-1) {
|
if(data->outbound_cd != (iconv_t)-1) {
|
||||||
iconv_close(data->outbound_cd);
|
iconv_close(data->outbound_cd);
|
||||||
}
|
}
|
||||||
if(data->utf8_cd != (iconv_t)-1) {
|
if(data->utf8_cd != (iconv_t)-1) {
|
||||||
iconv_close(data->utf8_cd);
|
iconv_close(data->utf8_cd);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#ifndef HEADER_CURL_NON_ASCII_H
|
||||||
|
#define HEADER_CURL_NON_ASCII_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
@@ -48,8 +50,7 @@ CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
|||||||
char *buffer, size_t length);
|
char *buffer, size_t length);
|
||||||
CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form);
|
CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form);
|
||||||
#else
|
#else
|
||||||
#define Curl_convert_clone(a,b,c,d) \
|
#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
|
||||||
((void)a, (void)b, (void)c, *(d)=NULL, CURLE_OK)
|
|
||||||
#define Curl_convert_init(x)
|
#define Curl_convert_init(x)
|
||||||
#define Curl_convert_setup(x)
|
#define Curl_convert_setup(x)
|
||||||
#define Curl_convert_close(x)
|
#define Curl_convert_close(x)
|
||||||
@@ -58,3 +59,5 @@ CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form);
|
|||||||
#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
|
#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
|
||||||
#define Curl_convert_form(a,b) CURLE_OK
|
#define Curl_convert_form(a,b) CURLE_OK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* HEADER_CURL_NON_ASCII_H */
|
||||||
|
|||||||
63
lib/nss.c
63
lib/nss.c
@@ -282,9 +282,9 @@ static int is_file(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return on heap allocated filename/nickname of a certificate. The returned
|
/* Return on heap allocated filename/nickname of a certificate. The returned
|
||||||
* string should be later deallocated using free(). *is_nickname is set to TRUE
|
* string should be later deallocated using free(). *is_nickname is set to
|
||||||
* if the given string is treated as nickname; FALSE if the given string is
|
* TRUE if the given string is treated as nickname; FALSE if the given string
|
||||||
* treated as file name.
|
* is treated as file name.
|
||||||
*/
|
*/
|
||||||
static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
|
static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
|
||||||
bool *is_nickname)
|
bool *is_nickname)
|
||||||
@@ -662,7 +662,8 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
|
|||||||
if(conn->data->set.ssl.verifyhost) {
|
if(conn->data->set.ssl.verifyhost) {
|
||||||
failf(conn->data, "SSL: certificate subject name '%s' does not match "
|
failf(conn->data, "SSL: certificate subject name '%s' does not match "
|
||||||
"target host name '%s'", subject_cn, conn->host.dispname);
|
"target host name '%s'", subject_cn, conn->host.dispname);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
result = SECSuccess;
|
result = SECSuccess;
|
||||||
infof(conn->data, "warning: SSL: certificate subject name '%s' does not "
|
infof(conn->data, "warning: SSL: certificate subject name '%s' does not "
|
||||||
"match target host name '%s'\n", subject_cn, conn->host.dispname);
|
"match target host name '%s'\n", subject_cn, conn->host.dispname);
|
||||||
@@ -778,10 +779,10 @@ static SECStatus check_issuer_cert(PRFileDesc *sock,
|
|||||||
issuer = NULL;
|
issuer = NULL;
|
||||||
issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
|
issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
|
||||||
|
|
||||||
if ((!cert_issuer) || (!issuer))
|
if((!cert_issuer) || (!issuer))
|
||||||
res = SECFailure;
|
res = SECFailure;
|
||||||
else if (SECITEM_CompareItem(&cert_issuer->derCert,
|
else if(SECITEM_CompareItem(&cert_issuer->derCert,
|
||||||
&issuer->derCert)!=SECEqual)
|
&issuer->derCert)!=SECEqual)
|
||||||
res = SECFailure;
|
res = SECFailure;
|
||||||
|
|
||||||
CERT_DestroyCertificate(cert);
|
CERT_DestroyCertificate(cert);
|
||||||
@@ -806,8 +807,8 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
struct SessionHandle *data = connssl->data;
|
struct SessionHandle *data = connssl->data;
|
||||||
const char *nickname = connssl->client_nickname;
|
const char *nickname = connssl->client_nickname;
|
||||||
|
|
||||||
if (mod && nickname &&
|
if(mod && nickname &&
|
||||||
0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {
|
0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {
|
||||||
|
|
||||||
/* use the cert/key provided by PEM reader */
|
/* use the cert/key provided by PEM reader */
|
||||||
PK11SlotInfo *slot;
|
PK11SlotInfo *slot;
|
||||||
@@ -815,20 +816,20 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
*pRetKey = NULL;
|
*pRetKey = NULL;
|
||||||
|
|
||||||
*pRetCert = PK11_FindCertFromNickname(nickname, proto_win);
|
*pRetCert = PK11_FindCertFromNickname(nickname, proto_win);
|
||||||
if (NULL == *pRetCert) {
|
if(NULL == *pRetCert) {
|
||||||
failf(data, "NSS: client certificate not found: %s", nickname);
|
failf(data, "NSS: client certificate not found: %s", nickname);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
slot = PK11_FindSlotByName(pem_slotname);
|
slot = PK11_FindSlotByName(pem_slotname);
|
||||||
if (NULL == slot) {
|
if(NULL == slot) {
|
||||||
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
|
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
|
*pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
|
||||||
PK11_FreeSlot(slot);
|
PK11_FreeSlot(slot);
|
||||||
if (NULL == *pRetKey) {
|
if(NULL == *pRetKey) {
|
||||||
failf(data, "NSS: private key not found for certificate: %s", nickname);
|
failf(data, "NSS: private key not found for certificate: %s", nickname);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
@@ -839,11 +840,11 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* use the default NSS hook */
|
/* use the default NSS hook */
|
||||||
if (SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
|
if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
|
||||||
pRetCert, pRetKey)
|
pRetCert, pRetKey)
|
||||||
|| NULL == *pRetCert) {
|
|| NULL == *pRetCert) {
|
||||||
|
|
||||||
if (NULL == nickname)
|
if(NULL == nickname)
|
||||||
failf(data, "NSS: client certificate not found (nickname not "
|
failf(data, "NSS: client certificate not found (nickname not "
|
||||||
"specified)");
|
"specified)");
|
||||||
else
|
else
|
||||||
@@ -854,10 +855,10 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
|
|
||||||
/* get certificate nickname if any */
|
/* get certificate nickname if any */
|
||||||
nickname = (*pRetCert)->nickname;
|
nickname = (*pRetCert)->nickname;
|
||||||
if (NULL == nickname)
|
if(NULL == nickname)
|
||||||
nickname = "[unknown]";
|
nickname = "[unknown]";
|
||||||
|
|
||||||
if (NULL == *pRetKey) {
|
if(NULL == *pRetKey) {
|
||||||
failf(data, "NSS: private key not found for certificate: %s", nickname);
|
failf(data, "NSS: private key not found for certificate: %s", nickname);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
@@ -931,7 +932,8 @@ static CURLcode init_nss(struct SessionHandle *data)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *certpath =
|
char *certpath =
|
||||||
PR_smprintf("%s%s", NSS_VersionCheck("3.12.0") ? "sql:" : "", cert_dir);
|
PR_smprintf("%s%s", NSS_VersionCheck("3.12.0") ? "sql:" : "",
|
||||||
|
cert_dir);
|
||||||
rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
|
rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
|
||||||
PR_smprintf_free(certpath);
|
PR_smprintf_free(certpath);
|
||||||
}
|
}
|
||||||
@@ -957,7 +959,7 @@ static CURLcode init_nss(struct SessionHandle *data)
|
|||||||
int Curl_nss_init(void)
|
int Curl_nss_init(void)
|
||||||
{
|
{
|
||||||
/* curl_global_init() is not thread-safe so this test is ok */
|
/* curl_global_init() is not thread-safe so this test is ok */
|
||||||
if (nss_initlock == NULL) {
|
if(nss_initlock == NULL) {
|
||||||
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
|
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
|
||||||
nss_initlock = PR_NewLock();
|
nss_initlock = PR_NewLock();
|
||||||
nss_crllock = PR_NewLock();
|
nss_crllock = PR_NewLock();
|
||||||
@@ -972,9 +974,10 @@ CURLcode Curl_nss_force_init(struct SessionHandle *data)
|
|||||||
{
|
{
|
||||||
CURLcode rv;
|
CURLcode rv;
|
||||||
if(!nss_initlock) {
|
if(!nss_initlock) {
|
||||||
failf(data, "unable to initialize NSS, curl_global_init() should have been "
|
failf(data,
|
||||||
"called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
|
"unable to initialize NSS, curl_global_init() should have been "
|
||||||
return CURLE_OUT_OF_MEMORY;
|
"called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_Lock(nss_initlock);
|
PR_Lock(nss_initlock);
|
||||||
@@ -990,7 +993,7 @@ void Curl_nss_cleanup(void)
|
|||||||
* as a safety feature.
|
* as a safety feature.
|
||||||
*/
|
*/
|
||||||
PR_Lock(nss_initlock);
|
PR_Lock(nss_initlock);
|
||||||
if (initialized) {
|
if(initialized) {
|
||||||
/* Free references to client certificates held in the SSL session cache.
|
/* Free references to client certificates held in the SSL session cache.
|
||||||
* Omitting this hampers destruction of the security module owning
|
* Omitting this hampers destruction of the security module owning
|
||||||
* the certificates. */
|
* the certificates. */
|
||||||
@@ -1167,7 +1170,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
long time_left;
|
long time_left;
|
||||||
PRUint32 timeout;
|
PRUint32 timeout;
|
||||||
|
|
||||||
if (connssl->state == ssl_connection_complete)
|
if(connssl->state == ssl_connection_complete)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
connssl->data = data;
|
connssl->data = data;
|
||||||
@@ -1240,7 +1243,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
default:
|
default:
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
ssl3 = PR_TRUE;
|
ssl3 = PR_TRUE;
|
||||||
if (data->state.ssl_connect_retry)
|
if(data->state.ssl_connect_retry)
|
||||||
infof(data, "TLS disabled due to previous handshake failure\n");
|
infof(data, "TLS disabled due to previous handshake failure\n");
|
||||||
else
|
else
|
||||||
tlsv1 = PR_TRUE;
|
tlsv1 = PR_TRUE;
|
||||||
@@ -1271,8 +1274,8 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
|
|
||||||
/* enable all ciphers from enable_ciphers_by_default */
|
/* enable all ciphers from enable_ciphers_by_default */
|
||||||
cipher_to_enable = enable_ciphers_by_default;
|
cipher_to_enable = enable_ciphers_by_default;
|
||||||
while (SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
|
while(SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
|
||||||
if (SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
|
if(SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
|
||||||
curlerr = CURLE_SSL_CIPHER;
|
curlerr = CURLE_SSL_CIPHER;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -1313,7 +1316,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->set.ssl.CRLfile) {
|
if(data->set.ssl.CRLfile) {
|
||||||
if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
|
if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
|
||||||
curlerr = CURLE_SSL_CRL_BADFILE;
|
curlerr = CURLE_SSL_CRL_BADFILE;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1358,7 +1361,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
model = NULL;
|
model = NULL;
|
||||||
|
|
||||||
/* This is the password associated with the cert that we're using */
|
/* This is the password associated with the cert that we're using */
|
||||||
if (data->set.str[STRING_KEY_PASSWD]) {
|
if(data->set.str[STRING_KEY_PASSWD]) {
|
||||||
SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
|
SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1390,7 +1393,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
|
|
||||||
display_conn_info(conn, connssl->handle);
|
display_conn_info(conn, connssl->handle);
|
||||||
|
|
||||||
if (data->set.str[STRING_SSL_ISSUERCERT]) {
|
if(data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||||
SECStatus ret = SECFailure;
|
SECStatus ret = SECFailure;
|
||||||
bool is_nickname;
|
bool is_nickname;
|
||||||
char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
|
char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
|
||||||
@@ -1434,7 +1437,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
connssl->obj_list = NULL;
|
connssl->obj_list = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
|
if(ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
|
||||||
/* schedule reconnect through Curl_retry_request() */
|
/* schedule reconnect through Curl_retry_request() */
|
||||||
data->state.ssl_connect_retry = TRUE;
|
data->state.ssl_connect_retry = TRUE;
|
||||||
infof(data, "Error in TLS handshake, trying SSLv3...\n");
|
infof(data, "Error in TLS handshake, trying SSLv3...\n");
|
||||||
|
|||||||
140
lib/openldap.c
140
lib/openldap.c
@@ -55,7 +55,8 @@
|
|||||||
|
|
||||||
#ifndef _LDAP_PVT_H
|
#ifndef _LDAP_PVT_H
|
||||||
extern int ldap_pvt_url_scheme2proto(const char *);
|
extern int ldap_pvt_url_scheme2proto(const char *);
|
||||||
extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, LDAP **ld);
|
extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
|
||||||
|
LDAP **ld);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CURLcode ldap_setup(struct connectdata *conn);
|
static CURLcode ldap_setup(struct connectdata *conn);
|
||||||
@@ -63,7 +64,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done);
|
|||||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
|
static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
|
||||||
static CURLcode ldap_connect(struct connectdata *conn, bool *done);
|
static CURLcode ldap_connect(struct connectdata *conn, bool *done);
|
||||||
static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
|
static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
|
||||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection);
|
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
|
||||||
|
|
||||||
static Curl_recv ldap_recv;
|
static Curl_recv ldap_recv;
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ const struct Curl_handler Curl_handler_ldap = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ldap_disconnect, /* disconnect */
|
ldap_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_LDAP, /* defport */
|
PORT_LDAP, /* defport */
|
||||||
CURLPROTO_LDAP, /* protocol */
|
CURLPROTO_LDAP, /* protocol */
|
||||||
PROTOPT_NONE /* flags */
|
PROTOPT_NONE /* flags */
|
||||||
@@ -107,6 +109,7 @@ const struct Curl_handler Curl_handler_ldaps = {
|
|||||||
ZERO_NULL, /* doing_getsock */
|
ZERO_NULL, /* doing_getsock */
|
||||||
ZERO_NULL, /* perform_getsock */
|
ZERO_NULL, /* perform_getsock */
|
||||||
ldap_disconnect, /* disconnect */
|
ldap_disconnect, /* disconnect */
|
||||||
|
ZERO_NULL, /* readwrite */
|
||||||
PORT_LDAPS, /* defport */
|
PORT_LDAPS, /* defport */
|
||||||
CURLPROTO_LDAP, /* protocol */
|
CURLPROTO_LDAP, /* protocol */
|
||||||
PROTOPT_SSL /* flags */
|
PROTOPT_SSL /* flags */
|
||||||
@@ -152,11 +155,11 @@ static CURLcode ldap_setup(struct connectdata *conn)
|
|||||||
CURLcode status;
|
CURLcode status;
|
||||||
|
|
||||||
rc = ldap_url_parse(data->change.url, &lud);
|
rc = ldap_url_parse(data->change.url, &lud);
|
||||||
if (rc != LDAP_URL_SUCCESS) {
|
if(rc != LDAP_URL_SUCCESS) {
|
||||||
const char *msg = "url parsing problem";
|
const char *msg = "url parsing problem";
|
||||||
status = CURLE_URL_MALFORMAT;
|
status = CURLE_URL_MALFORMAT;
|
||||||
if (rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
||||||
if (rc == LDAP_URL_ERR_MEM)
|
if(rc == LDAP_URL_ERR_MEM)
|
||||||
status = CURLE_OUT_OF_MEMORY;
|
status = CURLE_OUT_OF_MEMORY;
|
||||||
msg = url_errs[rc];
|
msg = url_errs[rc];
|
||||||
}
|
}
|
||||||
@@ -189,13 +192,13 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
strcpy(hosturl, "ldap");
|
strcpy(hosturl, "ldap");
|
||||||
ptr = hosturl+4;
|
ptr = hosturl+4;
|
||||||
if (conn->handler->flags & PROTOPT_SSL)
|
if(conn->handler->flags & PROTOPT_SSL)
|
||||||
*ptr++ = 's';
|
*ptr++ = 's';
|
||||||
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
|
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
|
||||||
conn->host.name, conn->remote_port);
|
conn->host.name, conn->remote_port);
|
||||||
|
|
||||||
rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
|
rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
|
||||||
if (rc) {
|
if(rc) {
|
||||||
failf(data, "LDAP local: Cannot connect to %s, %s",
|
failf(data, "LDAP local: Cannot connect to %s, %s",
|
||||||
hosturl, ldap_err2string(rc));
|
hosturl, ldap_err2string(rc));
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
@@ -231,22 +234,23 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->handler->flags & PROTOPT_SSL) {
|
if(conn->handler->flags & PROTOPT_SSL) {
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
if (data->state.used_interface == Curl_if_easy) {
|
if(data->state.used_interface == Curl_if_easy) {
|
||||||
res = Curl_ssl_connect(conn, FIRSTSOCKET);
|
res = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if (res)
|
if(res)
|
||||||
return res;
|
return res;
|
||||||
li->ssldone = TRUE;
|
li->ssldone = TRUE;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
|
res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
|
||||||
if (res)
|
if(res)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (data->state.used_interface == Curl_if_easy)
|
if(data->state.used_interface == Curl_if_easy)
|
||||||
return ldap_connecting(conn, done);
|
return ldap_connecting(conn, done);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -262,15 +266,16 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
|||||||
char *info = NULL;
|
char *info = NULL;
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->handler->flags & PROTOPT_SSL) {
|
if(conn->handler->flags & PROTOPT_SSL) {
|
||||||
/* Is the SSL handshake complete yet? */
|
/* Is the SSL handshake complete yet? */
|
||||||
if (!li->ssldone) {
|
if(!li->ssldone) {
|
||||||
CURLcode res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
|
CURLcode res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
|
||||||
if (res || !li->ssldone)
|
&li->ssldone);
|
||||||
|
if(res || !li->ssldone)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/* Have we installed the libcurl SSL handlers into the sockbuf yet? */
|
/* Have we installed the libcurl SSL handlers into the sockbuf yet? */
|
||||||
if (!li->sslinst) {
|
if(!li->sslinst) {
|
||||||
Sockbuf *sb;
|
Sockbuf *sb;
|
||||||
ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
|
ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
|
||||||
ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
|
ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
|
||||||
@@ -281,53 +286,54 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (data->state.used_interface == Curl_if_easy)
|
if(data->state.used_interface == Curl_if_easy)
|
||||||
tvp = NULL; /* let ldap_result block indefinitely */
|
tvp = NULL; /* let ldap_result block indefinitely */
|
||||||
else
|
else
|
||||||
tvp = &tv;
|
tvp = &tv;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (!li->didbind) {
|
if(!li->didbind) {
|
||||||
char *binddn;
|
char *binddn;
|
||||||
struct berval passwd;
|
struct berval passwd;
|
||||||
|
|
||||||
if (conn->bits.user_passwd) {
|
if(conn->bits.user_passwd) {
|
||||||
binddn = conn->user;
|
binddn = conn->user;
|
||||||
passwd.bv_val = conn->passwd;
|
passwd.bv_val = conn->passwd;
|
||||||
passwd.bv_len = strlen(passwd.bv_val);
|
passwd.bv_len = strlen(passwd.bv_val);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
binddn = NULL;
|
binddn = NULL;
|
||||||
passwd.bv_val = NULL;
|
passwd.bv_val = NULL;
|
||||||
passwd.bv_len = 0;
|
passwd.bv_len = 0;
|
||||||
}
|
}
|
||||||
rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
|
rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
|
||||||
NULL, NULL, &li->msgid);
|
NULL, NULL, &li->msgid);
|
||||||
if (rc)
|
if(rc)
|
||||||
return CURLE_LDAP_CANNOT_BIND;
|
return CURLE_LDAP_CANNOT_BIND;
|
||||||
li->didbind = TRUE;
|
li->didbind = TRUE;
|
||||||
if (tvp)
|
if(tvp)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &result);
|
rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &result);
|
||||||
if (rc < 0) {
|
if(rc < 0) {
|
||||||
failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
|
failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
|
||||||
return CURLE_LDAP_CANNOT_BIND;
|
return CURLE_LDAP_CANNOT_BIND;
|
||||||
}
|
}
|
||||||
if (rc == 0) {
|
if(rc == 0) {
|
||||||
/* timed out */
|
/* timed out */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
rc = ldap_parse_result(li->ld, result, &err, NULL, &info, NULL, NULL, 1);
|
rc = ldap_parse_result(li->ld, result, &err, NULL, &info, NULL, NULL, 1);
|
||||||
if (rc) {
|
if(rc) {
|
||||||
failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
|
failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
|
||||||
return CURLE_LDAP_CANNOT_BIND;
|
return CURLE_LDAP_CANNOT_BIND;
|
||||||
}
|
}
|
||||||
/* Try to fallback to LDAPv2? */
|
/* Try to fallback to LDAPv2? */
|
||||||
if (err == LDAP_PROTOCOL_ERROR) {
|
if(err == LDAP_PROTOCOL_ERROR) {
|
||||||
int proto;
|
int proto;
|
||||||
ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
||||||
if (proto == LDAP_VERSION3) {
|
if(proto == LDAP_VERSION3) {
|
||||||
ldap_memfree(info);
|
ldap_memfree(info);
|
||||||
proto = LDAP_VERSION2;
|
proto = LDAP_VERSION2;
|
||||||
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
|
||||||
@@ -336,7 +342,7 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if(err) {
|
||||||
failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
|
failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
|
||||||
info ? info : "");
|
info ? info : "");
|
||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
@@ -351,8 +357,8 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
|
|||||||
ldapconninfo *li = conn->proto.generic;
|
ldapconninfo *li = conn->proto.generic;
|
||||||
(void) dead_connection;
|
(void) dead_connection;
|
||||||
|
|
||||||
if (li) {
|
if(li) {
|
||||||
if (li->ld) {
|
if(li->ld) {
|
||||||
ldap_unbind_ext(li->ld, NULL, NULL);
|
ldap_unbind_ext(li->ld, NULL, NULL);
|
||||||
li->ld = NULL;
|
li->ld = NULL;
|
||||||
}
|
}
|
||||||
@@ -377,11 +383,11 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
|||||||
infof(data, "LDAP local: %s\n", data->change.url);
|
infof(data, "LDAP local: %s\n", data->change.url);
|
||||||
|
|
||||||
rc = ldap_url_parse(data->change.url, &ludp);
|
rc = ldap_url_parse(data->change.url, &ludp);
|
||||||
if (rc != LDAP_URL_SUCCESS) {
|
if(rc != LDAP_URL_SUCCESS) {
|
||||||
const char *msg = "url parsing problem";
|
const char *msg = "url parsing problem";
|
||||||
status = CURLE_URL_MALFORMAT;
|
status = CURLE_URL_MALFORMAT;
|
||||||
if (rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
|
||||||
if (rc == LDAP_URL_ERR_MEM)
|
if(rc == LDAP_URL_ERR_MEM)
|
||||||
status = CURLE_OUT_OF_MEMORY;
|
status = CURLE_OUT_OF_MEMORY;
|
||||||
msg = url_errs[rc];
|
msg = url_errs[rc];
|
||||||
}
|
}
|
||||||
@@ -393,7 +399,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
|||||||
ludp->lud_filter, ludp->lud_attrs, 0,
|
ludp->lud_filter, ludp->lud_attrs, 0,
|
||||||
NULL, NULL, NULL, 0, &msgid);
|
NULL, NULL, NULL, 0, &msgid);
|
||||||
ldap_free_urldesc(ludp);
|
ldap_free_urldesc(ludp);
|
||||||
if (rc != LDAP_SUCCESS) {
|
if(rc != LDAP_SUCCESS) {
|
||||||
failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
|
failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
|
||||||
return CURLE_LDAP_SEARCH_FAILED;
|
return CURLE_LDAP_SEARCH_FAILED;
|
||||||
}
|
}
|
||||||
@@ -412,9 +418,9 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
|
|||||||
(void)res;
|
(void)res;
|
||||||
(void)premature;
|
(void)premature;
|
||||||
|
|
||||||
if (lr) {
|
if(lr) {
|
||||||
/* if there was a search in progress, abandon it */
|
/* if there was a search in progress, abandon it */
|
||||||
if (lr->msgid) {
|
if(lr->msgid) {
|
||||||
ldapconninfo *li = conn->proto.generic;
|
ldapconninfo *li = conn->proto.generic;
|
||||||
ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
|
ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
|
||||||
lr->msgid = 0;
|
lr->msgid = 0;
|
||||||
@@ -441,7 +447,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
(void)sockindex;
|
(void)sockindex;
|
||||||
|
|
||||||
rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &result);
|
rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &result);
|
||||||
if (rc < 0) {
|
if(rc < 0) {
|
||||||
failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
|
failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
|
||||||
*err = CURLE_RECV_ERROR;
|
*err = CURLE_RECV_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -451,30 +457,32 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
/* timed out */
|
/* timed out */
|
||||||
if (result == NULL)
|
if(result == NULL)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
for (ent = ldap_first_message(li->ld, result); ent;
|
for(ent = ldap_first_message(li->ld, result); ent;
|
||||||
ent = ldap_next_message(li->ld, ent)) {
|
ent = ldap_next_message(li->ld, ent)) {
|
||||||
struct berval bv, *bvals, **bvp = &bvals;
|
struct berval bv, *bvals, **bvp = &bvals;
|
||||||
int binary = 0, msgtype;
|
int binary = 0, msgtype;
|
||||||
|
|
||||||
msgtype = ldap_msgtype(ent);
|
msgtype = ldap_msgtype(ent);
|
||||||
if (msgtype == LDAP_RES_SEARCH_RESULT) {
|
if(msgtype == LDAP_RES_SEARCH_RESULT) {
|
||||||
int code;
|
int code;
|
||||||
char *info = NULL;
|
char *info = NULL;
|
||||||
rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
|
rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
|
||||||
if (rc) {
|
if(rc) {
|
||||||
failf(data, "LDAP local: search ldap_parse_result %s",
|
failf(data, "LDAP local: search ldap_parse_result %s",
|
||||||
ldap_err2string(rc));
|
ldap_err2string(rc));
|
||||||
*err = CURLE_LDAP_SEARCH_FAILED;
|
*err = CURLE_LDAP_SEARCH_FAILED;
|
||||||
} else if (code && code != LDAP_SIZELIMIT_EXCEEDED) {
|
}
|
||||||
|
else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
|
||||||
failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
|
failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
|
||||||
info ? info : "");
|
info ? info : "");
|
||||||
*err = CURLE_LDAP_SEARCH_FAILED;
|
*err = CURLE_LDAP_SEARCH_FAILED;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* successful */
|
/* successful */
|
||||||
if (code == LDAP_SIZELIMIT_EXCEEDED)
|
if(code == LDAP_SIZELIMIT_EXCEEDED)
|
||||||
infof(data, "There are more than %d entries\n", lr->nument);
|
infof(data, "There are more than %d entries\n", lr->nument);
|
||||||
data->req.size = data->req.bytecount;
|
data->req.size = data->req.bytecount;
|
||||||
*err = CURLE_OK;
|
*err = CURLE_OK;
|
||||||
@@ -483,9 +491,9 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
lr->msgid = 0;
|
lr->msgid = 0;
|
||||||
ldap_memfree(info);
|
ldap_memfree(info);
|
||||||
break;
|
break;
|
||||||
} else if (msgtype != LDAP_RES_SEARCH_ENTRY) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else if(msgtype != LDAP_RES_SEARCH_ENTRY)
|
||||||
|
continue;
|
||||||
|
|
||||||
lr->nument++;
|
lr->nument++;
|
||||||
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
|
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
|
||||||
@@ -500,41 +508,42 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||||
data->req.bytecount += bv.bv_len + 5;
|
data->req.bytecount += bv.bv_len + 5;
|
||||||
|
|
||||||
for (rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
|
for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
|
||||||
rc == LDAP_SUCCESS;
|
rc == LDAP_SUCCESS;
|
||||||
rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
|
rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (bv.bv_val == NULL) break;
|
if(bv.bv_val == NULL) break;
|
||||||
|
|
||||||
if (bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
|
if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
|
||||||
binary = 1;
|
binary = 1;
|
||||||
else
|
else
|
||||||
binary = 0;
|
binary = 0;
|
||||||
|
|
||||||
for (i=0; bvals[i].bv_val != NULL; i++) {
|
for(i=0; bvals[i].bv_val != NULL; i++) {
|
||||||
int binval = 0;
|
int binval = 0;
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||||
|
bv.bv_len);
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
|
||||||
data->req.bytecount += bv.bv_len + 2;
|
data->req.bytecount += bv.bv_len + 2;
|
||||||
|
|
||||||
if (!binary) {
|
if(!binary) {
|
||||||
/* check for leading or trailing whitespace */
|
/* check for leading or trailing whitespace */
|
||||||
if (ISSPACE(bvals[i].bv_val[0]) ||
|
if(ISSPACE(bvals[i].bv_val[0]) ||
|
||||||
ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) {
|
ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
|
||||||
binval = 1;
|
binval = 1;
|
||||||
} else {
|
else {
|
||||||
/* check for unprintable characters */
|
/* check for unprintable characters */
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
for (j=0; j<bvals[i].bv_len; j++)
|
for(j=0; j<bvals[i].bv_len; j++)
|
||||||
if (!ISPRINT(bvals[i].bv_val[j])) {
|
if(!ISPRINT(bvals[i].bv_val[j])) {
|
||||||
binval = 1;
|
binval = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (binary || binval) {
|
if(binary || binval) {
|
||||||
char *val_b64;
|
char *val_b64;
|
||||||
/* Binary value, encode to base64. */
|
/* Binary value, encode to base64. */
|
||||||
size_t val_b64_sz = Curl_base64_encode(data,
|
size_t val_b64_sz = Curl_base64_encode(data,
|
||||||
@@ -548,7 +557,8 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
free(val_b64);
|
free(val_b64);
|
||||||
data->req.bytecount += val_b64_sz;
|
data->req.bytecount += val_b64_sz;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
|
Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
|
||||||
bvals[i].bv_len);
|
bvals[i].bv_len);
|
||||||
@@ -596,7 +606,7 @@ static int
|
|||||||
ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
|
ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
if (opt == LBER_SB_OPT_DATA_READY) {
|
if(opt == LBER_SB_OPT_DATA_READY) {
|
||||||
struct connectdata *conn = sbiod->sbiod_pvt;
|
struct connectdata *conn = sbiod->sbiod_pvt;
|
||||||
return Curl_ssl_data_pending(conn, FIRSTSOCKET);
|
return Curl_ssl_data_pending(conn, FIRSTSOCKET);
|
||||||
}
|
}
|
||||||
@@ -612,7 +622,7 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
|||||||
CURLcode err = CURLE_RECV_ERROR;
|
CURLcode err = CURLE_RECV_ERROR;
|
||||||
|
|
||||||
ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
|
ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
|
||||||
if (ret < 0 && err == CURLE_AGAIN) {
|
if(ret < 0 && err == CURLE_AGAIN) {
|
||||||
SET_SOCKERRNO(EWOULDBLOCK);
|
SET_SOCKERRNO(EWOULDBLOCK);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -627,7 +637,7 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
|||||||
CURLcode err = CURLE_SEND_ERROR;
|
CURLcode err = CURLE_SEND_ERROR;
|
||||||
|
|
||||||
ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
|
ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
|
||||||
if (ret < 0 && err == CURLE_AGAIN) {
|
if(ret < 0 && err == CURLE_AGAIN) {
|
||||||
SET_SOCKERRNO(EWOULDBLOCK);
|
SET_SOCKERRNO(EWOULDBLOCK);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -100,6 +100,24 @@ struct tzinfo {
|
|||||||
int offset; /* +/- in minutes */
|
int offset; /* +/- in minutes */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parsedate()
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* PARSEDATE_OK - a fine conversion
|
||||||
|
* PARSEDATE_FAIL - failed to convert
|
||||||
|
* PARSEDATE_LATER - time overflow at the far end of time_t
|
||||||
|
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int parsedate(const char *date, time_t *output);
|
||||||
|
|
||||||
|
#define PARSEDATE_OK 0
|
||||||
|
#define PARSEDATE_FAIL -1
|
||||||
|
#define PARSEDATE_LATER 1
|
||||||
|
#define PARSEDATE_SOONER 2
|
||||||
|
|
||||||
/* Here's a bunch of frequently used time zone names. These were supported
|
/* Here's a bunch of frequently used time zone names. These were supported
|
||||||
by the old getdate parser. */
|
by the old getdate parser. */
|
||||||
#define tDAYZONE -60 /* offset for daylight savings time */
|
#define tDAYZONE -60 /* offset for daylight savings time */
|
||||||
@@ -160,7 +178,8 @@ static const struct tzinfo tz[]= {
|
|||||||
{"G", +7 * 60}, /* Golf */
|
{"G", +7 * 60}, /* Golf */
|
||||||
{"H", +8 * 60}, /* Hotel */
|
{"H", +8 * 60}, /* Hotel */
|
||||||
{"I", +9 * 60}, /* India */
|
{"I", +9 * 60}, /* India */
|
||||||
/* "J", Juliet is not used as a timezone, to indicate the observer's local time */
|
/* "J", Juliet is not used as a timezone, to indicate the observer's local
|
||||||
|
time */
|
||||||
{"K", +10 * 60}, /* Kilo */
|
{"K", +10 * 60}, /* Kilo */
|
||||||
{"L", +11 * 60}, /* Lima */
|
{"L", +11 * 60}, /* Lima */
|
||||||
{"M", +12 * 60}, /* Mike */
|
{"M", +12 * 60}, /* Mike */
|
||||||
@@ -282,11 +301,11 @@ static time_t my_timegm(struct my_tm *tm)
|
|||||||
|
|
||||||
year = tm->tm_year + 1900;
|
year = tm->tm_year + 1900;
|
||||||
month = tm->tm_mon;
|
month = tm->tm_mon;
|
||||||
if (month < 0) {
|
if(month < 0) {
|
||||||
year += (11 - month) / 12;
|
year += (11 - month) / 12;
|
||||||
month = 11 - (11 - month) % 12;
|
month = 11 - (11 - month) % 12;
|
||||||
}
|
}
|
||||||
else if (month >= 12) {
|
else if(month >= 12) {
|
||||||
year -= month / 12;
|
year -= month / 12;
|
||||||
month = month % 12;
|
month = month % 12;
|
||||||
}
|
}
|
||||||
@@ -301,7 +320,7 @@ static time_t my_timegm(struct my_tm *tm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_parsedate()
|
* parsedate()
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*
|
*
|
||||||
@@ -311,7 +330,7 @@ static time_t my_timegm(struct my_tm *tm)
|
|||||||
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Curl_parsedate(const char *date, time_t *output)
|
static int parsedate(const char *date, time_t *output)
|
||||||
{
|
{
|
||||||
time_t t = 0;
|
time_t t = 0;
|
||||||
int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
|
int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
|
||||||
@@ -502,7 +521,7 @@ int Curl_parsedate(const char *date, time_t *output)
|
|||||||
time_t curl_getdate(const char *p, const time_t *now)
|
time_t curl_getdate(const char *p, const time_t *now)
|
||||||
{
|
{
|
||||||
time_t parsed;
|
time_t parsed;
|
||||||
int rc = Curl_parsedate(p, &parsed);
|
int rc = parsedate(p, &parsed);
|
||||||
(void)now; /* legacy argument from the past that we ignore */
|
(void)now; /* legacy argument from the past that we ignore */
|
||||||
|
|
||||||
switch(rc) {
|
switch(rc) {
|
||||||
|
|||||||
@@ -25,24 +25,6 @@
|
|||||||
extern const char * const Curl_wkday[7];
|
extern const char * const Curl_wkday[7];
|
||||||
extern const char * const Curl_month[12];
|
extern const char * const Curl_month[12];
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_parsedate()
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
*
|
|
||||||
* PARSEDATE_OK - a fine conversion
|
|
||||||
* PARSEDATE_FAIL - failed to convert
|
|
||||||
* PARSEDATE_LATER - time overflow at the far end of time_t
|
|
||||||
* PARSEDATE_SOONER - time underflow at the low end of time_t
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Curl_parsedate(const char *date, time_t *output);
|
|
||||||
|
|
||||||
#define PARSEDATE_OK 0
|
|
||||||
#define PARSEDATE_FAIL -1
|
|
||||||
#define PARSEDATE_LATER 1
|
|
||||||
#define PARSEDATE_SOONER 2
|
|
||||||
|
|
||||||
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user