summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-04-12 17:17:15 +0000
committerng0 <ng0@n0.is>2019-04-12 17:17:15 +0000
commitc152da162c9da2798d76372a279056a60721e74e (patch)
treeab704ab735dbb8707f82adbddcddf1ce093ec2a8
parente47d2b1430a54d636f26add05333b0834ed54ed3 (diff)
parent521bbbe29928f9bc1c61306df612e856d45cbe5a (diff)
downloadgnurl-c152da162c9da2798d76372a279056a60721e74e.tar.gz
gnurl-c152da162c9da2798d76372a279056a60721e74e.tar.bz2
gnurl-c152da162c9da2798d76372a279056a60721e74e.zip
Merge tag 'curl-7_64_1' of https://github.com/curl/curl
7.64.1
-rw-r--r--.cirrus.yml32
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml144
-rw-r--r--Makefile.am4
-rw-r--r--README.md1
-rw-r--r--RELEASE-NOTES401
-rw-r--r--acinclude.m444
-rw-r--r--appveyor.yml54
-rwxr-xr-xconfigure.ac167
-rw-r--r--docs/ALTSVC.md59
-rw-r--r--docs/CIPHERS.md1
-rw-r--r--docs/FAQ31
-rw-r--r--docs/GOVERNANCE.md4
-rw-r--r--docs/HTTP-COOKIES.md11
-rw-r--r--docs/INSTALL.md6
-rw-r--r--docs/INTERNALS.md3
-rw-r--r--docs/KNOWN_BUGS25
-rw-r--r--docs/Makefile.am4
-rw-r--r--docs/ROADMAP.md60
-rw-r--r--docs/THANKS25
-rw-r--r--docs/TODO44
-rw-r--r--docs/cmdline-opts/Makefile.inc1
-rw-r--r--docs/cmdline-opts/alt-svc.d17
-rw-r--r--docs/cmdline-opts/cookie.d2
-rw-r--r--docs/cmdline-opts/max-redirs.d5
-rw-r--r--docs/cmdline-opts/proxy-user.d6
-rw-r--r--docs/cmdline-opts/proxytunnel.d9
-rw-r--r--docs/cmdline-opts/user.d6
-rw-r--r--docs/examples/10-at-a-time.c99
-rw-r--r--docs/examples/Makefile.am9
-rw-r--r--docs/examples/cacertinmem.c148
-rw-r--r--docs/examples/crawler.c2
-rw-r--r--docs/examples/ephiperfifo.c24
-rw-r--r--docs/examples/evhiperfifo.c7
-rw-r--r--docs/examples/externalsocket.c10
-rw-r--r--docs/examples/ftpget.c4
-rw-r--r--docs/examples/ftpsget.c4
-rw-r--r--docs/examples/ghiper.c14
-rw-r--r--docs/examples/hiperfifo.c20
-rw-r--r--docs/examples/http2-download.c73
-rw-r--r--docs/examples/http2-serverpush.c19
-rw-r--r--docs/examples/http2-upload.c76
-rw-r--r--docs/examples/httpcustomheader.c4
-rw-r--r--docs/examples/postinmemory.c6
-rw-r--r--docs/examples/sftpget.c4
-rw-r--r--docs/examples/sftpuploadresume.c4
-rw-r--r--docs/libcurl/gnurl_easy_duphandle.310
-rw-r--r--docs/libcurl/gnurl_easy_setopt.36
-rw-r--r--docs/libcurl/gnurl_multi_remove_handle.35
-rw-r--r--docs/libcurl/gnurl_url.310
-rw-r--r--docs/libcurl/opts/CURLOPT_ALTSVC.361
-rw-r--r--docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.392
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PIPELINING.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.316
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.35
-rw-r--r--docs/libcurl/opts/Makefile.inc2
-rw-r--r--docs/libcurl/symbols-in-versions20
-rw-r--r--include/gnurl/Makefile.am9
-rw-r--r--include/gnurl/curl.h31
-rw-r--r--include/gnurl/curlver.h10
-rw-r--r--include/gnurl/typecheck-gcc.h3
-rw-r--r--lib/Makefile.am9
-rw-r--r--lib/Makefile.inc11
-rw-r--r--lib/altsvc.c571
-rw-r--r--lib/altsvc.h77
-rw-r--r--lib/amigaos.c32
-rw-r--r--lib/amigaos.h10
-rw-r--r--lib/asyn-thread.c68
-rw-r--r--lib/config-os400.h5
-rw-r--r--lib/config-vxworks.h5
-rw-r--r--lib/conncache.c13
-rw-r--r--lib/connect.c72
-rw-r--r--lib/connect.h9
-rw-r--r--lib/cookie.c59
-rw-r--r--lib/cookie.h11
-rw-r--r--lib/curl_addrinfo.c32
-rw-r--r--lib/curl_addrinfo.h13
-rw-r--r--lib/curl_endian.c10
-rw-r--r--lib/curl_fnmatch.c6
-rw-r--r--lib/curl_gssapi.h16
-rw-r--r--lib/curl_ntlm_core.c31
-rw-r--r--lib/curl_ntlm_wb.c15
-rw-r--r--lib/curl_path.c6
-rw-r--r--lib/curl_rtmp.c9
-rw-r--r--lib/curl_setup.h23
-rw-r--r--lib/dict.c11
-rw-r--r--lib/doh.c71
-rw-r--r--lib/easy.c81
-rw-r--r--lib/file.c4
-rw-r--r--lib/ftp.c58
-rw-r--r--lib/ftp.h3
-rw-r--r--lib/getinfo.c4
-rw-r--r--lib/gopher.c12
-rw-r--r--lib/hostasyn.c8
-rw-r--r--lib/hostip.c103
-rw-r--r--lib/hostip.h12
-rw-r--r--lib/hostip6.c9
-rw-r--r--lib/http.c246
-rw-r--r--lib/http.h6
-rw-r--r--lib/http2.c48
-rw-r--r--lib/http2.h3
-rw-r--r--lib/http_negotiate.c109
-rw-r--r--lib/http_negotiate.h4
-rw-r--r--lib/imap.c8
-rw-r--r--lib/ldap.c4
-rw-r--r--lib/md5.c4
-rw-r--r--lib/memdebug.c145
-rw-r--r--lib/memdebug.h123
-rw-r--r--lib/mime.c14
-rw-r--r--lib/mime.h7
-rw-r--r--lib/multi.c155
-rw-r--r--lib/non-ascii.c4
-rw-r--r--lib/openldap.c4
-rw-r--r--lib/pop3.c2
-rw-r--r--lib/rand.h7
-rw-r--r--lib/rtsp.c22
-rw-r--r--lib/security.c4
-rw-r--r--lib/sendf.c8
-rw-r--r--lib/setopt.c46
-rw-r--r--lib/smtp.c4
-rw-r--r--lib/socks.c4
-rw-r--r--lib/socks_sspi.c5
-rw-r--r--lib/ssh-libssh.c25
-rw-r--r--lib/ssh.c35
-rw-r--r--lib/strerror.c20
-rw-r--r--lib/strerror.h11
-rw-r--r--lib/system_win32.c82
-rw-r--r--lib/system_win32.h6
-rw-r--r--lib/telnet.c4
-rw-r--r--lib/tftp.c30
-rw-r--r--lib/timeval.c24
-rw-r--r--lib/transfer.c51
-rw-r--r--lib/transfer.h20
-rw-r--r--lib/url.c136
-rw-r--r--lib/urlapi.c38
-rw-r--r--lib/urldata.h530
-rw-r--r--lib/vauth/spnego_gssapi.c7
-rw-r--r--lib/vauth/spnego_sspi.c8
-rw-r--r--lib/version.c9
-rw-r--r--lib/vtls/cyassl.c21
-rw-r--r--lib/vtls/gtls.c7
-rw-r--r--lib/vtls/mbedtls.c8
-rw-r--r--lib/vtls/openssl.c23
-rw-r--r--lib/vtls/schannel.c196
-rw-r--r--lib/vtls/schannel_verify.c45
-rw-r--r--lib/vtls/sectransp.c (renamed from lib/vtls/darwinssl.c)158
-rw-r--r--lib/vtls/sectransp.h (renamed from lib/vtls/darwinssl.h)14
-rw-r--r--lib/vtls/vtls.c20
-rw-r--r--lib/vtls/vtls.h8
-rw-r--r--lib/warnless.c40
-rw-r--r--lib/warnless.h6
-rw-r--r--lib/x509asn1.c250
-rw-r--r--m4/curl-functions.m4136
-rw-r--r--packages/OS400/README.OS4001
-rw-r--r--packages/OS400/ccsidcurl.c8
-rw-r--r--packages/OS400/curl.inc.in23
-rw-r--r--scripts/Makefile.am22
-rwxr-xr-xscripts/completion.pl134
-rwxr-xr-xscripts/singleuse.pl210
-rwxr-xr-xscripts/zsh.pl89
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/Makefile.am41
-rwxr-xr-xsrc/mkhelp.pl23
-rw-r--r--src/tool_cb_wrt.c7
-rw-r--r--src/tool_cfgable.c11
-rw-r--r--src/tool_cfgable.h8
-rw-r--r--src/tool_convert.c12
-rw-r--r--src/tool_formparse.c719
-rw-r--r--src/tool_formparse.h46
-rw-r--r--src/tool_getparam.c29
-rw-r--r--src/tool_getpass.c6
-rw-r--r--src/tool_help.c31
-rw-r--r--src/tool_main.c6
-rw-r--r--src/tool_operate.c22
-rw-r--r--src/tool_setopt.c300
-rw-r--r--src/tool_setopt.h4
-rw-r--r--src/tool_urlglob.c4
-rw-r--r--src/tool_xattr.c12
-rw-r--r--tests/FILEFORMAT1
-rw-r--r--tests/data/Makefile.inc12
-rw-r--r--tests/data/test10262
-rw-r--r--tests/data/test10341
-rw-r--r--tests/data/test10462
-rw-r--r--tests/data/test10482
-rw-r--r--tests/data/test10502
-rw-r--r--tests/data/test10822
-rw-r--r--tests/data/test10832
-rw-r--r--tests/data/test10975
-rw-r--r--tests/data/test11332
-rw-r--r--tests/data/test11492
-rw-r--r--tests/data/test11561
-rw-r--r--tests/data/test11601
-rw-r--r--tests/data/test12622
-rw-r--r--tests/data/test12632
-rw-r--r--tests/data/test12913
-rw-r--r--tests/data/test13071
-rw-r--r--tests/data/test14042
-rw-r--r--tests/data/test1425bin1726 -> 1726 bytes
-rw-r--r--tests/data/test1426bin1663 -> 1663 bytes
-rw-r--r--tests/data/test14492
-rw-r--r--tests/data/test14552
-rw-r--r--tests/data/test14564
-rw-r--r--tests/data/test14573
-rw-r--r--tests/data/test15064
-rw-r--r--tests/data/test154134
-rw-r--r--tests/data/test156120
-rw-r--r--tests/data/test165458
-rw-r--r--tests/data/test190560
-rw-r--r--tests/data/test205622
-rw-r--r--tests/data/test205724
-rw-r--r--tests/data/test3272
-rw-r--r--tests/data/test33165
-rw-r--r--tests/data/test35557
-rw-r--r--tests/data/test35670
-rw-r--r--tests/data/test5063
-rw-r--r--tests/data/test5782
-rw-r--r--tests/data/test5971
-rw-r--r--tests/data/test6584
-rw-r--r--tests/data/test65954
-rw-r--r--tests/data/test81
-rwxr-xr-xtests/fuzz/download_fuzzer.sh2
-rw-r--r--tests/libtest/Makefile.am9
-rw-r--r--tests/libtest/Makefile.inc17
-rw-r--r--tests/libtest/first.c6
-rw-r--r--tests/libtest/lib1537.c4
-rw-r--r--tests/libtest/lib1541.c151
-rw-r--r--tests/libtest/lib1555.c8
-rw-r--r--tests/libtest/lib1900.c4
-rw-r--r--tests/libtest/lib1905.c93
-rw-r--r--tests/libtest/lib556.c4
-rw-r--r--tests/libtest/lib597.c104
-rw-r--r--tests/libtest/lib659.c75
-rw-r--r--tests/libtest/stub_gssapi.c18
-rwxr-xr-xtests/runtests.pl82
-rw-r--r--tests/server/Makefile.am9
-rw-r--r--tests/unit/Makefile.am9
-rw-r--r--tests/unit/Makefile.inc5
-rw-r--r--tests/unit/unit1307.c31
-rw-r--r--tests/unit/unit1607.c10
-rw-r--r--tests/unit/unit1608.c5
-rw-r--r--tests/unit/unit1609.c10
-rw-r--r--tests/unit/unit1650.c4
-rw-r--r--tests/unit/unit1651.c4
-rw-r--r--tests/unit/unit1654.c124
244 files changed, 6207 insertions, 3314 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 000000000..070a8d0aa
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,32 @@
+# Cirrus CI configuration
+# https://cirrus-ci.com/github/curl/curl
+
+task:
+ name: FreeBSD
+ freebsd_instance:
+ matrix:
+ image: freebsd-12-0-release-amd64
+ image: freebsd-11-2-release-amd64
+ image: freebsd-10-4-release-amd64
+
+ env:
+ CIRRUS_CLONE_DEPTH: 1
+ MAKE_FLAGS: -j 2
+
+ pkginstall_script:
+ - pkg install -y autoconf automake libtool pkgconf brotli openldap-client heimdal libpsl libmetalink libssh2 openssh-portable libidn2 librtmp libnghttp2 nghttp2 stunnel
+ - pkg delete -y curl
+ configure_script:
+ - ./buildconf
+ - ./configure --prefix="${HOME}"/install --enable-debug --with-libssh2 --with-brotli --with-gssapi --with-libidn2 --enable-manual --enable-ldap --enable-ldaps --with-librtmp --with-libmetalink --with-libpsl --with-nghttp2 || { tail -300 config.log; false; }
+ compile_script:
+ - make V=1
+ test_script:
+ # Some tests won't run if run as root so run them as another user.
+ # Make directories world writable so the test step can write wherever it needs.
+ - find . -type d -exec chmod 777 {} \;
+ # TODO: A number of tests are failing on FreeBSD and so are disabled.
+ # This should be investigated.
+ - sudo -u nobody make V=1 TFLAGS='-n -a -p !flaky !303 !304 !310 !311 !312 !313 !323 !504 !1082 !1242 !1243 !2002 !2003 !2034 !2035 !2037 !2038 !2041 !2042 !2048 !3000 !3001' test-nonflaky
+ install_script:
+ - make V=1 install
diff --git a/.gitignore b/.gitignore
index 397c21ca2..12240a533 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ mkinstalldirs
tags
test-driver
scripts/_gnurl
+scripts/curl.fish
\#*\#
curl_fuzzer
curl_fuzzer_seed_corpus.zip
diff --git a/.travis.yml b/.travis.yml
index d49d8f13a..3318773f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ cache:
- $HOME/libpsl-0.20.1
- $HOME/mbedtls-mbedtls-2.8.0
- $HOME/libidn2-2.0.4
- - $HOME/wolfssl-3.14.0-stable
+ - $HOME/wolfssl-4.0.0-stable
- $HOME/mesalink-0.7.1
- $HOME/nghttp2-1.34.0
@@ -19,13 +19,12 @@ addons:
retries: true
sources:
- ubuntu-toolchain-r-test
- - llvm-toolchain-trusty-6.0
+ - llvm-toolchain-trusty-7
packages:
- cmake
- - gcc-7
- gcc-8
- lcov
- - clang-6.0
+ - clang-7
- valgrind
- libev-dev
- libc-ares-dev
@@ -40,66 +39,107 @@ addons:
- libunistring-dev # for libidn2 needed by libpsl
- libnss3-dev
- gnutls-bin
- - clang-tidy-6.0
+ - libgnutls28-dev
+ - clang-tidy-7
matrix:
include:
- os: linux
compiler: gcc
dist: trusty
- env: T=normal C="--with-gssapi --with-libssh2" CHECKSRC=1
+ env:
+ - T=normal C="--with-gssapi --with-libssh2" CHECKSRC=1
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=normal C=--with-libssh
+ env:
+ - T=normal C=--with-libssh
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=normal C="--disable-http --disable-smtp --disable-imap"
+ env:
+ - T=normal C="--disable-http --disable-smtp --disable-imap"
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=normal C="--enable-ares"
+ env:
+ - T=normal C="--enable-ares"
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=normal C="--disable-verbose" CPPFLAGS="-Wno-variadic-macros" NOTESTS=1
+ env:
+ - T=normal C="--disable-verbose" CPPFLAGS="-Wno-variadic-macros" NOTESTS=1
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=normal BROTLI=yes
+ env:
+ - T=normal BROTLI=yes
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=novalgrind BORINGSSL=yes C="--with-ssl=$HOME/boringssl" LD_LIBRARY_PATH=/home/travis/boringssl/lib:/usr/local/lib
+ env:
+ - T=novalgrind BORINGSSL=yes C="--with-ssl=$HOME/boringssl" LD_LIBRARY_PATH=/home/travis/boringssl/lib:/usr/local/lib
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=debug-wolfssl C="--with-wolfssl --without-ssl"
+ env:
+ - T=debug-wolfssl C="--with-wolfssl --without-ssl"
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=debug-mesalink C="--with-mesalink --without-ssl"
+ env:
+ - T=debug-mesalink C="--with-mesalink --without-ssl"
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: clang
dist: trusty
- env: T=debug
+ env:
+ - T=debug
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: clang
dist: trusty
- env: T=debug C="--with-mbedtls --without-ssl"
+ env:
+ - T=debug C="--enable-alt-svc"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: clang
dist: trusty
- env: T=debug C="--disable-threaded-resolver"
+ env:
+ - T=debug C="--with-mbedtls --without-ssl"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: clang
dist: trusty
- env: T=debug C="--with-nss --without-ssl" NOTESTS=1 CPPFLAGS="-isystem /usr/include/nss"
+ env:
+ - T=debug C="--with-gnutls --without-ssl"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
+ - os: linux
+ compiler: clang
+ dist: trusty
+ env:
+ - T=debug C="--disable-threaded-resolver"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
+ - os: linux
+ compiler: clang
+ dist: trusty
+ env:
+ - T=debug C="--with-nss --without-ssl" NOTESTS=1 CPPFLAGS="-isystem /usr/include/nss"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: gcc
dist: trusty
- env: T=iconv
+ env:
+ - T=iconv
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: osx
compiler: gcc
env: T=debug C=--with-libssh2
@@ -125,31 +165,55 @@ matrix:
- os: linux
compiler: gcc
dist: trusty
- env: T=cmake
+ env:
+ - T=cmake
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: clang
dist: trusty
- env: T=cmake
+ env:
+ - T=cmake
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: gcc
dist: trusty
- env: T=coverage
+ env:
+ - T=coverage
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: gcc
dist: trusty
- env: T=distcheck
+ env:
+ - T=distcheck
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- os: linux
compiler: clang
dist: trusty
- env: T=fuzzer
+ env:
+ - T=fuzzer
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: clang
dist: trusty
- env: T=tidy
+ env:
+ - T=tidy
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- os: linux
compiler: clang
dist: trusty
- env: T=debug CFLAGS="-fsanitize=address,undefined,signed-integer-overflow -fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security -Werror=array-bounds -g" LDFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer" LIBS="-ldl -lubsan"
+ env:
+ - T=scan-build
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
+ - os: linux
+ compiler: clang
+ dist: trusty
+ env:
+ - T=debug CFLAGS="-fsanitize=address,undefined,signed-integer-overflow -fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security -Werror=array-bounds -g" LDFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer" LIBS="-ldl -lubsan"
+ - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
+
+before_install:
+ - eval "${OVERRIDE_CC}"
+ - eval "${OVERRIDE_CXX}"
install:
- if [ "$T" = "coverage" ]; then pip2 install --user cpp-coveralls; fi
@@ -180,7 +244,7 @@ before_script:
cd boringssl &&
mkdir build &&
cd build &&
- cmake -DCMAKE_BUILD_TYPE=release -DBUILD_SHARED_LIBS=1 .. &&
+ CXX="g++" CC="gcc" cmake -DCMAKE_BUILD_TYPE=release -DBUILD_SHARED_LIBS=1 .. &&
make &&
cd .. &&
mkdir lib &&
@@ -226,11 +290,11 @@ before_script:
fi
- |
if [ $TRAVIS_OS_NAME = linux ]; then
- if [ ! -e $HOME/wolfssl-3.14.0-stable/Makefile ]; then
+ if [ ! -e $HOME/wolfssl-4.0.0-stable/Makefile ]; then
(cd $HOME && \
- curl -LO https://github.com/wolfSSL/wolfssl/archive/v3.14.0-stable.tar.gz && \
- tar -xzf v3.14.0-stable.tar.gz && \
- cd wolfssl-3.14.0-stable && \
+ curl -LO https://github.com/wolfSSL/wolfssl/archive/v4.0.0-stable.tar.gz && \
+ tar -xzf v4.0.0-stable.tar.gz && \
+ cd wolfssl-4.0.0-stable && \
./autogen.sh && \
./configure --enable-tls13 --enable-all && \
touch wolfssl/wolfcrypt/fips.h && \
@@ -267,7 +331,7 @@ before_script:
(cd $HOME/libidn2-2.0.4 && sudo make install)
(cd $HOME/libpsl-0.20.1 && sudo make install)
(cd $HOME/mbedtls-mbedtls-2.8.0 && sudo make install)
- (cd $HOME/wolfssl-3.14.0-stable && sudo make install)
+ (cd $HOME/wolfssl-4.0.0-stable && sudo make install)
(cd $HOME/mesalink-0.7.1 && sudo make install)
(cd $HOME/nghttp2-1.34.0 && sudo make install)
fi
@@ -276,15 +340,14 @@ script:
- |
set -eo pipefail
if [ "$T" = "coverage" ]; then
- export CC="gcc-7"
./configure --enable-debug --disable-shared --enable-code-coverage
make
make TFLAGS=-n test-nonflaky
make "TFLAGS=-n -e" test-nonflaky
- tests="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 200 201 202 300 301 302 500 501 502 503 504 506 507 508 509 510 511 512 513 514 515 516 517 518 519 600 601 700 701 702 800 801 802 803 900 901 902 903 1000 1001 1002 1004 1100 1101 1200 1201 1302 1303 1304 1305 1306 1308 1400 1401 1402 1404 1450 1451 1452 1502 1507 1508 1600 1602 1603 1605 1650 2001 2100 3000"
+ tests="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 200 201 202 300 301 302 500 501 502 503 504 506 507 508 509 510 511 512 513 514 515 516 517 518 519 600 601 700 701 702 800 801 802 803 900 901 902 903 1000 1001 1002 1004 1100 1101 1200 1201 1302 1303 1304 1305 1306 1308 1400 1401 1402 1404 1450 1451 1452 1502 1507 1508 1600 1602 1603 1605 1650 1651 1652 1653 1654 2001 2100 3000"
make "TFLAGS=-n -t $tests" test-nonflaky
- coveralls --gcov /usr/bin/gcov-7 --gcov-options '\-lp' -i src -e lib -e tests -e docs -b $PWD/src
- coveralls --gcov /usr/bin/gcov-7 --gcov-options '\-lp' -e src -i lib -e tests -e docs -b $PWD/lib
+ coveralls --gcov /usr/bin/gcov-8 --gcov-options '\-lp' -i src -e lib -e tests -e docs -b $PWD/src
+ coveralls --gcov /usr/bin/gcov-8 --gcov-options '\-lp' -e src -i lib -e tests -e docs -b $PWD/lib
fi
- |
set -eo pipefail
@@ -300,7 +363,7 @@ script:
if [ "$T" = "debug-wolfssl" ]; then
./configure --enable-debug --enable-werror $C
make
- make "TFLAGS=-n !311 !313" test-nonflaky
+ make "TFLAGS=-n !313" test-nonflaky
fi
- |
set -eo pipefail
@@ -345,7 +408,7 @@ script:
source .travis-iconv-env.sh
./configure --enable-debug --enable-werror $C
make && make examples
- make TFLAGS=-n test-nonflaky
+ make test-nonflaky
fi
- |
set -eo pipefail
@@ -404,6 +467,11 @@ script:
./mainline.sh ${CURLSRC}
popd
fi
+ - |
+ if [ "$T" = "scan-build" ]; then
+ scan-build ./configure --enable-debug --enable-werror $C
+ scan-build --status-bugs make && scan-build --status-bugs make examples
+ fi
# whitelist branches to avoid testing feature branches twice (as branch and as pull request)
branches:
diff --git a/Makefile.am b/Makefile.am
index c6a5b0d0d..bf685e1c2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -155,9 +155,9 @@ WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
winbuild/MakefileBuild.vc winbuild/Makefile.vc
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist gnurl-config.in \
- RELEASE-NOTES buildconf libgnurl.pc.in MacOSX-Framework scripts/zsh.pl \
+ RELEASE-NOTES buildconf libgnurl.pc.in MacOSX-Framework \
scripts/updatemanpages.pl $(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) \
- lib/libcurl.vers.in buildconf.bat scripts/coverage.sh
+ lib/libcurl.vers.in buildconf.bat scripts/coverage.sh scripts/completion.pl
CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
$(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \
diff --git a/README.md b/README.md
index b54084502..3b495b15a 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
[![Coverity passed](https://scan.coverity.com/projects/curl/badge.svg)](https://scan.coverity.com/projects/curl)
[![Travis-CI Build Status](https://travis-ci.org/curl/curl.svg?branch=master)](https://travis-ci.org/curl/curl)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/l1vv31029huhf4g4?svg=true)](https://ci.appveyor.com/project/curlorg/curl)
+[![Cirrus Build Status](https://api.cirrus-ci.com/github/curl/curl.svg?branch=master)](https://cirrus-ci.com/github/curl/curl)
[![Coverage Status](https://coveralls.io/repos/github/curl/curl/badge.svg)](https://coveralls.io/github/curl/curl)
[![Backers on Open Collective](https://opencollective.com/curl/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/curl/sponsors/badge.svg)](#sponsors)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 9574e14bb..644b6d78d 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,97 +1,134 @@
-curl and libcurl 7.64.0
+curl and libcurl 7.64.1
- Public curl releases: 179
- Command line options: 220
- curl_easy_setopt() options: 265
+ Public curl releases: 180
+ Command line options: 221
+ curl_easy_setopt() options: 267
Public functions in libcurl: 80
- Contributors: 1875
+ Contributors: 1929
This release includes the following changes:
- o cookies: leave secure cookies alone [3]
- o hostip: support wildcard hosts [23]
- o http: Implement trailing headers for chunked transfers [7]
- o http: added options for allowing HTTP/0.9 responses [10]
- o timeval: Use high resolution timestamps on Windows [19]
+ o alt-svc: experiemental support added [74]
+ o configure: add --with-amissl [84]
This release includes the following bugfixes:
- o CVE-2018-16890: NTLM type-2 out-of-bounds buffer read [67]
- o CVE-2019-3822: NTLMv2 type-3 header stack buffer overflow [68]
- o CVE-2019-3823: SMTP end-of-response out-of-bounds read [66]
- o FAQ: remove mention of sourceforge for github [22]
- o OS400: handle memory error in list conversion [4]
- o OS400: upgrade ILE/RPG binding.
- o README: add codacy code quality badge
- o Revert http_negotiate: do not close connection [31]
- o THANKS: added several missing names from year <= 2000
- o build: make 'tidy' target work for metalink builds
- o cmake: added checks for variadic macros [47]
- o cmake: updated check for HAVE_POLL_FINE to match autotools [39]
- o cmake: use lowercase for function name like the rest of the code [20]
- o configure: detect xlclang separately from clang [41]
- o configure: fix recv/send/select detection on Android [53]
- o configure: rewrite --enable-code-coverage [61]
- o conncache_unlock: avoid indirection by changing input argument type
- o cookie: fix comment typo [44]
- o cookies: allow secure override when done over HTTPS [34]
- o cookies: extend domain checks to non psl builds [12]
- o cookies: skip custom cookies when redirecting cross-site [36]
- o curl --xattr: strip credentials from any URL that is stored [33]
- o curl -J: refuse to append to the destination file [14]
- o curl/urlapi.h: include "curl.h" first [30]
- o curl_multi_remove_handle() don't block terminating c-ares requests [32]
- o darwinssl: accept setting max-tls with default min-tls [6]
- o disconnect: separate connections and easy handles better [18]
- o disconnect: set conn->data for protocol disconnect
- o docs/version.d: mention MultiSSL [26]
- o docs: fix the --tls-max description [2]
- o docs: use $(INSTALL_DATA) to install man page [64]
- o docs: use meaningless port number in CURLOPT_LOCALPORT example [58]
- o gopher: always include the entire gopher-path in request [5]
- o http2: clear pause stream id if it gets closed [8]
- o if2ip: remove unused function Curl_if_is_interface_name [9]
- o libssh: do not let libssh create socket [63]
- o libssh: enable CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION for libssh [62]
- o libssh: free sftp_canonicalize_path() data correctly [17]
- o libtest/stub_gssapi: use "real" snprintf [27]
- o mbedtls: use VERIFYHOST [15]
- o multi: multiplexing improvements [35]
- o multi: set the EXPIRE_*TIMEOUT timers at TIMER_STARTSINGLE time [57]
- o ntlm: fix NTMLv2 compliance [25]
- o ntlm_sspi: add support for channel binding [54]
- o openssl: adapt to 3.0.0, OpenSSL_version_num() is deprecated [46]
- o openssl: fix the SSL_get_tlsext_status_ocsp_resp call [40]
- o openvms: fix OpenSSL discovery on VAX [21]
- o openvms: fix typos in documentation
- o os400: add a missing closing bracket [50]
- o os400: fix extra parameter syntax error [50]
- o pingpong: change default response timeout to 120 seconds
- o pingpong: ignore regular timeout in disconnect phase [16]
- o printf: fix format specifiers [28]
- o runtests.pl: Fix perl call to include srcdir [65]
- o schannel: fix compiler warning [29]
- o schannel: preserve original certificate path parameter [52]
- o schannel: stop calling it "winssl" [56]
- o sigpipe: if mbedTLS is used, ignore SIGPIPE [59]
- o smb: fix incorrect path in request if connection reused [13]
- o ssh: log the libssh2 error message when ssh session startup fails [55]
- o test1558: verify CURLINFO_PROTOCOL on file:// transfer [51]
- o test1561: improve test name
- o test1653: make it survive torture tests
- o tests: allow tests to pass by 2037-02-12 [38]
- o tests: move objnames-* from lib into tests [42]
- o timediff: fix math for unsigned time_t [37]
- o timeval: Disable MSVC Analyzer GetTickCount warning [60]
- o tool_cb_prg: avoid integer overflow [49]
- o travis: added cmake build for osx [43]
- o urlapi: Fix port parsing of eol colon [1]
- o urlapi: distinguish possibly empty query [5]
- o urlapi: fix parsing ipv6 with zone index [24]
- o urldata: rename easy_conn to just conn [48]
- o winbuild: conditionally use /DZLIB_WINAPI [45]
- o wolfssl: fix memory-leak in threaded use [11]
- o spnego_sspi: add support for channel binding [69]
+ o AppVeyor: add MinGW-w64 and classic Mingw builds [55]
+ o AppVeyor: switch VS 2015 builds to VS 2017 image [49]
+ o CURLU: fix NULL dereference when used over proxy [73]
+ o Curl_easy: remove req.maxfd - never used! [58]
+ o Curl_now: figure out windows version in win32_init: [11]
+ o Curl_resolv: fix a gcc -Werror=maybe-uninitialized warning [20]
+ o DoH: inherit some SSL options from user's easy handle [80]
+ o Secure Transport: no more "darwinssl" [56]
+ o Secure Transport: tvOS 11 is required for ALPN support [94]
+ o cirrus: Added FreeBSD builds using Cirrus CI
+ o cleanup: make local functions static [5]
+ o cli tool: do not use mime.h private structures [27]
+ o cmdline-opts/proxytunnel.d: the option tunnnels all protocols [83]
+ o configure: add additional libraries to check for LDAP support [45]
+ o configure: remove the unused fdopen macro [40]
+ o configure: show features as well in the final summary [15]
+ o conncache: use conn->data to know if a transfer owns it [95]
+ o connection: never reuse CONNECT_ONLY connections [35]
+ o connection_check: restore original conn->data after the check [14]
+ o connection_check: set ->data to the transfer doing the check [3]
+ o cookie: Add support for cookie prefixes [29]
+ o cookies: dotless names can set cookies again [81]
+ o cookies: fix NULL dereference if flushing cookies with no CookieInfo set [47]
+ o curl.1: --user and --proxy-user are hidden from ps output [86]
+ o curl.1: mark the argument to --cookie as <data|filename> [87]
+ o curl.h: use __has_declspec_attribute for shared builds [52]
+ o curl: display --version features sorted alphabetically [51]
+ o curl: fix FreeBSD compiler warning in the --xattr code [2]
+ o curl: remove MANUAL from -M output [38]
+ o curl_easy_duphandle.3: clarify that a duped handle has no shares [64]
+ o curl_multi_remove_handle.3: use at any time, just not from within callbacks
+ o curl_url.3: this API is not experimental anymore
+ o dns: release sharelock as soon as possible [1]
+ o docs: update max-redirs.d phrasing [59]
+ o easy: fix win32 init to work without CURL_GLOBAL_WIN32 [30]
+ o examples/10-at-a-time.c: improve readability and simplify
+ o examples/cacertinmem.c: use multiple certificates for loading CA-chain [54]
+ o examples/crawler: Fix the Accept-Encoding setting
+ o examples/ephiperfifo.c: various fixes [63]
+ o examples/externalsocket: add missing close socket calls [78]
+ o examples/http2-download: cleaned up
+ o examples/http2-serverpush: add some sensible error checks [31]
+ o examples/http2-upload: cleaned up
+ o examples/httpcustomheader: Value stored to 'res' is never read
+ o examples/postinmemory: Potential leak of memory pointed to by 'chunk.memory'
+ o examples/sftpuploadresume: Value stored to 'result' is never read
+ o examples: only include <curl/curl.h> [70]
+ o examples: remove recursive calls to curl_multi_socket_action [42]
+ o examples: remove superfluous null-pointer checks
+ o file: fix "Checking if unsigned variable 'readcount' is less than zero." [90]
+ o fnmatch: disable if FTP is disabled [25]
+ o gnutls: remove call to deprecated gnutls_compression_get_name [66]
+ o gopher: remove check for path == NULL [69]
+ o gssapi: fix deprecated header warnings [16]
+ o hostip: make create_hostcache_id avoid alloc + free [4]
+ o http2: multi_connchanged() moved from multi.c, only used for h2 [21]
+ o http2: verify :athority in push promise requests [37]
+ o http: make adding a blank header thread-safe [33]
+ o http: send payload when (proxy) authentication is done [89]
+ o http: set state.infilesize when sending multipart formposts [57]
+ o makefile: make checksrc and hugefile commands "silent" [85]
+ o mbedtls: make it build even if MBEDTLS_VERSION_C isn't set [24]
+ o mbedtls: release sessionid resources on error [28]
+ o memdebug: log pointer before freeing its data [91]
+ o memdebug: make debug-specific functions use curl_dbg_ prefix [82]
+ o mime: put the boundary buffer into the curl_mime struct [18]
+ o multi: call multi_done on connect timeouts, fixes CURLINFO_TOTAL_TIME [43]
+ o multi: remove verbose "Expire in" ... messages [23]
+ o multi: removed unused code for request retries [79]
+ o multi: support verbose conncache closure handle [72]
+ o negotiate: fix for HTTP POST with Negotiate [88]
+ o openssl: add support for TLS ASYNC state [46]
+ o openssl: if cert type is ENG and no key specified, key is ENG too [93]
+ o pretransfer: don't strlen() POSTFIELDS set for GET requests [22]
+ o rand: Fix a mismatch between comments in source and header [32]
+ o runtests: detect "schannel" as an alias for "winssl" [50]
+ o schannel: be quiet - remove verbose output [19]
+ o schannel: close TLS before removing conn from cache [10]
+ o schannel: support CALG_ECDH_EPHEM algorithm [44]
+ o scripts/completion.pl: also generate fish completion file [67]
+ o singlesocket: fix the 'sincebefore' placement [36]
+ o source: fix two 'nread' may be used uninitialized warnings [68]
+ o ssh: fix Condition '!status' is always true [60]
+ o ssh: loop the state machine if not done and not blocking [71]
+ o strerror: make the strerror function use local buffers [48]
+ o system_win32: move win32_init here from easy.c [65]
+ o test578: make it read data from the correct test
+ o tests: Fixed XML validation errors in some test files
+ o tests: add stderr comparison to the test suite [26]
+ o tests: fix multiple may be used uninitialized warnings
+ o threaded-resolver: shutdown the resolver thread without error message [61]
+ o tool_cb_wrt: fix writing to Windows null device NUL [96]
+ o tool_getpass: termios.h is present on AmigaOS 3, but no tcgetattr/tcsetattr [84]
+ o tool_operate: build on AmigaOS [84]
+ o tool_operate: fix typecheck warning [9]
+ o transfer.c: do not compute length of undefined hex buffer
+ o travis: add build using gnutls [75]
+ o travis: add scan-build [13]
+ o travis: bump the used wolfSSL version to 4.0.0 [92]
+ o travis: enable valgrind for the iconv tests [12]
+ o travis: use updated compiler versions: clang 7 and gcc 8 [77]
+ o unit1307: require FTP support [17]
+ o unit1651: survive curl_easy_init() fails
+ o url/idnconvert: remove scan for <= 32 ascii values [6]
+ o url: change conn shutdown order to ensure SOCKETFUNCTION callbacks [39]
+ o urlapi: reduce variable scope, remove unreachable 'break' [7]
+ o urldata: convert bools to bitfields and move to end [53]
+ o urldata: simplify bytecounters [62]
+ o urlglob: Argument with 'nonnull' attribute passed null
+ o version.c: silent scan-build even when librtmp is not enabled
+ o vtls: rename some of the SSL functions [84]
+ o wolfssl: stop custom-adding curves [41]
+ o x509asn1: "Dereference of null pointer"
+ o x509asn1: cleanup and unify code layout [34]
+ o zsh.pl: escape ':' character [8]
+ o zsh.pl: update regex to better match curl -h output [8]
This release includes the following known bugs:
@@ -100,91 +137,117 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
- Alessandro Ghedini, Andrei Neculau, Archangel SDY, Ayoub Boudhar, Ben Kohler,
- Bernhard M. Wiedemann, Brad Spencer, Brian Carpenter, Claes Jakobsson,
- Daniel Gustafsson, Daniel Stenberg, David Garske, dnivras on github,
- Eric Rosenquist, Etienne Simard, Felix Hädicke, Florian Pritz,
- Frank Gevaerts, Giorgos Oikonomou, Gisle Vanem, GitYuanQu on github,
- Haibo Huang, Harry Sintonen, Helge Klein, Huzaifa Sidhpurwala,
- jasal82 on github, Jeremie Rapin, Jeroen Ooms, Joel Depooter, John Marshall,
- jonrumsey on github, Julian Z, Kamil Dudka, Katsuhiko YOSHIDA, Kees Dekker,
- Ladar Levison, Leonardo Taccari, Marcel Raad, Markus Moeller,
- masbug on github, Matus Uzak, Michael Kujawa, Patrick Monnerat, Pavel Pavlov,
- Peng Li, Ray Satiro, Rikard Falkeborn, Ruslan Baratov, Sergei Nikulov,
- Shlomi Fish, Tobias Lindgren, Tom van der Woerdt, Viktor Szakats,
- Wenxiang Qian, William A. Rowe Jr, Zhao Yisha,
- (56 contributors)
+ accountantM on github, Alessandro Ghedini, Andre Guibert de Bruet,
+ Arnaud Rebillout, Bernd Mueller, Björn Stenberg, buzo-ffm on github,
+ Chris Araman, Christian Schmitz, Chris Young, d912e3 on github, Dan Fandrich,
+ Daniel Gustafsson, Daniel Lublin, Daniel Stenberg, David Garske,
+ David Woodhouse, Dominik Hölzl, Don J Olmstead, Eric Curtin, Frank Gevaerts,
+ Gisle Vanem, James Brown, Jan Alexander Steffens, jnbr on github,
+ MAntoniak on github, Marcel Raad, Marc Schlatter, Matt McClure, Michael Felt,
+ Michael Schmid, Michael Wallner, Michał Antoniak, nedres on github,
+ nianxuejie on github, Nick Zitzmann, Nicolas Grekas, Patrick Monnerat,
+ Paul Groke, Pavel Löbl, Ray Satiro, Renaud Allard, Romain Geissler,
+ Sara Golemon, Simon Legner, tholin on github, Tim Rühsen, Volker Schmid,
+ wesinator on github,
+ (49 contributors)
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
- [1] = https://curl.haxx.se/bug/?i=3365
- [2] = https://curl.haxx.se/bug/?i=3368
- [3] = https://curl.haxx.se/bug/?i=2956
- [4] = https://curl.haxx.se/bug/?i=3372
- [5] = https://curl.haxx.se/bug/?i=3369
- [6] = https://curl.haxx.se/bug/?i=3367
- [7] = https://curl.haxx.se/bug/?i=3350
- [8] = https://curl.haxx.se/bug/?i=3392
- [9] = https://curl.haxx.se/bug/?i=3401
- [10] = https://curl.haxx.se/bug/?i=2873
- [11] = https://curl.haxx.se/bug/?i=3395
- [12] = https://curl.haxx.se/bug/?i=2964
- [13] = https://curl.haxx.se/bug/?i=3388
- [14] = https://curl.haxx.se/bug/?i=3380
- [15] = https://curl.haxx.se/bug/?i=3376
- [16] = https://curl.haxx.se/bug/?i=3264
- [17] = https://curl.haxx.se/bug/?i=3402
- [18] = https://curl.haxx.se/bug/?i=3400
- [19] = https://curl.haxx.se/bug/?i=3318
- [20] = https://curl.haxx.se/bug/?i=3196
- [21] = https://curl.haxx.se/bug/?i=3407
- [22] = https://curl.haxx.se/bug/?i=3410
- [23] = https://curl.haxx.se/bug/?i=3406
- [24] = https://curl.haxx.se/bug/?i=3411
- [25] = https://curl.haxx.se/bug/?i=3286
- [26] = https://curl.haxx.se/bug/?i=3432
- [27] = https://curl.haxx.se/mail/lib-2019-01/0000.html
- [28] = https://curl.haxx.se/bug/?i=3426
- [29] = https://curl.haxx.se/bug/?i=3435
- [30] = https://curl.haxx.se/bug/?i=3438
- [31] = https://curl.haxx.se/bug/?i=3384
- [32] = https://curl.haxx.se/bug/?i=3371
- [33] = https://curl.haxx.se/bug/?i=3423
- [34] = https://curl.haxx.se/bug/?i=3445
- [35] = https://curl.haxx.se/bug/?i=3436
- [36] = https://curl.haxx.se/bug/?i=3417
- [37] = https://curl.haxx.se/bug/?i=3449
- [38] = https://curl.haxx.se/bug/?i=3443
- [39] = https://curl.haxx.se/bug/?i=3292
- [40] = https://curl.haxx.se/bug/?i=3477
- [41] = https://curl.haxx.se/bug/?i=3474
- [42] = https://curl.haxx.se/bug/?i=3470
- [43] = https://curl.haxx.se/bug/?i=3468
- [44] = https://curl.haxx.se/bug/?i=3469
- [45] = https://curl.haxx.se/bug/?i=3133
- [46] = https://curl.haxx.se/bug/?i=3462
- [47] = https://curl.haxx.se/bug/?i=3459
- [48] = https://curl.haxx.se/bug/?i=3442
- [49] = https://curl.haxx.se/bug/?i=3456
- [50] = https://curl.haxx.se/bug/?i=3453
- [51] = https://curl.haxx.se/bug/?i=3447
- [52] = https://curl.haxx.se/bug/?i=3480
- [53] = https://curl.haxx.se/bug/?i=3484
- [54] = https://curl.haxx.se/bug/?i=3280
- [55] = https://curl.haxx.se/bug/?i=3481
- [56] = https://curl.haxx.se/bug/?i=3504
- [57] = https://curl.haxx.se/mail/lib-2019-01/0073.html
- [58] = https://curl.haxx.se/bug/?i=3513
- [59] = https://curl.haxx.se/bug/?i=3502
- [60] = https://curl.haxx.se/bug/?i=3437
- [61] = https://curl.haxx.se/bug/?i=3497
- [62] = https://curl.haxx.se/bug/?i=3493
- [63] = https://curl.haxx.se/bug/?i=3491
- [64] = https://curl.haxx.se/bug/?i=3518
- [65] = https://curl.haxx.se/bug/?i=3496
- [66] = https://curl.haxx.se/docs/CVE-2019-3823.html
- [67] = https://curl.haxx.se/docs/CVE-2018-16890.html
- [68] = https://curl.haxx.se/docs/CVE-2019-3822.html
- [69] = https://curl.haxx.se/bug/?i=3503
+ [1] = https://curl.haxx.se/bug/?i=3516
+ [2] = https://curl.haxx.se/bug/?i=3550
+ [3] = https://curl.haxx.se/bug/?i=3541
+ [4] = https://curl.haxx.se/bug/?i=3544
+ [5] = https://curl.haxx.se/bug/?i=3538
+ [6] = https://curl.haxx.se/bug/?i=3539
+ [7] = https://curl.haxx.se/bug/?i=3540
+ [8] = https://bugs.debian.org/921452
+ [9] = https://curl.haxx.se/bug/?i=3534
+ [10] = https://curl.haxx.se/bug/?i=3412
+ [11] = https://curl.haxx.se/bug/?i=3572
+ [12] = https://curl.haxx.se/bug/?i=3571
+ [13] = https://curl.haxx.se/bug/?i=3564
+ [14] = https://curl.haxx.se/bug/?i=3542
+ [15] = https://curl.haxx.se/bug/?i=3569
+ [16] = https://curl.haxx.se/bug/?i=3566
+ [17] = https://curl.haxx.se/bug/?i=3565
+ [18] = https://curl.haxx.se/bug/?i=3561
+ [19] = https://curl.haxx.se/bug/?i=3552
+ [20] = https://curl.haxx.se/bug/?i=3562
+ [21] = https://curl.haxx.se/bug/?i=3557
+ [22] = https://curl.haxx.se/bug/?i=3548
+ [23] = https://curl.haxx.se/mail/archive-2019-02/0013.html
+ [24] = https://curl.haxx.se/bug/?i=3553
+ [25] = https://curl.haxx.se/bug/?i=3551
+ [26] = https://curl.haxx.se/bug/?i=3536
+ [27] = https://curl.haxx.se/bug/?i=3532
+ [28] = https://curl.haxx.se/bug/?i=3574
+ [29] = https://curl.haxx.se/bug/?i=3554
+ [30] = https://curl.haxx.se/bug/?i=3313
+ [31] = https://curl.haxx.se/bug/?i=3580
+ [32] = https://curl.haxx.se/bug/?i=3584
+ [33] = https://curl.haxx.se/bug/?i=3578
+ [34] = https://curl.haxx.se/bug/?i=3582
+ [35] = https://curl.haxx.se/mail/lib-2019-02/0064.html
+ [36] = https://curl.haxx.se/bug/?i=3585
+ [37] = https://curl.haxx.se/bug/?i=3577
+ [38] = https://curl.haxx.se/bug/?i=3587
+ [39] = https://curl.haxx.se/mail/lib-2019-02/0101.html
+ [40] = https://curl.haxx.se/bug/?i=3600
+ [41] = https://curl.haxx.se/bug/?i=3599
+ [42] = https://curl.haxx.se/bug/?i=3537
+ [43] = https://curl.haxx.se/bug/?i=3602
+ [44] = https://curl.haxx.se/bug/?i=3608
+ [45] = https://curl.haxx.se/bug/?i=3595
+ [46] = https://curl.haxx.se/bug/?i=3591
+ [47] = https://curl.haxx.se/bug/?i=3613
+ [48] = https://curl.haxx.se/bug/?i=3612
+ [49] = https://curl.haxx.se/bug/?i=3606
+ [50] = https://curl.haxx.se/bug/?i=3609
+ [51] = https://curl.haxx.se/bug/?i=3611
+ [52] = https://curl.haxx.se/bug/?i=3616
+ [53] = https://curl.haxx.se/bug/?i=3610
+ [54] = https://curl.haxx.se/bug/?i=3421
+ [55] = https://curl.haxx.se/bug/?i=3623
+ [56] = https://curl.haxx.se/bug/?i=3619
+ [57] = https://curl.haxx.se/mail/archive-2019-02/0023.html
+ [58] = https://curl.haxx.se/bug/?i=3626
+ [59] = https://curl.haxx.se/bug/?i=3631
+ [60] = https://curl.haxx.se/bug/?i=3628
+ [61] = https://curl.haxx.se/bug/?i=3629
+ [62] = https://curl.haxx.se/bug/?i=3627
+ [63] = https://curl.haxx.se/bug/?i=3632
+ [64] = https://curl.haxx.se/bug/?i=3592
+ [65] = https://curl.haxx.se/bug/?i=3625
+ [66] = https://curl.haxx.se/bug/?i=3636
+ [67] = https://curl.haxx.se/bug/?i=3545
+ [68] = https://curl.haxx.se/bug/?i=3546
+ [69] = https://curl.haxx.se/bug/?i=3617
+ [70] = https://curl.haxx.se/bug/?i=3645
+ [71] = https://curl.haxx.se/bug/?i=3506
+ [72] = https://curl.haxx.se/bug/?i=3618
+ [73] = https://curl.haxx.se/bug/?i=3641
+ [74] = https://curl.haxx.se/bug/?i=3498
+ [76] = https://curl.haxx.se/bug/?i=3637
+ [77] = https://curl.haxx.se/bug/?i=3670
+ [78] = https://curl.haxx.se/bug/?i=3663
+ [79] = https://curl.haxx.se/bug/?i=3666
+ [80] = https://curl.haxx.se/bug/?i=3660
+ [81] = https://curl.haxx.se/bug/?i=3649
+ [82] = https://curl.haxx.se/bug/?i=3656
+ [83] = https://curl.haxx.se/bug/?i=3658
+ [84] = https://curl.haxx.se/bug/?i=3677
+ [85] = https://curl.haxx.se/bug/?i=3681
+ [86] = https://curl.haxx.se/bug/?i=3680
+ [87] = https://curl.haxx.se/bug/?i=3682
+ [88] = https://curl.haxx.se/bug/?i=1261
+ [89] = https://curl.haxx.se/bug/?i=2431
+ [90] = https://curl.haxx.se/bug/?i=3672
+ [91] = https://curl.haxx.se/bug/?i=3671
+ [92] = https://curl.haxx.se/bug/?i=3697
+ [93] = https://curl.haxx.se/bug/?i=3692
+ [94] = https://curl.haxx.se/bug/?i=3689
+ [95] = https://curl.haxx.se/bug/?i=3686
+ [96] = https://github.com/curl/curl/issues/3175#issuecomment-439068724
+
diff --git a/acinclude.m4 b/acinclude.m4
index 982d38e56..24dad3914 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -791,7 +791,9 @@ AC_DEFUN([CURL_CHECK_LIBS_LDAP], [
'-lldap -llber' \
'-llber -lldap' \
'-lldapssl -lldapx -lldapsdk' \
- '-lldapsdk -lldapx -lldapssl' ; do
+ '-lldapsdk -lldapx -lldapssl' \
+ '-lldap -llber -lssl -lcrypto' ; do
+
if test "$curl_cv_ldap_LIBS" = "unknown"; then
if test -z "$x_nlibs"; then
LIBS="$curl_cv_save_LIBS"
@@ -1029,6 +1031,10 @@ AC_DEFUN([CURL_CHECK_FUNC_RECV], [
#endif
#endif
#else
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -1074,6 +1080,10 @@ AC_DEFUN([CURL_CHECK_FUNC_RECV], [
#endif
#define RECVCALLCONV PASCAL
#else
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -1082,8 +1092,10 @@ AC_DEFUN([CURL_CHECK_FUNC_RECV], [
#endif
#define RECVCALLCONV
#endif
+#ifndef HAVE_PROTO_BSDSOCKET_H
extern $recv_retv RECVCALLCONV
recv($recv_arg1, $recv_arg2, $recv_arg3, $recv_arg4);
+#endif
]],[[
$recv_arg1 s=0;
$recv_arg2 buf=0;
@@ -1163,6 +1175,10 @@ AC_DEFUN([CURL_CHECK_FUNC_SEND], [
#endif
#endif
#else
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -1208,6 +1224,10 @@ AC_DEFUN([CURL_CHECK_FUNC_SEND], [
#endif
#define SENDCALLCONV PASCAL
#else
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -1216,8 +1236,10 @@ AC_DEFUN([CURL_CHECK_FUNC_SEND], [
#endif
#define SENDCALLCONV
#endif
+#ifndef HAVE_PROTO_BSDSOCKET_H
extern $send_retv SENDCALLCONV
send($send_arg1, $send_arg2, $send_arg3, $send_arg4);
+#endif
]],[[
$send_arg1 s=0;
$send_arg3 len=0;
@@ -1319,6 +1341,10 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [
#endif
#endif
#else
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -1712,6 +1738,7 @@ dnl using current libraries or if another one is required.
AC_DEFUN([CURL_CHECK_LIBS_CONNECT], [
AC_REQUIRE([CURL_INCLUDES_WINSOCK2])dnl
+ AC_REQUIRE([CURL_INCLUDES_BSDSOCKET])dnl
AC_MSG_CHECKING([for connect in libraries])
tst_connect_save_LIBS="$LIBS"
tst_connect_need_LIBS="unknown"
@@ -1721,7 +1748,8 @@ AC_DEFUN([CURL_CHECK_LIBS_CONNECT], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
- #ifndef HAVE_WINDOWS_H
+ $curl_includes_bsdsocket
+ #if !defined(HAVE_WINDOWS_H) && !defined(HAVE_PROTO_BSDSOCKET_H)
int connect(int, void*, int);
#endif
]],[[
@@ -1852,6 +1880,11 @@ AC_DEFUN([CURL_CHECK_FUNC_SELECT], [
#endif
#endif
#ifndef HAVE_WINDOWS_H
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
@@ -1910,6 +1943,11 @@ AC_DEFUN([CURL_CHECK_FUNC_SELECT], [
#endif
#endif
#ifndef HAVE_WINDOWS_H
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
@@ -1924,12 +1962,14 @@ AC_DEFUN([CURL_CHECK_FUNC_SELECT], [
long tv_usec;
};
#endif
+#ifndef HAVE_PROTO_BSDSOCKET_H
extern $sel_retv SELECTCALLCONV
select($sel_arg1,
$sel_arg234,
$sel_arg234,
$sel_arg234,
$sel_arg5);
+#endif
]],[[
$sel_arg1 nfds=0;
$sel_arg234 rfds=0;
diff --git a/appveyor.yml b/appveyor.yml
index d6d59075d..7681308e2 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,62 +2,93 @@ version: 7.50.0.{build}
environment:
matrix:
- - PRJ_GEN: "Visual Studio 9 2008"
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PRJ_GEN: "Visual Studio 9 2008"
PRJ_CFG: Release
OPENSSL: OFF
WINSSL: ON
HTTP_ONLY: OFF
TESTING: OFF
SHARED: ON
- - PRJ_GEN: "Visual Studio 14 2015 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PRJ_GEN: "Visual Studio 15 2017 Win64"
PRJ_CFG: Release
OPENSSL: OFF
WINSSL: ON
HTTP_ONLY: OFF
TESTING: OFF
SHARED: ON
- - PRJ_GEN: "Visual Studio 14 2015 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PRJ_GEN: "Visual Studio 15 2017 Win64"
PRJ_CFG: Release
OPENSSL: ON
WINSSL: OFF
HTTP_ONLY: OFF
TESTING: OFF
SHARED: ON
- - PRJ_GEN: "Visual Studio 10 2010 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PRJ_GEN: "Visual Studio 10 2010 Win64"
PRJ_CFG: Debug
OPENSSL: OFF
WINSSL: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
- - PRJ_GEN: "Visual Studio 11 2012 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PRJ_GEN: "Visual Studio 15 2017 Win64"
PRJ_CFG: Debug
OPENSSL: OFF
WINSSL: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
- - PRJ_GEN: "Visual Studio 12 2013 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PRJ_GEN: "Visual Studio 15 2017 Win64"
PRJ_CFG: Debug
OPENSSL: OFF
WINSSL: OFF
- HTTP_ONLY: OFF
+ HTTP_ONLY: ON
TESTING: ON
SHARED: OFF
- - PRJ_GEN: "Visual Studio 14 2015 Win64"
+ DISABLED_TESTS: ""
+ COMPILER_PATH: ""
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PRJ_GEN: "MSYS Makefiles"
PRJ_CFG: Debug
OPENSSL: OFF
WINSSL: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
- - PRJ_GEN: "Visual Studio 14 2015 Win64"
+ DISABLED_TESTS: "!198"
+ COMPILER_PATH: "C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
+ MSYS2_ARG_CONV_EXCL: "/*"
+ - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PRJ_GEN: "MSYS Makefiles"
PRJ_CFG: Debug
OPENSSL: OFF
WINSSL: OFF
- HTTP_ONLY: ON
+ HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
+ DISABLED_TESTS: ""
+ COMPILER_PATH: "C:\\MinGW\\bin"
+ MSYS2_ARG_CONV_EXCL: "/*"
+
+install:
+ - set "PATH=C:\msys64\usr\bin;%PATH%"
+ - if not "%COMPILER_PATH%"=="" (
+ set "PATH=%COMPILER_PATH%;%PATH%" )
build_script:
- cmake .
@@ -72,11 +103,12 @@ build_script:
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=""
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=""
-DCMAKE_INSTALL_PREFIX="C:/CURL"
+ -DCMAKE_BUILD_TYPE=%PRJ_CFG%
- cmake --build . --config %PRJ_CFG% --clean-first
test_script:
- if %TESTING%==ON (
- C:\msys64\usr\bin\bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a -p !flaky !500 !1139" )
+ bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a -p !flaky !1139 %DISABLED_TESTS%" )
# whitelist branches to avoid testing feature branches twice (as branch and as pull request)
branches:
diff --git a/configure.ac b/configure.ac
index d1faab863..faf2b2129 100755
--- a/configure.ac
+++ b/configure.ac
@@ -155,7 +155,7 @@ AC_SUBST(PKGADD_VENDOR)
dnl
dnl initialize all the info variables
- curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,winssl,darwinssl,mesalink} )"
+ curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,schannel,secure-transport,mesalink,amissl} )"
curl_ssh_msg="no (--with-libssh2)"
curl_zlib_msg="no (--with-zlib)"
curl_brotli_msg="no (--with-brotli)"
@@ -365,6 +365,7 @@ CURL_CHECK_WIN32_LARGEFILE
CURL_MAC_CFLAGS
CURL_SUPPORTS_BUILTIN_AVAILABLE
+
dnl ************************************************************
dnl switch off particular protocols
dnl
@@ -832,6 +833,28 @@ fi
if test "$HAVE_GETHOSTBYNAME" != "1"
then
+ dnl This is for AmigaOS with bsdsocket.library - needs testing before -lnet
+ AC_MSG_CHECKING([for gethostbyname for AmigaOS bsdsocket.library])
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+ ]],[[
+ gethostbyname("www.dummysite.com");
+ ]])
+ ],[
+ AC_MSG_RESULT([yes])
+ HAVE_GETHOSTBYNAME="1"
+ HAVE_PROTO_BSDSOCKET_H="1"
+ AC_DEFINE(HAVE_PROTO_BSDSOCKET_H, 1, [if Amiga bsdsocket.library is in use])
+ AC_SUBST(HAVE_PROTO_BSDSOCKET_H, [1])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+fi
+
+if test "$HAVE_GETHOSTBYNAME" != "1"
+then
dnl gethostbyname in the network lib - for Haiku OS
AC_CHECK_LIB(network, gethostbyname,
[HAVE_GETHOSTBYNAME="1"
@@ -1468,6 +1491,34 @@ dnl check winssl option before other SSL libraries
dnl -------------------------------------------------
OPT_WINSSL=no
+OPT_AMISSL=no
+AC_ARG_WITH(amissl,dnl
+AC_HELP_STRING([--with-amissl],[enable Amiga native SSL/TLS (AmiSSL)])
+AC_HELP_STRING([--without-amissl], [disable Amiga native SSL/TLS (AmiSSL)]),
+ OPT_AMISSL=$withval)
+
+AC_MSG_CHECKING([whether to enable Amiga native SSL/TLS (AmiSSL)])
+if test "$HAVE_PROTO_BSDSOCKET_H" == "1"; then
+ if test -z "$ssl_backends" -o "x$OPT_AMISSL" != xno; then
+ ssl_msg=
+ if test "x$OPT_AMISSL" != "xno"; then
+ AC_MSG_RESULT(yes)
+ ssl_msg="AmiSSL"
+ test amissl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes
+ AMISSL_ENABLED=1
+ LIBS="-lamisslauto $LIBS"
+ AC_DEFINE(USE_AMISSL, 1, [if AmiSSL is in use])
+ AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use])
+ else
+ AC_MSG_RESULT(no)
+ fi
+ test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
+ else
+ AC_MSG_RESULT(no)
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
dnl **********************************************************************
dnl Check for the presence of SSL libraries and headers
@@ -1765,7 +1816,7 @@ AC_ARG_WITH(libpsl,
with_libpsl=yes)
if test $with_libpsl != "no"; then
AC_SEARCH_LIBS(psl_builtin, psl,
- [curl_psl_msg="yes";
+ [curl_psl_msg="enabled";
AC_DEFINE([USE_LIBPSL], [1], [PSL support enabled])
],
[curl_psl_msg="no (libpsl not found)";
@@ -1773,7 +1824,7 @@ if test $with_libpsl != "no"; then
]
)
fi
-AM_CONDITIONAL([USE_LIBPSL], [test "$curl_psl_msg" = "yes"])
+AM_CONDITIONAL([USE_LIBPSL], [test "$curl_psl_msg" = "enabled"])
dnl **********************************************************************
dnl Check for libmetalink
@@ -1927,9 +1978,9 @@ AC_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shar
elif test "x$CYASSL_ENABLED" = "x1"; then
versioned_symbols_flavour="CYASSL_"
elif test "x$WINSSL_ENABLED" = "x1"; then
- versioned_symbols_flavour="WINSSL_"
- elif test "x$DARWINSSL_ENABLED" = "x1"; then
- versioned_symbols_flavour="DARWINSSL_"
+ versioned_symbols_flavour="SCHANNEL_"
+ elif test "x$SECURETRANSPORT_ENABLED" = "x1"; then
+ versioned_symbols_flavour="SECURE_TRANSPORT_"
else
versioned_symbols_flavour=""
fi
@@ -2215,6 +2266,31 @@ case "$OPT_ZSH_FPATH" in
esac
dnl **********************************************************************
+dnl Check for fish completion path
+dnl **********************************************************************
+
+OPT_FISH_FPATH=default
+AC_ARG_WITH(fish-functions-dir,
+AC_HELP_STRING([--with-fish-functions-dir=PATH],[Install fish completions to PATH])
+AC_HELP_STRING([--without-fish-functions-dir],[Do not install fish completions]),
+ [OPT_FISH_FPATH=$withval])
+case "$OPT_FISH_FPATH" in
+ no)
+ dnl --without-fish-functions-dir option used
+ ;;
+ default|yes)
+ dnl --with-fish-functions-dir option used without path
+ FISH_FUNCTIONS_DIR="$datarootdir/fish/completions"
+ AC_SUBST(FISH_FUNCTIONS_DIR)
+ ;;
+ *)
+ dnl --with-fish-functions-dir option used with path
+ FISH_FUNCTIONS_DIR="$withval"
+ AC_SUBST(FISH_FUNCTIONS_DIR)
+ ;;
+esac
+
+dnl **********************************************************************
dnl Back to "normal" configuring
dnl **********************************************************************
@@ -2299,6 +2375,7 @@ dnl default includes
]
)
+
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
CURL_CHECK_VARIADIC_MACROS
@@ -2419,7 +2496,6 @@ CURL_CHECK_FUNC_CLOSESOCKET
CURL_CHECK_FUNC_CLOSESOCKET_CAMEL
CURL_CHECK_FUNC_CONNECT
CURL_CHECK_FUNC_FCNTL
-CURL_CHECK_FUNC_FDOPEN
CURL_CHECK_FUNC_FREEADDRINFO
CURL_CHECK_FUNC_FREEIFADDRS
CURL_CHECK_FUNC_FSETXATTR
@@ -2841,6 +2917,32 @@ AC_HELP_STRING([--disable-cookies],[Disable cookies support]),
)
dnl ************************************************************
+dnl switch on/off alt-svc
+dnl
+curl_altsvc_msg="no (--enable-alt-svc)";
+AC_MSG_CHECKING([whether to support alt-svc])
+AC_ARG_ENABLE(alt-svc,
+AC_HELP_STRING([--enable-alt-svc],[Enable alt-svc support])
+AC_HELP_STRING([--disable-alt-svc],[Disable alt-svc support]),
+[ case "$enableval" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_RESULT(yes)
+ curl_altsvc_msg="enabled";
+ enable_altsvc="yes"
+ experimental="alt-svc"
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+if test "$enable_altsvc" = "yes"; then
+ AC_DEFINE(USE_ALTSVC, 1, [to enable alt-svc])
+ experimental="alt-svc"
+fi
+
+dnl ************************************************************
dnl hiding of library internal symbols
dnl
CURL_CONFIGURE_SYMBOL_HIDING
@@ -2908,10 +3010,14 @@ if test "x$HAVE_GSSAPI" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API"
fi
-if test "x$curl_psl_msg" = "xyes"; then
+if test "x$curl_psl_msg" = "xenabled"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES PSL"
fi
+if test "x$enable_altsvc" = "xyes"; then
+ SUPPORT_FEATURES="$SUPPORT_FEATURES alt-svc"
+fi
+
if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \
\( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then
SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO"
@@ -2925,7 +3031,7 @@ fi
if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then
if test "x$OPENSSL_ENABLED" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
-o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
- -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1"; then
+ -o "x$NSS_ENABLED" = "x1" -o "x$SECURETRANSPORT_ENABLED" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM"
if test "x$CURL_DISABLE_HTTP" != "x1" -a \
@@ -3007,7 +3113,7 @@ if test "x$CURL_DISABLE_SMB" != "x1" \
-a "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" \
-a \( "x$OPENSSL_ENABLED" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
-o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
- -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1" \); then
+ -o "x$NSS_ENABLED" = "x1" -o "x$SECURETRANSPORT_ENABLED" = "x1" \); then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMB"
if test "x$SSL_ENABLED" = "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMBS"
@@ -3107,31 +3213,38 @@ AC_MSG_NOTICE([Configured to build gnurl/libgnurl:
LIBS: ${LIBS}
curl version: ${CURLVERSION}
- SSL support: ${curl_ssl_msg}
- SSH support: ${curl_ssh_msg}
- zlib support: ${curl_zlib_msg}
- brotli support: ${curl_brotli_msg}
- GSS-API support: ${curl_gss_msg}
- TLS-SRP support: ${curl_tls_srp_msg}
+ SSL: ${curl_ssl_msg}
+ SSH: ${curl_ssh_msg}
+ zlib: ${curl_zlib_msg}
+ brotli: ${curl_brotli_msg}
+ GSS-API: ${curl_gss_msg}
+ TLS-SRP: ${curl_tls_srp_msg}
resolver: ${curl_res_msg}
- IPv6 support: ${curl_ipv6_msg}
- Unix sockets support: ${curl_unix_sockets_msg}
- IDN support: ${curl_idn_msg}
+ IPv6: ${curl_ipv6_msg}
+ Unix sockets: ${curl_unix_sockets_msg}
+ IDN: ${curl_idn_msg}
Build libcurl: Shared=${enable_shared}, Static=${enable_static}
Built-in manual: ${curl_manual_msg}
--libcurl option: ${curl_libcurl_msg}
Verbose errors: ${curl_verbose_msg}
Code coverage: ${curl_coverage_msg}
- SSPI support: ${curl_sspi_msg}
+ SSPI: ${curl_sspi_msg}
ca cert bundle: ${ca}${ca_warning}
ca cert path: ${capath}${capath_warning}
ca fallback: ${with_ca_fallback}
- LDAP support: ${curl_ldap_msg}
- LDAPS support: ${curl_ldaps_msg}
- RTSP support: ${curl_rtsp_msg}
- RTMP support: ${curl_rtmp_msg}
- metalink support: ${curl_mtlnk_msg}
- PSL support: ${curl_psl_msg}
- HTTP2 support: ${curl_h2_msg}
+ LDAP: ${curl_ldap_msg}
+ LDAPS: ${curl_ldaps_msg}
+ RTSP: ${curl_rtsp_msg}
+ RTMP: ${curl_rtmp_msg}
+ Metalink: ${curl_mtlnk_msg}
+ PSL: ${curl_psl_msg}
+ Alt-svc: ${curl_altsvc_msg}
+ HTTP2: ${curl_h2_msg}
Protocols: ${SUPPORT_PROTOCOLS}
+ Features: ${SUPPORT_FEATURES}
])
+if test -n "$experimental"; then
+ cat >&2 << _EOF
+ WARNING: $experimental is enabled but marked EXPERIMENTAL. Use with caution!
+_EOF
+fi
diff --git a/docs/ALTSVC.md b/docs/ALTSVC.md
new file mode 100644
index 000000000..5aca1c950
--- /dev/null
+++ b/docs/ALTSVC.md
@@ -0,0 +1,59 @@
+# Alt-Svc
+
+curl features **EXPERIMENTAL** support for the Alt-Svc: HTTP header.
+
+## Experimental
+
+Experimental support in curl means:
+
+1. Experimental features are provided to allow users to try them out and
+ provide feedback on functionality and API etc before they ship and get
+ "carved in stone".
+2. You must enable the feature when invoking configure as otherwise curl will
+ not be built with the feature present.
+3. We strongly advice against using this feature in production.
+4. **We reserve the right to change behavior** of the feature without sticking
+ to our API/ABI rules as we do for regular features, as long as it is marked
+ experimental.
+5. Experimental features are clearly marked so in documentation. Beware.
+
+## Enable Alt-Svc in build
+
+`./configure --enable-alt-svc`
+
+## Standard
+
+[RFC 7838](https://tools.ietf.org/html/rfc7838)
+
+## What works
+
+- read alt-svc file from disk
+- write alt-svc file from disk
+- parse `Alt-Svc:` response headers, including `ma`, `clear` and `persist`.
+- replaces old entries when new alternatives are received
+- unit tests to verify most of this functionality (test 1654)
+- act on `Alt-Svc:` response headers
+- build conditionally on `configure --enable-alt-svc` only, feature marked as
+ **EXPERIMENTAL**
+- implement `CURLOPT_ALTSVC_CTRL`
+- implement `CURLOPT_ALTSVC`
+- document `CURLOPT_ALTSVC_CTRL`
+- document `CURLOPT_ALTSVC`
+- document `--alt-svc`
+- add `CURL_VERSION_ALTSVC`
+- make `curl -V` show 'alt-svc' as a feature if built-in
+- support `curl --alt-svc [file]` to enable caching, using that file
+- make `tests/runtests.pl` able to filter tests on the feature `alt-svc`
+- actually use the existing in-memory alt-svc cache for outgoing connections
+- alt-svc cache expiry
+- test 355 and 356 verify curl acting on Alt-Svc, received from header and
+ loaded from cache. The latter needs a debug build since it enables Alt-Svc
+ for plain HTTP.
+
+## What is left
+
+- handle multiple response headers, when one of them says `clear` (should
+ override them all)
+- using `Age:` value for caching age as per spec
+- `CURLALTSVC_IMMEDIATELY` support
+- `CURLALTSVC_ALTUSED` support
diff --git a/docs/CIPHERS.md b/docs/CIPHERS.md
index 0d3be3b56..c01180426 100644
--- a/docs/CIPHERS.md
+++ b/docs/CIPHERS.md
@@ -496,3 +496,4 @@ WinSSL allows the enabling and disabling of encryption algorithms, but not speci
`CALG_ECDH`,
`CALG_ECMQV`,
`CALG_ECDSA`,
+`CALG_ECDH_EPHEM`,
diff --git a/docs/FAQ b/docs/FAQ
index c20716dc6..c1bc9bea5 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -446,10 +446,10 @@ FAQ
backends.
curl can be built to use one of the following SSL alternatives: OpenSSL,
- GnuTLS, yassl, NSS, PolarSSL, MesaLink, Secure Transport (native iOS/OS X),
- WinSSL (native Windows) or GSKit (native IBM i). They all have their pros
- and cons, and we try to maintain a comparison of them here:
- https://curl.haxx.se/docs/ssl-compared.html
+ libressl, BoringSSL, GnuTLS, wolfSSL, NSS, mbedTLS, MesaLink, Secure
+ Transport (native iOS/OS X), Schannel (native Windows) or GSKit (native IBM
+ i). They all have their pros and cons, and we try to maintain a comparison
+ of them here: https://curl.haxx.se/docs/ssl-compared.html
2.3 Where can I find a copy of LIBEAY32.DLL?
@@ -483,7 +483,7 @@ FAQ
and logs and check out why the configure script doesn't find the SSL libs
and/or include files.
- Also, check out the other paragraph in this FAQ labelled "configure doesn't
+ Also, check out the other paragraph in this FAQ labeled "configure doesn't
find OpenSSL even when it is installed".
3.2 How do I tell curl to resume a transfer?
@@ -572,13 +572,14 @@ FAQ
about bindings on the curl-library list too, but be prepared that people on
that list may not know anything about bindings.
- In October 2009, there were interfaces available for the following
- languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
- Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET,
- Object-Pascal, OCaml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby,
- Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro,
- Q, wxwidgets and XBLite. By the time you read this, additional ones may have
- appeared!
+ In February 2019, there were interfaces available for the following
+ languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Delphi, Dylan, Eiffel,
+ Euphoria, Falcon, Ferite, Gambas, glib/GTK+, Go, Guile, Harbour, Haskell,
+ Java, Julia, Lisp, Lua, Mono, .NET, node.js, Object-Pascal, OCaml, Pascal,
+ Perl, PHP, PostgreSQL, Python, R, Rexx, Ring, RPG, Ruby, Rust, Scheme,
+ Scilab, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro,
+ Q, wxwidgets, XBLite and Xoho. By the time you read this, additional ones
+ may have appeared!
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
@@ -745,7 +746,7 @@ FAQ
directory, you get the actual root directory.
To specify a file in your user's home directory, you need to use the correct
- URL syntax which for sftp might look similar to:
+ URL syntax which for SFTP might look similar to:
curl -O -u user:password sftp://example.com/~/file.txt
@@ -1024,7 +1025,7 @@ FAQ
speak SSL. FTPS:// connections default to port 990.
To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one
- of its related flavours). This is the most common method, and the one
+ of its related flavors). This is the most common method, and the one
mandated by RFC4217. This kind of connection will then of course use the
standard FTP port 21 by default.
@@ -1115,7 +1116,7 @@ FAQ
an embedded device with only a single network connection) may want to act
immediately if its lone network connection goes down. That can be achieved
by having the application monitor the network connection on its own using an
- OS-specific mechanism, then signalling libcurl to abort (see also item 5.13).
+ OS-specific mechanism, then signaling libcurl to abort (see also item 5.13).
4.20 curl doesn't return error for HTTP non-200 responses!
diff --git a/docs/GOVERNANCE.md b/docs/GOVERNANCE.md
index 6de2eff41..d49358b95 100644
--- a/docs/GOVERNANCE.md
+++ b/docs/GOVERNANCE.md
@@ -97,7 +97,7 @@ Anyone can aspire to become a curl maintainer.
### Duties
There are no mandatory duties. We hope and wish that maintainers consider
-reviewing patches and help merching them, especially when the changes are
+reviewing patches and help merging them, especially when the changes are
within the area of personal expertise and experience.
### Requirements
@@ -108,7 +108,7 @@ within the area of personal expertise and experience.
### Recommendations
-- please enable 2fa on your github account to reduce risk of malicious sourc
+- please enable 2fa on your github account to reduce risk of malicious source
code tampering
- consider enabling signed git commits for additional verification of changes
diff --git a/docs/HTTP-COOKIES.md b/docs/HTTP-COOKIES.md
index 66e39d232..632cb4ebe 100644
--- a/docs/HTTP-COOKIES.md
+++ b/docs/HTTP-COOKIES.md
@@ -18,9 +18,16 @@
original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html).
In 2011, [RFC6265](https://www.ietf.org/rfc/rfc6265.txt) was finally
- published and details how cookies work within HTTP. In 2017, an update was
+ published and details how cookies work within HTTP. In 2016, an update which
+ added support for prefixes was
+ [proposed](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00),
+ and in 2017, another update was
[drafted](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01)
- to deprecate modification of 'secure' cookies from non-secure origins.
+ to deprecate modification of 'secure' cookies from non-secure origins. Both
+ of these drafs have been incorporated into a proposal to
+ [replace](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02)
+ RFC6265. Cookie prefixes and secure cookie modification protection has been
+ implemented by curl.
## Cookies saved to disk
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index d4b01f215..f2f93227a 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -101,12 +101,12 @@ The default OpenSSL configure check will also detect and use BoringSSL or
libressl.
- GnuTLS: `--without-ssl --with-gnutls`.
- - Cyassl: `--without-ssl --with-cyassl`
+ - wolfSSL: `--without-ssl --with-wolfssl`
- NSS: `--without-ssl --with-nss`
- PolarSSL: `--without-ssl --with-polarssl`
- mbedTLS: `--without-ssl --with-mbedtls`
- - schannel: `--without-ssl --with-winssl`
- - secure transport: `--without-ssl --with-darwinssl`
+ - schannel: `--without-ssl --with-schannel`
+ - secure transport: `--without-ssl --with-secure-transport`
- MesaLink: `--without-ssl --with-mesalink`
# Windows
diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md
index 1633e59ff..69b92d4e2 100644
--- a/docs/INTERNALS.md
+++ b/docs/INTERNALS.md
@@ -314,7 +314,7 @@ FTP
<a name="kerberos"></a>
Kerberos
---------
+========
Kerberos support is mainly in lib/krb5.c and lib/security.c but also
`curl_sasl_sspi.c` and `curl_sasl_gssapi.c` for the email protocols and
@@ -590,6 +590,7 @@ Asynchronous name resolves
options that end with LARGE. The type is 64bit large on most modern
platforms.
+<a name="curlx"></a>
curlx
=====
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index 5363575ef..875456f19 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -18,6 +18,7 @@ problems may have been fixed or changed somewhat since this was written!
1.4 multipart formposts file name encoding
1.5 Expect-100 meets 417
1.6 Unnecessary close when 401 received waiting for 100
+ 1.7 Deflate error after all content was received
1.9 HTTP/2 frames while in the connection pool kill reuse
1.10 Strips trailing dot from host name
1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
@@ -29,6 +30,7 @@ problems may have been fixed or changed somewhat since this was written!
2.4 DarwinSSL won't import PKCS#12 client certificates without a password
2.5 Client cert handling with Issuer DN differs between backends
2.6 CURL_GLOBAL_SSL
+ 2.7 Client cert (MTLS) issues with Schannel
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
@@ -46,6 +48,8 @@ problems may have been fixed or changed somewhat since this was written!
5. Build and portability issues
5.1 tests not compatible with python3
5.2 curl-config --libs contains private details
+ 5.3 curl compiled on OSX 10.13 failed to run on OSX 10.10
+ 5.4 Cannot compile against a static build of OpenLDAP
5.5 can't handle Unicode arguments in Windows
5.6 cmake support gaps
5.7 Visual Studio project gaps
@@ -154,6 +158,15 @@ problems may have been fixed or changed somewhat since this was written!
waiting for the the 100-continue response.
https://curl.haxx.se/mail/lib-2008-08/0462.html
+1.7 Deflate error after all content was received
+
+ There's a situation where we can get an error in a HTTP response that is
+ compressed, when that error is detected after all the actual body contents
+ have been received and delivered to the appliction. This is tricky, but is
+ ultimately a broken server.
+
+ See https://github.com/curl/curl/issues/2719
+
1.9 HTTP/2 frames while in the connection pool kill reuse
If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to
@@ -272,6 +285,10 @@ problems may have been fixed or changed somewhat since this was written!
https://github.com/curl/curl/issues/2276
+2.7 Client cert (MTLS) issues with Schannel
+
+ See https://github.com/curl/curl/issues/3145
+
3. Email protocols
@@ -367,6 +384,14 @@ problems may have been fixed or changed somewhat since this was written!
run that might be needed only for building libcurl. Further, curl-config
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
+5.3 curl compiled on OSX 10.13 failed to run on OSX 10.10
+
+ See https://github.com/curl/curl/issues/2905
+
+5.4 Cannot compile against a static build of OpenLDAP
+
+ See https://github.com/curl/curl/issues/2367
+
5.5 can't handle Unicode arguments in Windows
If a URL or filename can't be encoded using the user's current codepage then
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 99021f19a..b020ccf70 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -42,6 +42,7 @@ CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES) $(MANDISTPAGES) gnurl.1
EXTRA_DIST = \
$(noinst_man_MANS) \
+ ALTSVC.md \
BINDINGS.md \
BUGS \
CHECKSRC.md \
@@ -65,7 +66,6 @@ EXTRA_DIST = \
KNOWN_BUGS \
LICENSE-MIXING.md \
MAIL-ETIQUETTE \
- MANUAL \
README.cmake \
README.md \
README.netware \
diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md
index 497c45b54..10e7effee 100644
--- a/docs/ROADMAP.md
+++ b/docs/ROADMAP.md
@@ -5,35 +5,55 @@ Roadmap of things Daniel Stenberg wants to work on next. It is intended to
serve as a guideline for others for information, feedback and possible
participation.
-QUIC
+HTTP/3
+------
+
+ See the [QUIC and HTTP/3 wiki page](https://github.com/curl/curl/wiki/QUIC).
+
+ESNI (Encrypted SNI)
+--------------------
+
+ See Daniel's post on [Support of Encrypted
+ SNI](https://curl.haxx.se/mail/lib-2019-03/0000.html) on the mailing list.
+
+HSTS
----
- See the [QUIC wiki page](https://github.com/curl/curl/wiki/QUIC).
+Complete and merge [the existing PR](https://github.com/curl/curl/pull/2682).
+
+Parallel transfers for the curl tool
+------------------------------------
+
+This will require several new command line options to enable and control.
-HTTP cookies
-------------
+ 1. switch to creating a list of all the transfers first before any transfer
+ is done
+ 2. make the transfers using the multi interface
+ 3. optionally fire up more transfers before the previous has completed
-On top of what we already support, the prefix cookie draft has been adopted by
-the httpwg in IETF and we should support it as the popular browsers will:
+Option to refuse HTTPS => HTTP redirects
+----------------------------------------
-[Cookie Prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00)
+Possibly as a new bit to `CURLOPT_FOLLOWLOCATION` ?
-[Firefox bug report about secure cookies](https://bugzilla.mozilla.org/show_bug.cgi?id=976073)
+Option to let CURLOPT_CUSTOMREQUEST be overridden on redirect
+-------------------------------------------------------------
-SRV records
------------
+(This is a common problem for people using `-X` and `-L` together.)
-How to find services for specific domains/hosts.
+Possibly as a new bit to `CURLOPT_FOLLOWLOCATION` ?
-Improve
--------
+Hardcode “localhostâ€
+--------------------
-1. curl -h output (considered overwhelming to users).
+No need to resolve it. Avoid a risk where this is resolved over the network
+and actually responds with something else than a local address. Some operating
+systems already do this. Also:
+https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02
-2. We have > 200 command line options, is there a way to redo things to
- simplify or improve the situation as we are likely to keep adding
- features/options in the future too.
+Consider "menu config"-style build feature selection
+----------------------------------------------------
-3. Perform some of the clean up from the TODO document, removing old
- definitions and such like that are currently earmarked to be removed years
- ago.
+Allow easier building of custom libcurl versions with only a selected feature
+where the available features are easily browsable and toggle-able ON/OFF or
+similar.
diff --git a/docs/THANKS b/docs/THANKS
index 58a8322ba..bf6ad755c 100644
--- a/docs/THANKS
+++ b/docs/THANKS
@@ -152,6 +152,7 @@ Arkadiusz Miskiewicz
Armel Asselin
Arnaud Compan
Arnaud Ebalard
+Arnaud Rebillout
Aron Bergman
Artak Galoyan
Arthur Murray
@@ -193,6 +194,7 @@ Benoit Neil
Benoit Sigoure
Bernard Leak
Bernard Spil
+Bernd Mueller
Bernhard Iselborn
Bernhard M. Wiedemann
Bernhard Reutner-Fischer
@@ -358,6 +360,7 @@ Daniel Johnson
Daniel Kahn Gillmor
Daniel Krügler
Daniel Lee Hwang
+Daniel Lublin
Daniel Melani
Daniel Mentz
Daniel Romero
@@ -508,6 +511,7 @@ Enrico Scholz
Enrik Berkhan
Eramoto Masaya
Eric Cooper
+Eric Curtin
Eric Gallager
Eric Hu
Eric Landes
@@ -726,6 +730,7 @@ Jaime Fullaondo
Jakub Wilk
Jakub Zakrzewski
James Atwill
+James Brown
James Bursa
James Cheng
James Clancy
@@ -1040,6 +1045,7 @@ Luz Paz
Luật Nguyễn
Lyman Epp
Lyndon Hill
+MAntoniak on github
Maciej Karpiuk
Maciej Puzio
Maciej W. Rozycki
@@ -1060,6 +1066,7 @@ Marc Hesse
Marc Hörsken
Marc Kleine-Budde
Marc Renault
+Marc Schlatter
Marc-Antoine Perennou
Marcel Raad
Marcel Roelofs
@@ -1126,6 +1133,7 @@ Mats Lidell
Matt Arsenault
Matt Ford
Matt Kraai
+Matt McClure
Matt Veenstra
Matt Witherspoon
Matt Wixson
@@ -1176,6 +1184,7 @@ Michael Maltese
Michael Mealling
Michael Mueller
Michael Osipov
+Michael Schmid
Michael Smith
Michael Stapelberg
Michael Steuer
@@ -1184,6 +1193,7 @@ Michael Wallner
Michal Bonino
Michal Marek
Michal Trybus
+Michał Antoniak
Michał Fita
Michał Górny
Michał Janiszewski
@@ -1250,6 +1260,7 @@ Nico Baggus
Nicolas Berloquin
Nicolas Croiset
Nicolas François
+Nicolas Grekas
Nicolas Morey-Chaisemartin
Niels van Tongeren
Nikita Schmidt
@@ -1312,6 +1323,7 @@ Patrick Watson
Patrik Thunstrom
Pau Garcia i Quiles
Paul Donohue
+Paul Groke
Paul Harrington
Paul Harris
Paul Howarth
@@ -1325,6 +1337,7 @@ Paul Querna
Paul Saab
Pavel Cenek
Pavel Gushchin
+Pavel Löbl
Pavel Orehov
Pavel Pavlov
Pavel Raiskup
@@ -1426,6 +1439,7 @@ Remco van Hooff
Remi Gacogne
Remo E
Renato Botelho
+Renaud Allard
Renaud Chaillat
Renaud Duhaut
Renaud Guillard
@@ -1499,6 +1513,7 @@ Roland Zimmermann
Rolland Dudemaine
Romain Coltel
Romain Fliedel
+Romain Geissler
Roman Koifman
Roman Mamedov
Romulo A. Ceccon
@@ -1588,6 +1603,7 @@ Siegfried Gyuricsko
Simon Dick
Simon H.
Simon Josefsson
+Simon Legner
Simon Liu
Simon Warta
Somnath Kundu
@@ -1783,6 +1799,7 @@ Vladimir Lazarenko
Vojtech Janota
Vojtech Minarik
Vojtěch Král
+Volker Schmid
Vsevolod Novikov
W. Mark Kubacki
Waldek Kozba
@@ -1837,6 +1854,7 @@ Zhibiao Wu
Zhouyihai Ding
Zmey Petroff
Zvi Har'El
+accountantM on github
adnn on github
afrind on github
ahodesuka on github
@@ -1846,9 +1864,11 @@ asavah on github
baumanj on github
bobmitchell1956 on github
bsammon on github
+buzo-ffm on github
cbartl on github
clbr on github
cmfrolick on github
+d912e3 on github
daboul on github
dasimx on github
destman on github
@@ -1866,6 +1886,7 @@ infinnovation-dev on github
iz8mbw on github
jakirkham on github
jasal82 on github
+jnbr on github
jonrumsey on github
joshhe on github
jungle-boogie on github
@@ -1880,8 +1901,10 @@ masbug on github
mccormickt12 on github
mkzero on github
moohoorama on github
+nedres on github
neex on github
neheb on github
+nianxuejie on github
nk
nopjmp on github
olesteban on github
@@ -1895,10 +1918,12 @@ steini2000 on github
stootill on github
swalkaus at yahoo.com
tarek112 on github
+tholin on github
tommink[at]post.pl
tonystz on Github
tpaukrt on github
vanillajonathan on github
+wesinator on github
wmsch on github
wncboy on github
youngchopin on github
diff --git a/docs/TODO b/docs/TODO
index 323bbb771..40bc726fc 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -17,6 +17,7 @@
All bugs documented in the KNOWN_BUGS document are subject for fixing!
1. libcurl
+ 1.1 TFO support on Windows
1.2 More data sharing
1.3 struct lifreq
1.4 signal-based resolver timeouts
@@ -44,6 +45,8 @@
1.26 CURL_REFUSE_CLEARTEXT
1.27 hardcode the "localhost" addresses
1.28 FD_CLOEXEC
+ 1.29 Upgrade to websockets
+ 1.30 config file parsing
2. libcurl - multi interface
2.1 More non-blocking
@@ -70,6 +73,7 @@
5.1 Better persistency for HTTP 1.0
5.2 support FF3 sqlite cookie files
5.3 Rearrange request header order
+ 5.4 Allow SAN names in HTTP/2 server push
5.5 auth= in URLs
5.6 Refuse "downgrade" redirects
5.7 QUIC
@@ -164,6 +168,7 @@
19. Build
19.1 roffit
19.2 Enable PIE and RELRO by default
+ 19.3 cmake test suite improvements
20. Test suite
20.1 SSL tunnel
@@ -192,6 +197,13 @@
1. libcurl
+1.1 TFO support on Windows
+
+ TCP Fast Open is supported on several platforms but not on Windows. Work on
+ this was once started but never finished.
+
+ See https://github.com/curl/curl/pull/3378
+
1.2 More data sharing
curl_share_* functions already exist and work, and they can be extended to
@@ -440,6 +452,22 @@
https://github.com/curl/curl/issues/2252
+1.29 Upgrade to websockets
+
+ libcurl could offer a smoother path to get to a websocket connection.
+ See https://github.com/curl/curl/issues/3523
+
+ Michael Kaufmann suggestion here:
+ https://curl.haxx.se/video/curlup-2017/2017-03-19_05_Michael_Kaufmann_Websocket_support_for_curl.mp4
+
+1.30 config file parsing
+
+ Consider providing an API, possibly in a separate companion library, for
+ parsing a config file like curl's -K/--config option to allow applications to
+ get the same ability to read curl options from files.
+
+ See https://github.com/curl/curl/issues/3698
+
2. libcurl - multi interface
2.1 More non-blocking
@@ -577,6 +605,15 @@
headers use a default value so only headers that need to be moved have to be
specified.
+5.4 Allow SAN names in HTTP/2 server push
+
+ curl only allows HTTP/2 push promise if the provided :autority header value
+ exactly matches the host name given in the URL. It could be extended to allow
+ any name that would match the Subject Alternative Names in the server's TLS
+ certificate.
+
+ See https://github.com/curl/curl/pull/3581
+
5.5 auth= in URLs
Add the ability to specify the preferred authentication mechanism to use by
@@ -1144,6 +1181,13 @@ that doesn't exist on the server, just like --ftp-create-dirs.
to no impact, neither on the performance nor on the general functionality of
curl.
+19.3 cmake test suite improvements
+
+ The cmake build doesn't support 'make show' so it doesn't know which tests
+ are in the makefile or not (making appveyor builds do many false warnings
+ about it) nor does it support running the test suite if building out-of-tree.
+
+ See https://github.com/curl/curl/issues/3109
20. Test suite
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index b99a142ee..7a8af6f9e 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -2,6 +2,7 @@
DPAGES = \
abstract-unix-socket.d \
+ alt-svc.d \
anyauth.d \
append.d basic.d \
cacert.d capath.d \
diff --git a/docs/cmdline-opts/alt-svc.d b/docs/cmdline-opts/alt-svc.d
new file mode 100644
index 000000000..dfe636cfc
--- /dev/null
+++ b/docs/cmdline-opts/alt-svc.d
@@ -0,0 +1,17 @@
+Long: alt-svc
+Arg: <file name>
+Protocols: HTTPS
+Help: Enable alt-svc with this cache file
+Added: 7.64.1
+---
+WARNING: this option is experiemental. Do not use in production.
+
+This option enables the alt-svc parser in curl. If the file name points to an
+existing alt-svc cache file, that will be used. After a completed transfer,
+the cache will be saved to the file name again if it has been modified.
+
+Specifiy a "" file name (zero length) to avoid loading/saving and make curl
+just handle the cache in memory.
+
+If this option is used several times, curl will load contents from all the
+files but the the last one will be used for saving.
diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d
index 3ae697548..1e9906977 100644
--- a/docs/cmdline-opts/cookie.d
+++ b/docs/cmdline-opts/cookie.d
@@ -1,6 +1,6 @@
Short: b
Long: cookie
-Arg: <data>
+Arg: <data|filename>
Protocols: HTTP
Help: Send cookies from string/file
---
diff --git a/docs/cmdline-opts/max-redirs.d b/docs/cmdline-opts/max-redirs.d
index 04b824bd2..a97860a8b 100644
--- a/docs/cmdline-opts/max-redirs.d
+++ b/docs/cmdline-opts/max-redirs.d
@@ -4,8 +4,7 @@ Help: Maximum number of redirects allowed
Protocols: HTTP
---
Set maximum number of redirection-followings allowed. When --location is used,
-is used to prevent curl from following redirections \&"in absurdum". By
-default, the limit is set to 50 redirections. Set this option to -1 to make it
-unlimited.
+is used to prevent curl from following redirections too much. By default, the
+limit is set to 50 redirections. Set this option to -1 to make it unlimited.
If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/proxy-user.d b/docs/cmdline-opts/proxy-user.d
index b1f6f6e03..152466daa 100644
--- a/docs/cmdline-opts/proxy-user.d
+++ b/docs/cmdline-opts/proxy-user.d
@@ -9,4 +9,10 @@ If you use a Windows SSPI-enabled curl binary and do either Negotiate or NTLM
authentication then you can tell curl to select the user name and password
from your environment by specifying a single colon with this option: "-U :".
+On systems where it works, curl will hide the given option argument from
+process listings. This is not enough to protect credentials from possibly
+getting seen by other users on the same system as they will still be visible
+for a brief moment before cleared. Such sensitive data should be retrieved
+from a file instead or similar and never used in clear text in a command line.
+
If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/proxytunnel.d b/docs/cmdline-opts/proxytunnel.d
index 42aee2bb2..1f587f120 100644
--- a/docs/cmdline-opts/proxytunnel.d
+++ b/docs/cmdline-opts/proxytunnel.d
@@ -3,11 +3,10 @@ Short: p
Help: Operate through an HTTP proxy tunnel (using CONNECT)
See-also: proxy
---
-When an HTTP proxy is used --proxy, this option will cause non-HTTP protocols
-to attempt to tunnel through the proxy instead of merely using it to do
-HTTP-like operations. The tunnel approach is made with the HTTP proxy CONNECT
-request and requires that the proxy allows direct connect to the remote port
-number curl wants to tunnel through to.
+When an HTTP proxy is used --proxy, this option will make curl tunnel through
+the proxy. The tunnel approach is made with the HTTP proxy CONNECT request and
+requires that the proxy allows direct connect to the remote port number curl
+wants to tunnel through to.
To suppress proxy CONNECT response headers when curl is set to output headers
use --suppress-connect-headers.
diff --git a/docs/cmdline-opts/user.d b/docs/cmdline-opts/user.d
index 439def348..7001d28ab 100644
--- a/docs/cmdline-opts/user.d
+++ b/docs/cmdline-opts/user.d
@@ -12,6 +12,12 @@ The user name and passwords are split up on the first colon, which makes it
impossible to use a colon in the user name with this option. The password can,
still.
+On systems where it works, curl will hide the given option argument from
+process listings. This is not enough to protect credentials from possibly
+getting seen by other users on the same system as they will still be visible
+for a brief moment before cleared. Such sensitive data should be retrieved
+from a file instead or similar and never used in clear text in a command line.
+
When using Kerberos V5 with a Windows based server you should include the
Windows domain name in the user name, in order for the server to successfully
obtain a Kerberos Ticket. If you don't then the initial authentication
diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c
index 690bd6f28..12e5261fa 100644
--- a/docs/examples/10-at-a-time.c
+++ b/docs/examples/10-at-a-time.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,10 +20,8 @@
*
***************************************************************************/
/* <DESC>
- * Source code using the multi interface to download many
- * files, with a capped maximum amount of simultaneous transfers.
+ * Download many files in parallel, in the same thread.
* </DESC>
- * Written by Michael Wallner
*/
#include <errno.h>
@@ -32,7 +30,7 @@
#ifndef WIN32
# include <unistd.h>
#endif
-#include <gnurl/multi.h>
+#include <gnurl/curl.h>
static const char *urls[] = {
"https://www.microsoft.com",
@@ -84,27 +82,23 @@ static const char *urls[] = {
"https://www.un.org",
};
-#define MAX 10 /* number of simultaneous transfers */
-#define CNT sizeof(urls)/sizeof(char *) /* total number of transfers to do */
+#define MAX_PARALLEL 10 /* number of simultaneous transfers */
+#define NUM_URLS sizeof(urls)/sizeof(char *)
-static size_t cb(char *d, size_t n, size_t l, void *p)
+static size_t write_cb(char *data, size_t n, size_t l, void *userp)
{
/* take care of the data here, ignored in this example */
- (void)d;
- (void)p;
+ (void)data;
+ (void)userp;
return n*l;
}
-static void init(CURLM *cm, int i)
+static void add_transfer(CURLM *cm, int i)
{
CURL *eh = curl_easy_init();
-
- curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
- curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
+ curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
- curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
-
curl_multi_add_handle(cm, eh);
}
@@ -112,64 +106,23 @@ int main(void)
{
CURLM *cm;
CURLMsg *msg;
- long L;
- unsigned int C = 0;
- int M, Q, U = -1;
- fd_set R, W, E;
- struct timeval T;
+ unsigned int transfers = 0;
+ int msgs_left = -1;
+ int still_alive = 1;
curl_global_init(CURL_GLOBAL_ALL);
-
cm = curl_multi_init();
- /* we can optionally limit the total amount of connections this multi handle
- uses */
- curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);
+ /* Limit the amount of simultaneous connections curl should allow: */
+ curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL);
- for(C = 0; C < MAX; ++C) {
- init(cm, C);
- }
+ for(transfers = 0; transfers < MAX_PARALLEL; transfers++)
+ add_transfer(cm, transfers);
- while(U) {
- curl_multi_perform(cm, &U);
+ do {
+ curl_multi_perform(cm, &still_alive);
- if(U) {
- FD_ZERO(&R);
- FD_ZERO(&W);
- FD_ZERO(&E);
-
- if(curl_multi_fdset(cm, &R, &W, &E, &M)) {
- fprintf(stderr, "E: curl_multi_fdset\n");
- return EXIT_FAILURE;
- }
-
- if(curl_multi_timeout(cm, &L)) {
- fprintf(stderr, "E: curl_multi_timeout\n");
- return EXIT_FAILURE;
- }
- if(L == -1)
- L = 100;
-
- if(M == -1) {
-#ifdef WIN32
- Sleep(L);
-#else
- sleep((unsigned int)L / 1000);
-#endif
- }
- else {
- T.tv_sec = L/1000;
- T.tv_usec = (L%1000)*1000;
-
- if(0 > select(M + 1, &R, &W, &E, &T)) {
- fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n",
- M + 1, L, errno, strerror(errno));
- return EXIT_FAILURE;
- }
- }
- }
-
- while((msg = curl_multi_info_read(cm, &Q))) {
+ while((msg = curl_multi_info_read(cm, &msgs_left))) {
if(msg->msg == CURLMSG_DONE) {
char *url;
CURL *e = msg->easy_handle;
@@ -182,13 +135,13 @@ int main(void)
else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
}
- if(C < CNT) {
- init(cm, C++);
- U++; /* just to prevent it from remaining at 0 if there are more
- URLs to get */
- }
+ if(transfers < NUM_URLS)
+ add_transfer(cm, transfers++);
}
- }
+ if(still_alive)
+ curl_multi_wait(cm, NULL, 0, 1000, NULL);
+
+ } while(still_alive || (transfers < NUM_URLS));
curl_multi_cleanup(cm);
curl_global_cleanup();
diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am
index ff0774e31..105f78b1d 100644
--- a/docs/examples/Makefile.am
+++ b/docs/examples/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -61,5 +61,10 @@ include Makefile.inc
all: $(check_PROGRAMS)
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl -ASNPRINTF $(srcdir)/*.c
+ $(CHECKSRC)(@PERL@ $(top_srcdir)/lib/checksrc.pl -ASNPRINTF $(srcdir)/*.c)
diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c
index ec72c7a71..5948ff039 100644
--- a/docs/examples/cacertinmem.c
+++ b/docs/examples/cacertinmem.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -29,7 +29,7 @@
#include <gnurl/curl.h>
#include <stdio.h>
-size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
+static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
{
fwrite(ptr, size, nmemb, (FILE *)stream);
return (nmemb*size);
@@ -38,88 +38,86 @@ size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
CURLcode rv = CURLE_ABORTED_BY_CALLBACK;
- X509_STORE *store = NULL;
- X509 *cert = NULL;
- BIO *bio = NULL;
- char *mypem =
- /* CA for example.com. CN = DigiCert High Assurance EV Root CA */
+
+ /** This example uses two (fake) certificates **/
+ static const char mypem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE\n"
+ "AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw\n"
+ "CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ\n"
+ "BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND\n"
+ "VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb\n"
+ "qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY\n"
+ "HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo\n"
+ "G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA\n"
+ "0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH\n"
+ "k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47\n"
+ "JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m\n"
+ "AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD\n"
+ "vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms\n"
+ "tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH\n"
+ "7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\n"
+ "I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA\n"
+ "h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF\n"
+ "d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H\n"
+ "pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7\n"
+ "-----END CERTIFICATE-----\n"
"-----BEGIN CERTIFICATE-----\n"
- "MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n"
- "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
- "d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"
- "ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n"
- "MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"
- "LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n"
- "RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n"
- "+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n"
- "PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n"
- "xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n"
- "Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n"
- "hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n"
- "EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n"
- "MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n"
- "FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n"
- "nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n"
- "eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n"
- "hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n"
- "Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n"
- "vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n"
- "+OkuE6N36B9K\n"
+ "MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE\n"
+ "AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x\n"
+ "CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW\n"
+ "MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF\n"
+ "RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\n"
+ "AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7\n"
+ "09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7\n"
+ "XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P\n"
+ "gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe\n"
+ "I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i\n"
+ "5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi\n"
+ "ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn\n"
+ "MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ\n"
+ "o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6\n"
+ "zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN\n"
+ "GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt\n"
+ "r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK\n"
+ "Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==\n"
"-----END CERTIFICATE-----\n";
- /* clear the current thread's OpenSSL error queue */
- ERR_clear_error();
+ BIO *cbio = BIO_new_mem_buf(mypem, sizeof(mypem));
+ X509_STORE *cts = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
+ X509_INFO *itmp;
+ int i, count = 0;
+ STACK_OF(X509_INFO) *inf;
+ (void)curl;
+ (void)parm;
- /* get a BIO */
- bio = BIO_new_mem_buf(mypem, -1);
- if(!bio)
- goto err;
-
- /* use it to read the PEM formatted certificate from memory into an X509
- * structure that SSL can use
- */
- if(!PEM_read_bio_X509(bio, &cert, 0, NULL))
- goto err;
-
- /* get a pointer to the X509 certificate store (which may be empty!) */
- store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
- if(!store)
- goto err;
-
- /* add our certificate to this store */
- if(!X509_STORE_add_cert(store, cert)) {
- unsigned long error = ERR_peek_last_error();
-
- /* Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE which means the
- * certificate is already in the store. That could happen if
- * libcurl already loaded the certificate from a ca cert bundle
- * set at libcurl build-time or runtime.
- */
- if(ERR_GET_LIB(error) != ERR_LIB_X509 ||
- ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
- goto err;
-
- ERR_clear_error();
+ if(!cts || !cbio) {
+ return rv;
}
- rv = CURLE_OK;
+ inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
-err:
- if(rv != CURLE_OK) {
- char errbuf[256];
- unsigned long error = ERR_peek_last_error();
+ if(!inf) {
+ BIO_free(cbio);
+ return rv;
+ }
- fprintf(stderr, "error adding certificate\n");
- if(error) {
- ERR_error_string_n(error, errbuf, sizeof(errbuf));
- fprintf(stderr, "%s\n", errbuf);
+ for(i = 0; i < sk_X509_INFO_num(inf); i++) {
+ itmp = sk_X509_INFO_value(inf, i);
+ if(itmp->x509) {
+ X509_STORE_add_cert(cts, itmp->x509);
+ count++;
+ }
+ if(itmp->crl) {
+ X509_STORE_add_crl(cts, itmp->crl);
+ count++;
}
}
- X509_free(cert);
- BIO_free(bio);
- ERR_clear_error();
+ sk_X509_INFO_pop_free(inf, X509_INFO_free);
+ BIO_free(cbio);
+ rv = CURLE_OK;
return rv;
}
@@ -142,9 +140,9 @@ int main(void)
rv = curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L);
rv = curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
- /* turn off the default CA locations (optional)
- * otherwise libcurl will load CA certificates from the locations that
- * were detected/specified at build-time
+ /* Turn off the default CA locations, otherwise libcurl will load CA
+ * certificates from the locations that were detected/specified at
+ * build-time
*/
rv = curl_easy_setopt(ch, CURLOPT_CAINFO, NULL);
rv = curl_easy_setopt(ch, CURLOPT_CAPATH, NULL);
diff --git a/docs/examples/crawler.c b/docs/examples/crawler.c
index 32e6050f8..ec3c853fc 100644
--- a/docs/examples/crawler.c
+++ b/docs/examples/crawler.c
@@ -81,7 +81,7 @@ CURL *make_handle(char *url)
curl_easy_setopt(handle, CURLOPT_PRIVATE, mem);
/* For completeness */
- curl_easy_setopt(handle, CURLOPT_ENCODING, "gzip, deflate");
+ curl_easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(handle, CURLOPT_TIMEOUT, 5L);
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 10L);
diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c
index 96ee4e70a..9963399ac 100644
--- a/docs/examples/ephiperfifo.c
+++ b/docs/examples/ephiperfifo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -72,7 +72,6 @@ callback.
#include <unistd.h>
#include <gnurl/curl.h>
-#include <curl/multi.h>
#ifdef __GNUC__
#define _Unused __attribute__((unused))
@@ -153,23 +152,26 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
- timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
if(timeout_ms > 0) {
its.it_interval.tv_sec = 1;
its.it_interval.tv_nsec = 0;
its.it_value.tv_sec = timeout_ms / 1000;
- its.it_value.tv_nsec = (timeout_ms % 1000) * 1000;
- timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
+ its.it_value.tv_nsec = (timeout_ms % 1000) * 1000 * 1000;
}
else if(timeout_ms == 0) {
- rc = curl_multi_socket_action(g->multi,
- CURL_SOCKET_TIMEOUT, 0, &g->still_running);
- mcode_or_die("multi_timer_cb: curl_multi_socket_action", rc);
+ /* libcurl wants us to timeout now, however setting both fields of
+ * new_value.it_value to zero disarms the timer. The closest we can
+ * do is to schedule the timer to fire in 1 ns. */
+ its.it_interval.tv_sec = 1;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = 1;
}
else {
memset(&its, 0, sizeof(struct itimerspec));
- timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
}
+
+ timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
return 0;
}
@@ -206,8 +208,8 @@ static void event_cb(GlobalInfo *g, int fd, int revents)
CURLMcode rc;
struct itimerspec its;
- int action = (revents & EPOLLIN ? CURL_POLL_IN : 0) |
- (revents & EPOLLOUT ? CURL_POLL_OUT : 0);
+ int action = (revents & EPOLLIN ? CURL_CSELECT_IN : 0) |
+ (revents & EPOLLOUT ? CURL_CSELECT_OUT : 0);
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
mcode_or_die("event_cb: curl_multi_socket_action", rc);
diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c
index 8673724b8..5e0905560 100644
--- a/docs/examples/evhiperfifo.c
+++ b/docs/examples/evhiperfifo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -119,13 +119,12 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{
DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
ev_timer_stop(g->loop, &g->timer_event);
- if(timeout_ms > 0) {
+ if(timeout_ms >= 0) {
+ /* -1 means delete, other values are timeout times in milliseconds */
double t = timeout_ms / 1000;
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
ev_timer_start(g->loop, &g->timer_event);
}
- else if(timeout_ms == 0)
- timer_cb(g->loop, &g->timer_event, 0);
return 0;
}
diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c
index 25f510173..516fa98b0 100644
--- a/docs/examples/externalsocket.c
+++ b/docs/examples/externalsocket.c
@@ -124,8 +124,10 @@ int main(void)
servaddr.sin_port = htons(PORTNUM);
servaddr.sin_addr.s_addr = inet_addr(IPADDR);
- if(INADDR_NONE == servaddr.sin_addr.s_addr)
+ if(INADDR_NONE == servaddr.sin_addr.s_addr) {
+ close(sockfd);
return 2;
+ }
if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) ==
-1) {
@@ -157,10 +159,16 @@ int main(void)
curl_easy_cleanup(curl);
+ close(sockfd);
+
if(res) {
printf("libcurl error: %d\n", res);
return 4;
}
}
+
+#ifdef WIN32
+ WSACleanup();
+#endif
return 0;
}
diff --git a/docs/examples/ftpget.c b/docs/examples/ftpget.c
index f9d78ae7f..68e655305 100644
--- a/docs/examples/ftpget.c
+++ b/docs/examples/ftpget.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -36,7 +36,7 @@ struct FtpFile {
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
- if(out && !out->stream) {
+ if(!out->stream) {
/* open file for writing */
out->stream = fopen(out->filename, "wb");
if(!out->stream)
diff --git a/docs/examples/ftpsget.c b/docs/examples/ftpsget.c
index 348747ab4..dedd347b1 100644
--- a/docs/examples/ftpsget.c
+++ b/docs/examples/ftpsget.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -38,7 +38,7 @@ static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
- if(out && !out->stream) {
+ if(!out->stream) {
/* open file for writing */
out->stream = fopen(out->filename, "wb");
if(!out->stream)
diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c
index c76d31d0e..064b2fedb 100644
--- a/docs/examples/ghiper.c
+++ b/docs/examples/ghiper.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -163,16 +163,14 @@ static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
timeout_ms, timeout.tv_sec, timeout.tv_usec);
- /* TODO
- *
- * if timeout_ms is 0, call curl_multi_socket_action() at once!
- *
+ /*
* if timeout_ms is -1, just delete the timer
*
- * for all other values of timeout_ms, this should set or *update*
- * the timer to the new value
+ * For other values of timeout_ms, this should set or *update* the timer to
+ * the new value
*/
- g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
+ if(timeout_ms >= 0)
+ g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
return 0;
}
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c
index eddeccd58..bcdffa6d3 100644
--- a/docs/examples/hiperfifo.c
+++ b/docs/examples/hiperfifo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -152,23 +152,15 @@ static int multi_timer_cb(CURLM *multi _Unused, long timeout_ms, GlobalInfo *g)
timeout.tv_usec = (timeout_ms%1000)*1000;
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
- /* TODO
- *
- * if timeout_ms is 0, call curl_multi_socket_action() at once!
- *
+ /*
* if timeout_ms is -1, just delete the timer
*
- * for all other values of timeout_ms, this should set or *update*
- * the timer to the new value
+ * For all other values of timeout_ms, this should set or *update* the timer
+ * to the new value
*/
- if(timeout_ms == 0) {
- rc = curl_multi_socket_action(g->multi,
- CURL_SOCKET_TIMEOUT, 0, &g->still_running);
- mcode_or_die("multi_timer_cb: curl_multi_socket_action", rc);
- }
- else if(timeout_ms == -1)
+ if(timeout_ms == -1)
evtimer_del(&g->timer_event);
- else
+ else /* includes timeout zero */
evtimer_add(&g->timer_event, &timeout);
return 0;
}
diff --git a/docs/examples/http2-download.c b/docs/examples/http2-download.c
index aa8e69b31..febb89bb2 100644
--- a/docs/examples/http2-download.c
+++ b/docs/examples/http2-download.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -41,22 +41,13 @@
#define CURLPIPE_MULTIPLEX 0
#endif
-#define NUM_HANDLES 1000
-
-static void *curl_hnd[NUM_HANDLES];
-static int num_transfers;
+struct transfer {
+ CURL *easy;
+ unsigned int num;
+ FILE *out;
+};
-/* a handle to number lookup, highly ineffective when we do many
- transfers... */
-static int hnd2num(CURL *hnd)
-{
- int i;
- for(i = 0; i< num_transfers; i++) {
- if(curl_hnd[i] == hnd)
- return i;
- }
- return 0; /* weird, but just a fail-safe */
-}
+#define NUM_HANDLES 1000
static
void dump(const char *text, int num, unsigned char *ptr, size_t size,
@@ -113,9 +104,10 @@ int my_trace(CURL *handle, curl_infotype type,
void *userp)
{
const char *text;
- int num = hnd2num(handle);
+ struct transfer *t = (struct transfer *)userp;
+ unsigned int num = t->num;
(void)handle; /* prevent compiler warning */
- (void)userp;
+
switch(type) {
case CURLINFO_TEXT:
fprintf(stderr, "== %d Info: %s", num, data);
@@ -147,17 +139,19 @@ int my_trace(CURL *handle, curl_infotype type,
return 0;
}
-static void setup(CURL *hnd, int num)
+static void setup(struct transfer *t, int num)
{
- FILE *out;
char filename[128];
+ CURL *hnd;
+
+ hnd = t->easy = curl_easy_init();
snprintf(filename, 128, "dl-%d", num);
- out = fopen(filename, "wb");
+ t->out = fopen(filename, "wb");
/* write to this file */
- curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
+ curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t->out);
/* set the same URL */
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
@@ -165,6 +159,7 @@ static void setup(CURL *hnd, int num)
/* please be verbose */
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
+ curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, t);
/* HTTP/2 please */
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
@@ -177,37 +172,35 @@ static void setup(CURL *hnd, int num)
/* wait for pipe connection to confirm */
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
#endif
-
- curl_hnd[num] = hnd;
}
/*
- * Simply download two files over HTTP/2, using the same physical connection!
+ * Download many transfers over HTTP/2, using the same connection!
*/
int main(int argc, char **argv)
{
- CURL *easy[NUM_HANDLES];
+ struct transfer trans[NUM_HANDLES];
CURLM *multi_handle;
int i;
int still_running = 0; /* keep number of running handles */
-
- if(argc > 1)
+ int num_transfers;
+ if(argc > 1) {
/* if given a number, do that many transfers */
num_transfers = atoi(argv[1]);
-
- if(!num_transfers || (num_transfers > NUM_HANDLES))
- num_transfers = 3; /* a suitable low default */
+ if((num_transfers < 1) || (num_transfers > NUM_HANDLES))
+ num_transfers = 3; /* a suitable low default */
+ }
+ else
+ num_transfers = 3; /* suitable default */
/* init a multi stack */
multi_handle = curl_multi_init();
- for(i = 0; i<num_transfers; i++) {
- easy[i] = curl_easy_init();
- /* set options */
- setup(easy[i], i);
+ for(i = 0; i < num_transfers; i++) {
+ setup(&trans[i], i);
/* add the individual transfer */
- curl_multi_add_handle(multi_handle, easy[i]);
+ curl_multi_add_handle(multi_handle, trans[i].easy);
}
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
@@ -286,10 +279,12 @@ int main(int argc, char **argv)
}
}
- curl_multi_cleanup(multi_handle);
+ for(i = 0; i < num_transfers; i++) {
+ curl_multi_remove_handle(multi_handle, trans[i].easy);
+ curl_easy_cleanup(trans[i].easy);
+ }
- for(i = 0; i<num_transfers; i++)
- curl_easy_cleanup(easy[i]);
+ curl_multi_cleanup(multi_handle);
return 0;
}
diff --git a/docs/examples/http2-serverpush.c b/docs/examples/http2-serverpush.c
index f7fc13c59..26d5a6927 100644
--- a/docs/examples/http2-serverpush.c
+++ b/docs/examples/http2-serverpush.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -128,9 +128,12 @@ int my_trace(CURL *handle, curl_infotype type,
#define OUTPUTFILE "dl"
-static void setup(CURL *hnd)
+static int setup(CURL *hnd)
{
FILE *out = fopen(OUTPUTFILE, "wb");
+ if(!out)
+ /* failed */
+ return 1;
/* write to this file */
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
@@ -153,7 +156,7 @@ static void setup(CURL *hnd)
/* wait for pipe connection to confirm */
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
#endif
-
+ return 0; /* all is good */
}
/* called when there's an incoming push */
@@ -176,6 +179,11 @@ static int server_push_callback(CURL *parent,
/* here's a new stream, save it in a new file for each new push */
out = fopen(filename, "wb");
+ if(!out) {
+ /* if we can't save it, deny it */
+ fprintf(stderr, "Failed to create output file for push\n");
+ return CURL_PUSH_DENY;
+ }
/* write to this file */
curl_easy_setopt(easy, CURLOPT_WRITEDATA, out);
@@ -215,7 +223,10 @@ int main(void)
easy = curl_easy_init();
/* set options */
- setup(easy);
+ if(setup(easy)) {
+ fprintf(stderr, "failed\n");
+ return 1;
+ }
/* add the easy transfer */
curl_multi_add_handle(multi_handle, easy);
diff --git a/docs/examples/http2-upload.c b/docs/examples/http2-upload.c
index 2371a543d..bdec19b4a 100644
--- a/docs/examples/http2-upload.c
+++ b/docs/examples/http2-upload.c
@@ -45,20 +45,12 @@
#define NUM_HANDLES 1000
-static void *curl_hnd[NUM_HANDLES];
-static int num_transfers;
-
-/* a handle to number lookup, highly ineffective when we do many
- transfers... */
-static int hnd2num(CURL *hnd)
-{
- int i;
- for(i = 0; i< num_transfers; i++) {
- if(curl_hnd[i] == hnd)
- return i;
- }
- return 0; /* weird, but just a fail-safe */
-}
+struct input {
+ FILE *in;
+ size_t bytes_read; /* count up */
+ CURL *hnd;
+ int num;
+};
static
void dump(const char *text, int num, unsigned char *ptr, size_t size,
@@ -115,15 +107,14 @@ int my_trace(CURL *handle, curl_infotype type,
{
char timebuf[60];
const char *text;
- int num = hnd2num(handle);
+ struct input *i = (struct input *)userp;
+ int num = i->num;
static time_t epoch_offset;
static int known_offset;
struct timeval tv;
time_t secs;
struct tm *now;
-
(void)handle; /* prevent compiler warning */
- (void)userp;
gettimeofday(&tv, NULL);
if(!known_offset) {
@@ -166,12 +157,6 @@ int my_trace(CURL *handle, curl_infotype type,
return 0;
}
-struct input {
- FILE *in;
- size_t bytes_read; /* count up */
- CURL *hnd;
-};
-
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct input *i = userp;
@@ -180,16 +165,17 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
return retcode;
}
-static struct input indata[NUM_HANDLES];
-
-static void setup(CURL *hnd, int num, const char *upload)
+static void setup(struct input *i, int num, const char *upload)
{
FILE *out;
char url[256];
char filename[128];
struct stat file_info;
curl_off_t uploadsize;
+ CURL *hnd;
+ hnd = i->hnd = curl_easy_init();
+ i->num = num;
snprintf(filename, 128, "dl-%d", num);
out = fopen(filename, "wb");
@@ -199,8 +185,7 @@ static void setup(CURL *hnd, int num, const char *upload)
stat(upload, &file_info);
uploadsize = file_info.st_size;
- indata[num].in = fopen(upload, "rb");
- indata[num].hnd = hnd;
+ i->in = fopen(upload, "rb");
/* write to this file */
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
@@ -208,7 +193,7 @@ static void setup(CURL *hnd, int num, const char *upload)
/* we want to use our own read function */
curl_easy_setopt(hnd, CURLOPT_READFUNCTION, read_callback);
/* read from this file */
- curl_easy_setopt(hnd, CURLOPT_READDATA, &indata[num]);
+ curl_easy_setopt(hnd, CURLOPT_READDATA, i);
/* provide the size of the upload */
curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, uploadsize);
@@ -221,6 +206,7 @@ static void setup(CURL *hnd, int num, const char *upload)
/* please be verbose */
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
+ curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, i);
/* HTTP/2 please */
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
@@ -233,8 +219,6 @@ static void setup(CURL *hnd, int num, const char *upload)
/* wait for pipe connection to confirm */
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
#endif
-
- curl_hnd[num] = hnd;
}
/*
@@ -242,33 +226,35 @@ static void setup(CURL *hnd, int num, const char *upload)
*/
int main(int argc, char **argv)
{
- CURL *easy[NUM_HANDLES];
+ struct input trans[NUM_HANDLES];
CURLM *multi_handle;
int i;
int still_running = 0; /* keep number of running handles */
const char *filename = "index.html";
+ int num_transfers;
- if(argc > 1)
+ if(argc > 1) {
/* if given a number, do that many transfers */
num_transfers = atoi(argv[1]);
- if(argc > 2)
- /* if given a file name, upload this! */
- filename = argv[2];
+ if(!num_transfers || (num_transfers > NUM_HANDLES))
+ num_transfers = 3; /* a suitable low default */
- if(!num_transfers || (num_transfers > NUM_HANDLES))
- num_transfers = 3; /* a suitable low default */
+ if(argc > 2)
+ /* if given a file name, upload this! */
+ filename = argv[2];
+ }
+ else
+ num_transfers = 3;
/* init a multi stack */
multi_handle = curl_multi_init();
for(i = 0; i<num_transfers; i++) {
- easy[i] = curl_easy_init();
- /* set options */
- setup(easy[i], i, filename);
+ setup(&trans[i], i, filename);
/* add the individual transfer */
- curl_multi_add_handle(multi_handle, easy[i]);
+ curl_multi_add_handle(multi_handle, trans[i].hnd);
}
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
@@ -352,8 +338,10 @@ int main(int argc, char **argv)
curl_multi_cleanup(multi_handle);
- for(i = 0; i<num_transfers; i++)
- curl_easy_cleanup(easy[i]);
+ for(i = 0; i<num_transfers; i++) {
+ curl_multi_remove_handle(multi_handle, trans[i].hnd);
+ curl_easy_cleanup(trans[i].hnd);
+ }
return 0;
}
diff --git a/docs/examples/httpcustomheader.c b/docs/examples/httpcustomheader.c
index 01ddc33da..d98aa7a5a 100644
--- a/docs/examples/httpcustomheader.c
+++ b/docs/examples/httpcustomheader.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -49,7 +49,7 @@ int main(void)
chunk = curl_slist_append(chunk, "X-silly-header;");
/* set our custom set of headers */
- res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_URL, "localhost");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
diff --git a/docs/examples/postinmemory.c b/docs/examples/postinmemory.c
index a8efe93d6..22014abc9 100644
--- a/docs/examples/postinmemory.c
+++ b/docs/examples/postinmemory.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -67,7 +67,6 @@ int main(void)
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
-
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.org/");
/* send all data to this function */
@@ -106,10 +105,9 @@ int main(void)
/* always cleanup */
curl_easy_cleanup(curl);
- free(chunk.memory);
-
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
+ free(chunk.memory);
return 0;
}
diff --git a/docs/examples/sftpget.c b/docs/examples/sftpget.c
index 7d0aa4292..14230e95c 100644
--- a/docs/examples/sftpget.c
+++ b/docs/examples/sftpget.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -47,7 +47,7 @@ static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
- if(out && !out->stream) {
+ if(!out->stream) {
/* open file for writing */
out->stream = fopen(out->filename, "wb");
if(!out->stream)
diff --git a/docs/examples/sftpuploadresume.c b/docs/examples/sftpuploadresume.c
index 078fa723a..4e070fb35 100644
--- a/docs/examples/sftpuploadresume.c
+++ b/docs/examples/sftpuploadresume.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -65,6 +65,8 @@ static curl_off_t sftpGetRemoteFileSize(const char *i_remoteFile)
result = curl_easy_getinfo(curlHandlePtr,
CURLINFO_CONTENT_LENGTH_DOWNLOAD_T,
&remoteFileSizeByte);
+ if(result)
+ return -1;
printf("filesize: %" CURL_FORMAT_CURL_OFF_T "\n", remoteFileSizeByte);
}
curl_easy_cleanup(curlHandlePtr);
diff --git a/docs/libcurl/gnurl_easy_duphandle.3 b/docs/libcurl/gnurl_easy_duphandle.3
index 7b57cf051..bf413235c 100644
--- a/docs/libcurl/gnurl_easy_duphandle.3
+++ b/docs/libcurl/gnurl_easy_duphandle.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -39,10 +39,12 @@ will be pointed to by the new handle as well. You must therefore make sure to
keep the data around until both handles have been cleaned up.
The new handle will \fBnot\fP inherit any state information, no connections,
-no SSL sessions and no cookies.
+no SSL sessions and no cookies. It also will not inherit any share object
+states or options (it will be made as if \fICURLOPT_SHARE(3)\fP was set to
+NULL).
-\fBNote\fP that even in multi-threaded programs, this function must be called
-in a synchronous way, the input handle may not be in use when cloned.
+In multi-threaded programs, this function must be called in a synchronous way,
+the input handle may not be in use when cloned.
.SH RETURN VALUE
If this function returns NULL, something went wrong and no valid handle was
returned.
diff --git a/docs/libcurl/gnurl_easy_setopt.3 b/docs/libcurl/gnurl_easy_setopt.3
index f13771242..17ed4369d 100644
--- a/docs/libcurl/gnurl_easy_setopt.3
+++ b/docs/libcurl/gnurl_easy_setopt.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -313,6 +313,10 @@ File to write cookies to. See \fICURLOPT_COOKIEJAR(3)\fP
Start a new cookie session. See \fICURLOPT_COOKIESESSION(3)\fP
.IP CURLOPT_COOKIELIST
Add or control cookies. See \fICURLOPT_COOKIELIST(3)\fP
+.IP CURLOPT_ALTSVC
+Specify the Alt-Svc: cache file name. See \fICURLOPT_ALTSVC(3)\fP
+.IP CURLOPT_ALTSVC_CTRL
+Enable and configure Alt-Svc: treatment. See \fICURLOPT_ALTSVC_CTRL(3)\fP
.IP CURLOPT_HTTPGET
Do an HTTP GET request. See \fICURLOPT_HTTPGET(3)\fP
.IP CURLOPT_REQUEST_TARGET
diff --git a/docs/libcurl/gnurl_multi_remove_handle.3 b/docs/libcurl/gnurl_multi_remove_handle.3
index de87f726e..0987ea287 100644
--- a/docs/libcurl/gnurl_multi_remove_handle.3
+++ b/docs/libcurl/gnurl_multi_remove_handle.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -37,6 +37,9 @@ perfectly legal to invoke \fIcurl_easy_perform(3)\fP on this easy handle.
Removing an easy handle while being used is perfectly legal and will
effectively halt the transfer in progress involving that easy handle. All
other easy handles and transfers will remain unaffected.
+
+It is fine to remove a handle at any time during a transfer, just not from
+within any libcurl callback function.
.SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code.
.SH "SEE ALSO"
diff --git a/docs/libcurl/gnurl_url.3 b/docs/libcurl/gnurl_url.3
index 4b0439481..325865ae2 100644
--- a/docs/libcurl/gnurl_url.3
+++ b/docs/libcurl/gnurl_url.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -26,14 +26,6 @@ curl_url - returns a new CURLU handle
.B #include <gnurl/curl.h>
CURLU *curl_url();
-.SH EXPERIMENTAL
-The URL API is considered \fBEXPERIMENTAL\fP until further notice. Please test
-it, report bugs and help us perfect it. Once proven to be reliable, the
-experimental label will be removed.
-
-While this API is marked experimental, we reserve the right to modify the API
-slightly if we deem it necessary and it makes it notably better or easier to
-use.
.SH DESCRIPTION
This function will allocates and returns a pointer to a fresh CURLU handle, to
be used for further use of the URL API.
diff --git a/docs/libcurl/opts/CURLOPT_ALTSVC.3 b/docs/libcurl/opts/CURLOPT_ALTSVC.3
new file mode 100644
index 000000000..d6b5d87f8
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_ALTSVC.3
@@ -0,0 +1,61 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2019, 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 https://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.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_ALTSVC 3 "5 Feb 2019" "libcurl 7.64.1" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_ALTSVC \- set alt-svc cache file name
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ALTSVC, char *filename);
+.fi
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explictly telling configure with \fB--enable-alt-svc\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Pass in a pointer to a \fIfilename\fP to instruct libcurl to use that file as
+the Alt-Svc cache to read existing cache contents from and possibly also write
+it back to a after a transfer, unless \fBCURLALTSVC_READONLYFILE\fP is set in
+\fICURLOPT_ALTSVC_CTRL(3)\fP.
+.SH DEFAULT
+NULL. The alt-svc cache is not read nor written to file.
+.SH PROTOCOLS
+HTTPS
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, CURLALTSVC_H1);
+ curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt");
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.64.1
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_ALTSVC_CTRL "(3), " CURLOPT_CONNECT_TO "(3), " CURLOPT_RESOLVE "(3), "
+.BR CURLOPT_COOKIEFILE "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3 b/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3
new file mode 100644
index 000000000..bdbb382a3
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3
@@ -0,0 +1,92 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2019, 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 https://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.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_ALTSVC_CTRL 3 "5 Feb 2019" "libcurl 7.64.1" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_ALTSVC_CTRL \- control alt-svc behavior
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+#define CURLALTSVC_IMMEDIATELY (1<<0)
+#define CURLALTSVC_ALTUSED (1<<1)
+#define CURLALTSVC_READONLYFILE (1<<2)
+#define CURLALTSVC_H1 (1<<3)
+#define CURLALTSVC_H2 (1<<4)
+#define CURLALTSVC_H3 (1<<5)
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ALTSVC_CTRL, long bitmask);
+.fi
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explictly telling configure with \fB--enable-alt-svc\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Populate the long \fIbitmask\fP with the correct set of features to instruct
+libcurl how to handle Alt-Svc for the transfers using this handle.
+
+libcurl will only accept Alt-Svc headers over a secure transport, meaning
+HTTPS. It will also only complete a request to an alternative origin if that
+origin is properly hosted over HTTPS. These requirements are there to make
+sure both the source and the destination are legitimate.
+
+Setting any bit will enable the alt-svc engine.
+.IP "CURLALTSVC_IMMEDIATELY"
+If an Alt-Svc: header is received, this instructs libcurl to switch to one of
+those alternatives asap rather than to save it and use for the next request.
+.IP "CURLALTSVC_ALTUSED"
+Issue the Alt-Used: header in all requests that have been redirected by
+alt-svc.
+.IP "CURLALTSVC_READONLYFILE"
+Do not write the alt-svc cache back to the file specified with
+\fICURLOPT_ALTSVC(3)\fP even if it gets updated. By default a file specified
+with that option will be read and written to as deemed necessary.
+.IP "CURLALTSVC_H1"
+Accept alternative services offered over HTTP/1.1.
+.IP "CURLALTSVC_H2"
+Accept alternative services offered over HTTP/2. This will only be used if
+libcurl was also built to actually support HTTP/2, otherwise this bit will be
+ignored.
+.IP "CURLALTSVC_H3"
+Accept alternative services offered over HTTP/3. This will only be used if
+libcurl was also built to actually support HTTP/3, otherwise this bit will be
+ignored.
+.SH DEFAULT
+0. No Alt-Svc treatment.
+.SH PROTOCOLS
+HTTPS
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, CURLALTSVC_H1);
+ curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt");
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.64.1
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_ALTSVC "(3), " CURLOPT_CONNECT_TO "(3), " CURLOPT_RESOLVE "(3), "
diff --git a/docs/libcurl/opts/GNURLMOPT_PIPELINING.3 b/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
index a331ef8b9..50c9ba313 100644
--- a/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
+++ b/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
@@ -63,7 +63,7 @@ This bit is deprecated and has no effect since version 7.62.0.
If this bit is set, libcurl will try to multiplex the new transfer over an
existing connection if possible. This requires HTTP/2.
.SH DEFAULT
-Since 7.62.0, \fBCURLPIPE_MULTIPLEX\bP is enabled by default.
+Since 7.62.0, \fBCURLPIPE_MULTIPLEX\fP is enabled by default.
Before that, default was \fBCURLPIPE_NOTHING\fP.
.SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3 b/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
index 970e57a34..f60391f45 100644
--- a/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
+++ b/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -28,7 +28,7 @@ CURLMOPT_TIMERFUNCTION \- set callback to receive timeout values
#include <gnurl/curl.h>
int timer_callback(CURLM *multi, /* multi handle */
- long timeout_ms, /* see above */
+ long timeout_ms, /* timeout in number of ms */
void *userp); /* private callback pointer */
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_TIMERFUNCTION, timer_callback);
@@ -40,17 +40,15 @@ Certain features, such as timeouts and retries, require you to call libcurl
even when there is no activity on the file descriptors.
Your callback function \fBtimer_callback\fP should install a non-repeating
-timer with an interval of \fBtimeout_ms\fP. Each time that timer fires, call
+timer with an interval of \fBtimeout_ms\fP. When time that timer fires, call
either \fIcurl_multi_socket_action(3)\fP or \fIcurl_multi_perform(3)\fP,
depending on which interface you use.
-A \fBtimeout_ms\fP value of -1 means you should delete your timer.
+A \fBtimeout_ms\fP value of -1 passed to this callback means you should delete
+the timer. All other values are valid expire times in number of milliseconds.
-A \fBtimeout_ms\fP value of 0 means you should call
-\fIcurl_multi_socket_action(3)\fP or \fIcurl_multi_perform(3)\fP (once) as soon
-as possible.
-
-\fBtimer_callback\fP will only be called when the \fBtimeout_ms\fP changes.
+The \fBtimer_callback\fP will only be called when the timeout expire time is
+changed.
The \fBuserp\fP pointer is set with \fICURLMOPT_TIMERDATA(3)\fP.
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3 b/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
index b94a5c5ee..a01ba2117 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, 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
@@ -37,6 +37,9 @@ useful when used with the \fICURLINFO_ACTIVESOCKET(3)\fP option to
\fIcurl_easy_getinfo(3)\fP as the library can set up the connection and then
the application can obtain the most recently used socket for special data
transfers.
+
+Transfers marked connect only will not reuse any existing connections and
+connections marked connect only will not be allowed to get reused.
.SH DEFAULT
0
.SH PROTOCOLS
diff --git a/docs/libcurl/opts/Makefile.inc b/docs/libcurl/opts/Makefile.inc
index acd2d68ec..c6c2abdc4 100644
--- a/docs/libcurl/opts/Makefile.inc
+++ b/docs/libcurl/opts/Makefile.inc
@@ -83,6 +83,8 @@ man_MANS = \
GNURLOPT_ACCEPTTIMEOUT_MS.3 \
GNURLOPT_ACCEPT_ENCODING.3 \
GNURLOPT_ADDRESS_SCOPE.3 \
+ GNURLOPT_ALTSVC.3 \
+ GNURLOPT_ALTSVC_CTRL.3 \
GNURLOPT_APPEND.3 \
GNURLOPT_AUTOREFERER.3 \
GNURLOPT_BUFFERSIZE.3 \
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index f25009c2c..0f43aee31 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -12,6 +12,12 @@
Name Introduced Deprecated Removed
+CURLALTSVC_ALTUSED 7.64.1
+CURLALTSVC_H1 7.64.1
+CURLALTSVC_H2 7.64.1
+CURLALTSVC_H3 7.64.1
+CURLALTSVC_IMMEDIATELY 7.64.1
+CURLALTSVC_READONLYFILE 7.64.1
CURLAUTH_ANY 7.10.6
CURLAUTH_ANYSAFE 7.10.6
CURLAUTH_BASIC 7.10.6
@@ -343,6 +349,8 @@ CURLOPT_ABSTRACT_UNIX_SOCKET 7.53.0
CURLOPT_ACCEPTTIMEOUT_MS 7.24.0
CURLOPT_ACCEPT_ENCODING 7.21.6
CURLOPT_ADDRESS_SCOPE 7.19.0
+CURLOPT_ALTSVC 7.64.1
+CURLOPT_ALTSVC_CTRL 7.64.1
CURLOPT_APPEND 7.17.0
CURLOPT_AUTOREFERER 7.1
CURLOPT_BUFFERSIZE 7.10
@@ -432,8 +440,6 @@ CURLOPT_HTTPREQUEST 7.1 - 7.15.5
CURLOPT_HTTP_CONTENT_DECODING 7.16.2
CURLOPT_HTTP_TRANSFER_DECODING 7.16.2
CURLOPT_HTTP_VERSION 7.9.1
-CURLOPT_TRAILERFUNCTION 7.64.0
-CURLOPT_TRAILERDATA 7.64.0
CURLOPT_IGNORE_CONTENT_LENGTH 7.14.1
CURLOPT_INFILE 7.1 7.9.7
CURLOPT_INFILESIZE 7.1
@@ -615,6 +621,8 @@ CURLOPT_TLS13_CIPHERS 7.61.0
CURLOPT_TLSAUTH_PASSWORD 7.21.4
CURLOPT_TLSAUTH_TYPE 7.21.4
CURLOPT_TLSAUTH_USERNAME 7.21.4
+CURLOPT_TRAILERDATA 7.64.0
+CURLOPT_TRAILERFUNCTION 7.64.0
CURLOPT_TRANSFERTEXT 7.1.1
CURLOPT_TRANSFER_ENCODING 7.21.6
CURLOPT_UNIX_SOCKET_PATH 7.40.0
@@ -707,7 +715,7 @@ CURLSSH_AUTH_PUBLICKEY 7.16.1
CURLSSLBACKEND_AXTLS 7.38.0 7.61.0
CURLSSLBACKEND_BORINGSSL 7.49.0
CURLSSLBACKEND_CYASSL 7.34.0
-CURLSSLBACKEND_DARWINSSL 7.34.0
+CURLSSLBACKEND_DARWINSSL 7.34.0 7.64.1
CURLSSLBACKEND_GNUTLS 7.34.0
CURLSSLBACKEND_GSKIT 7.34.0
CURLSSLBACKEND_LIBRESSL 7.49.0
@@ -719,6 +727,7 @@ CURLSSLBACKEND_OPENSSL 7.34.0
CURLSSLBACKEND_POLARSSL 7.34.0
CURLSSLBACKEND_QSOSSL 7.34.0 - 7.38.1
CURLSSLBACKEND_SCHANNEL 7.34.0
+CURLSSLBACKEND_SECURETRANSPORT 7.64.1
CURLSSLBACKEND_WOLFSSL 7.49.0
CURLSSLOPT_ALLOW_BEAST 7.25.0
CURLSSLOPT_NO_REVOKE 7.44.0
@@ -854,8 +863,6 @@ CURL_PUSH_DENY 7.44.0
CURL_PUSH_OK 7.44.0
CURL_READFUNC_ABORT 7.12.1
CURL_READFUNC_PAUSE 7.18.0
-CURL_TRAILERFUNC_OK 7.64.0
-CURL_TRAILERFUNC_ABORT 7.64.0
CURL_REDIR_GET_ALL 7.19.1
CURL_REDIR_POST_301 7.19.1
CURL_REDIR_POST_302 7.19.1
@@ -902,7 +909,10 @@ CURL_TIMECOND_LASTMOD 7.9.7
CURL_TIMECOND_NONE 7.9.7
CURL_TLSAUTH_NONE 7.21.4
CURL_TLSAUTH_SRP 7.21.4
+CURL_TRAILERFUNC_ABORT 7.64.0
+CURL_TRAILERFUNC_OK 7.64.0
CURL_UPKEEP_INTERVAL_DEFAULT 7.62.0
+CURL_VERSION_ALTSVC 7.64.1
CURL_VERSION_ASYNCHDNS 7.10.7
CURL_VERSION_BROTLI 7.57.0
CURL_VERSION_CONV 7.15.4
diff --git a/include/gnurl/Makefile.am b/include/gnurl/Makefile.am
index 6bafa0400..b8298f29b 100644
--- a/include/gnurl/Makefile.am
+++ b/include/gnurl/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -25,8 +25,13 @@ pkginclude_HEADERS = \
pkgincludedir= $(includedir)/gnurl
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/gnurl $(pkginclude_HEADERS)
+ $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/gnurl $(pkginclude_HEADERS)
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
diff --git a/include/gnurl/curl.h b/include/gnurl/curl.h
index 88e1f39e8..86a24184a 100644
--- a/include/gnurl/curl.h
+++ b/include/gnurl/curl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -91,6 +91,11 @@
#include <support/SupportDefs.h>
#endif
+/* Compatibility for non-Clang compilers */
+#ifndef __has_declspec_attribute
+# define __has_declspec_attribute(x) 0
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -109,7 +114,9 @@ typedef void CURLSH;
#ifdef CURL_STATICLIB
# define CURL_EXTERN
-#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) || \
+ (__has_declspec_attribute(dllexport) && \
+ __has_declspec_attribute(dllimport))
# if defined(BUILDING_LIBCURL)
# define CURL_EXTERN __declspec(dllexport)
# else
@@ -144,7 +151,7 @@ typedef enum {
CURLSSLBACKEND_POLARSSL = 6,
CURLSSLBACKEND_WOLFSSL = 7,
CURLSSLBACKEND_SCHANNEL = 8,
- CURLSSLBACKEND_DARWINSSL = 9,
+ CURLSSLBACKEND_SECURETRANSPORT = 9,
CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
CURLSSLBACKEND_MBEDTLS = 11,
CURLSSLBACKEND_MESALINK = 12
@@ -153,7 +160,10 @@ typedef enum {
/* aliases for library clones and renames */
#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
+
+/* deprecated names: */
#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
+#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
struct curl_httppost {
struct curl_httppost *next; /* next entry in the list */
@@ -871,6 +881,14 @@ typedef enum {
#define CURLHEADER_UNIFIED 0
#define CURLHEADER_SEPARATE (1<<0)
+/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
+#define CURLALTSVC_IMMEDIATELY (1<<0)
+#define CURLALTSVC_ALTUSED (1<<1)
+#define CURLALTSVC_READONLYFILE (1<<2)
+#define CURLALTSVC_H1 (1<<3)
+#define CURLALTSVC_H2 (1<<4)
+#define CURLALTSVC_H3 (1<<5)
+
/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
#define CURLPROTO_HTTP (1<<0)
#define CURLPROTO_HTTPS (1<<1)
@@ -1894,6 +1912,12 @@ typedef enum {
/* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
CINIT(HTTP09_ALLOWED, LONG, 285),
+ /* alt-svc control bitmask */
+ CINIT(ALTSVC_CTRL, LONG, 286),
+
+ /* alt-svc cache file name to possibly read from/write to */
+ CINIT(ALTSVC, STRINGPOINT, 287),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2756,6 +2780,7 @@ typedef struct {
#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */
#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */
#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
+#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
/*
* NAME curl_version_info()
diff --git a/include/gnurl/curlver.h b/include/gnurl/curlver.h
index a6ceb3413..479cd8e6c 100644
--- a/include/gnurl/curlver.h
+++ b/include/gnurl/curlver.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -26,17 +26,17 @@
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */
-#define LIBCURL_COPYRIGHT "1996 - 2018 Daniel Stenberg, <daniel@haxx.se>."
+#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.64.0-DEV"
+#define LIBCURL_VERSION "7.64.1-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 64
-#define LIBCURL_VERSION_PATCH 0
+#define LIBCURL_VERSION_PATCH 1
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -57,7 +57,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x074000
+#define LIBCURL_VERSION_NUM 0x074001
/*
* This is the date and time when the full source package was created. The
diff --git a/include/gnurl/typecheck-gcc.h b/include/gnurl/typecheck-gcc.h
index 01df7b15f..8018ea37f 100644
--- a/include/gnurl/typecheck-gcc.h
+++ b/include/gnurl/typecheck-gcc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -256,6 +256,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
#define _curl_is_string_option(option) \
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
(option) == CURLOPT_ACCEPT_ENCODING || \
+ (option) == CURLOPT_ALTSVC || \
(option) == CURLOPT_CAINFO || \
(option) == CURLOPT_CAPATH || \
(option) == CURLOPT_COOKIE || \
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 8905e7107..6e8a83fad 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -131,9 +131,14 @@ include Makefile.inc
libgnurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS)
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \
- $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch]
+ $(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \
+ $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch])
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 54acd6cea..6c47bcda5 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -30,11 +30,11 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
vtls/polarssl.c vtls/polarssl_threadlock.c \
vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \
- vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
+ vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
- vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \
+ vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \
vtls/mbedtls.h vtls/mesalink.h
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
@@ -55,7 +55,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
- doh.c urlapi.c
+ doh.c urlapi.c altsvc.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@@ -75,7 +75,8 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
- curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h
+ curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
+ altsvc.h
LIB_RCFILES = libcurl.rc
diff --git a/lib/altsvc.c b/lib/altsvc.c
new file mode 100644
index 000000000..164346645
--- /dev/null
+++ b/lib/altsvc.c
@@ -0,0 +1,571 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, 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 https://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.
+ *
+ ***************************************************************************/
+/*
+ * The Alt-Svc: header is defined in RFC 7838:
+ * https://tools.ietf.org/html/rfc7838
+ */
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#include <curl/curl.h>
+#include "urldata.h"
+#include "altsvc.h"
+#include "cookie.h" /* for Curl_get_line() */
+#include "strcase.h"
+#include "parsedate.h"
+#include "sendf.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MAX_ALTSVC_LINE 4095
+#define MAX_ALTSVC_DATELENSTR "64"
+#define MAX_ALTSVC_DATELEN 64
+#define MAX_ALTSVC_HOSTLENSTR "512"
+#define MAX_ALTSVC_HOSTLEN 512
+#define MAX_ALTSVC_ALPNLENSTR "10"
+#define MAX_ALTSVC_ALPNLEN 10
+
+static enum alpnid alpn2alpnid(char *name)
+{
+ if(strcasecompare(name, "h1"))
+ return ALPN_h1;
+ if(strcasecompare(name, "h2"))
+ return ALPN_h2;
+ if(strcasecompare(name, "h2c"))
+ return ALPN_h2c;
+ if(strcasecompare(name, "h3"))
+ return ALPN_h3;
+ return ALPN_none; /* unknown, probably rubbish input */
+}
+
+/* Given the ALPN ID, return the name */
+const char *Curl_alpnid2str(enum alpnid id)
+{
+ switch(id) {
+ case ALPN_h1:
+ return "h1";
+ case ALPN_h2:
+ return "h2";
+ case ALPN_h2c:
+ return "h2c";
+ case ALPN_h3:
+ return "h3";
+ default:
+ return ""; /* bad */
+ }
+}
+
+
+static void altsvc_free(struct altsvc *as)
+{
+ free(as->srchost);
+ free(as->dsthost);
+ free(as);
+}
+
+static struct altsvc *altsvc_createid(const char *srchost,
+ const char *dsthost,
+ enum alpnid srcalpnid,
+ enum alpnid dstalpnid,
+ unsigned int srcport,
+ unsigned int dstport)
+{
+ struct altsvc *as = calloc(sizeof(struct altsvc), 1);
+ if(!as)
+ return NULL;
+
+ as->srchost = strdup(srchost);
+ if(!as->srchost)
+ goto error;
+ as->dsthost = strdup(dsthost);
+ if(!as->dsthost)
+ goto error;
+
+ as->srcalpnid = srcalpnid;
+ as->dstalpnid = dstalpnid;
+ as->srcport = curlx_ultous(srcport);
+ as->dstport = curlx_ultous(dstport);
+
+ return as;
+ error:
+ altsvc_free(as);
+ return NULL;
+}
+
+static struct altsvc *altsvc_create(char *srchost,
+ char *dsthost,
+ char *srcalpn,
+ char *dstalpn,
+ unsigned int srcport,
+ unsigned int dstport)
+{
+ enum alpnid dstalpnid = alpn2alpnid(dstalpn);
+ enum alpnid srcalpnid = alpn2alpnid(srcalpn);
+ if(!srcalpnid || !dstalpnid)
+ return NULL;
+ return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
+ srcport, dstport);
+}
+
+/* only returns SERIOUS errors */
+static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
+{
+ /* Example line:
+ h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
+ */
+ char srchost[MAX_ALTSVC_HOSTLEN + 1];
+ char dsthost[MAX_ALTSVC_HOSTLEN + 1];
+ char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
+ char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
+ char date[MAX_ALTSVC_DATELEN + 1];
+ unsigned int srcport;
+ unsigned int dstport;
+ unsigned int prio;
+ unsigned int persist;
+ int rc;
+
+ rc = sscanf(line,
+ "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
+ "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
+ "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
+ srcalpn, srchost, &srcport,
+ dstalpn, dsthost, &dstport,
+ date, &persist, &prio);
+ if(9 == rc) {
+ struct altsvc *as;
+ time_t expires = curl_getdate(date, NULL);
+ as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
+ if(as) {
+ as->expires = expires;
+ as->prio = prio;
+ as->persist = persist ? 1 : 0;
+ Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+ asi->num++; /* one more entry */
+ }
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Load alt-svc entries from the given file. The text based line-oriented file
+ * format is documented here:
+ * https://github.com/curl/curl/wiki/QUIC-implementation
+ *
+ * This function only returns error on major problems that prevents alt-svc
+ * handling to work completely. It will ignore individual syntactical errors
+ * etc.
+ */
+static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
+{
+ CURLcode result = CURLE_OK;
+ char *line = NULL;
+ FILE *fp = fopen(file, FOPEN_READTEXT);
+ if(fp) {
+ line = malloc(MAX_ALTSVC_LINE);
+ if(!line)
+ goto fail;
+ while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) {
+ char *lineptr = line;
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+ if(*lineptr == '#')
+ /* skip commented lines */
+ continue;
+
+ altsvc_add(asi, lineptr);
+ }
+ free(line); /* free the line buffer */
+ fclose(fp);
+ }
+ return result;
+
+ fail:
+ free(line);
+ fclose(fp);
+ return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Write this single altsvc entry to a single output line
+ */
+
+static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
+{
+ struct tm stamp;
+ CURLcode result = Curl_gmtime(as->expires, &stamp);
+ if(result)
+ return result;
+
+ fprintf(fp,
+ "%s %s %u "
+ "%s %s %u "
+ "\"%d%02d%02d "
+ "%02d:%02d:%02d\" "
+ "%u %d\n",
+ Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport,
+ Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport,
+ stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+ stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
+ as->persist, as->prio);
+ return CURLE_OK;
+}
+
+/* ---- library-wide functions below ---- */
+
+/*
+ * Curl_altsvc_init() creates a new altsvc cache.
+ * It returns the new instance or NULL if something goes wrong.
+ */
+struct altsvcinfo *Curl_altsvc_init(void)
+{
+ struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1);
+ if(!asi)
+ return NULL;
+ Curl_llist_init(&asi->list, NULL);
+
+ /* set default behavior */
+ asi->flags = CURLALTSVC_H1
+#ifdef USE_NGHTTP2
+ | CURLALTSVC_H2
+#endif
+#ifdef USE_HTTP3
+ /* TODO: adjust when known */
+ | CURLALTSVC_H3
+#endif
+ ;
+ return asi;
+}
+
+/*
+ * Curl_altsvc_load() loads alt-svc from file.
+ */
+CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
+{
+ CURLcode result;
+ DEBUGASSERT(asi);
+ result = altsvc_load(asi, file);
+ return result;
+}
+
+/*
+ * Curl_altsvc_ctrl() passes on the external bitmask.
+ */
+CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
+{
+ DEBUGASSERT(asi);
+ if(!ctrl)
+ /* unexpected */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ asi->flags = ctrl;
+ return CURLE_OK;
+}
+
+/*
+ * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
+ * resources.
+ */
+void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
+{
+ struct curl_llist_element *e;
+ struct curl_llist_element *n;
+ if(altsvc) {
+ for(e = altsvc->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ altsvc_free(as);
+ }
+ free(altsvc);
+ }
+}
+
+/*
+ * Curl_altsvc_save() writes the altsvc cache to a file.
+ */
+CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
+{
+ struct curl_llist_element *e;
+ struct curl_llist_element *n;
+ CURLcode result = CURLE_OK;
+ FILE *out;
+
+ if(!altsvc)
+ /* no cache activated */
+ return CURLE_OK;
+
+ if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0])
+ /* marked as read-only or zero length file name */
+ return CURLE_OK;
+ out = fopen(file, FOPEN_WRITETEXT);
+ if(!out)
+ return CURLE_WRITE_ERROR;
+ fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
+ "# This file was generated by libcurl! Edit at your own risk.\n",
+ out);
+ for(e = altsvc->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ result = altsvc_out(as, out);
+ if(result)
+ break;
+ }
+ fclose(out);
+ return result;
+}
+
+static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
+{
+ size_t len;
+ const char *protop;
+ const char *p = *ptr;
+ while(*p && ISBLANK(*p))
+ p++;
+ protop = p;
+ while(*p && ISALNUM(*p))
+ p++;
+ len = p - protop;
+
+ if(!len || (len >= buflen))
+ return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */
+ memcpy(alpnbuf, protop, len);
+ alpnbuf[len] = 0;
+ *ptr = p;
+ return CURLE_OK;
+}
+
+/* altsvc_flush() removes all alternatives for this source origin from the
+ list */
+static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
+ const char *srchost, unsigned short srcport)
+{
+ struct curl_llist_element *e;
+ struct curl_llist_element *n;
+ for(e = asi->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ if((srcalpnid == as->srcalpnid) &&
+ (srcport == as->srcport) &&
+ strcasecompare(srchost, as->srchost)) {
+ Curl_llist_remove(&asi->list, e, NULL);
+ altsvc_free(as);
+ asi->num--;
+ }
+ }
+}
+
+#ifdef DEBUGBUILD
+/* to play well with debug builds, we can *set* a fixed time this will
+ return */
+static time_t debugtime(void *unused)
+{
+ char *timestr = getenv("CURL_TIME");
+ (void)unused;
+ if(timestr) {
+ unsigned long val = strtol(timestr, NULL, 10);
+ return (time_t)val;
+ }
+ return time(NULL);
+}
+#define time(x) debugtime(x)
+#endif
+
+/*
+ * Curl_altsvc_parse() takes an incoming alt-svc response header and stores
+ * the data correctly in the cache.
+ *
+ * 'value' points to the header *value*. That's contents to the right of the
+ * header name.
+ */
+CURLcode Curl_altsvc_parse(struct Curl_easy *data,
+ struct altsvcinfo *asi, const char *value,
+ enum alpnid srcalpnid, const char *srchost,
+ unsigned short srcport)
+{
+ const char *p = value;
+ size_t len;
+ enum alpnid dstalpnid = srcalpnid; /* the same by default */
+ char namebuf[MAX_ALTSVC_HOSTLEN] = "";
+ char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
+ struct altsvc *as;
+ unsigned short dstport = srcport; /* the same by default */
+ const char *semip;
+ time_t maxage = 24 * 3600; /* default is 24 hours */
+ bool persist = FALSE;
+ CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+ if(result)
+ return result;
+
+ DEBUGASSERT(asi);
+
+ /* Flush all cached alternatives for this source origin, if any */
+ altsvc_flush(asi, srcalpnid, srchost, srcport);
+
+ /* "clear" is a magic keyword */
+ if(strcasecompare(alpnbuf, "clear")) {
+ /* TODO: clear whatever it is it should clear */
+ return CURLE_OK;
+ }
+
+ /* The 'ma' and 'persist' flags are annoyingly meant for all alternatives
+ but are set after the list on the line. Scan for the semicolons and get
+ those fields first! */
+ semip = p;
+ do {
+ semip = strchr(semip, ';');
+ if(semip) {
+ char option[32];
+ unsigned long num;
+ char *end_ptr;
+ semip++; /* pass the semicolon */
+ result = getalnum(&semip, option, sizeof(option));
+ if(result)
+ break;
+ while(*semip && ISBLANK(*semip))
+ semip++;
+ if(*semip != '=')
+ continue;
+ semip++;
+ num = strtoul(semip, &end_ptr, 10);
+ if(num < ULONG_MAX) {
+ if(strcasecompare("ma", option))
+ maxage = num;
+ else if(strcasecompare("persist", option) && (num == 1))
+ persist = TRUE;
+ }
+ semip = end_ptr;
+ }
+ } while(semip);
+
+ do {
+ if(*p == '=') {
+ /* [protocol]="[host][:port]" */
+ dstalpnid = alpn2alpnid(alpnbuf);
+ if(!dstalpnid) {
+ infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf);
+ return CURLE_OK;
+ }
+ p++;
+ if(*p == '\"') {
+ const char *dsthost;
+ p++;
+ if(*p != ':') {
+ /* host name starts here */
+ const char *hostp = p;
+ while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
+ p++;
+ len = p - hostp;
+ if(!len || (len >= MAX_ALTSVC_HOSTLEN))
+ return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */
+ memcpy(namebuf, hostp, len);
+ namebuf[len] = 0;
+ dsthost = namebuf;
+ }
+ else {
+ /* no destination name, use source host */
+ dsthost = srchost;
+ }
+ if(*p == ':') {
+ /* a port number */
+ char *end_ptr;
+ unsigned long port = strtoul(++p, &end_ptr, 10);
+ if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
+ infof(data, "Unknown alt-svc port number, ignoring...\n");
+ return CURLE_OK;
+ }
+ p = end_ptr;
+ dstport = curlx_ultous(port);
+ }
+ if(*p++ != '\"')
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ as = altsvc_createid(srchost, dsthost,
+ srcalpnid, dstalpnid,
+ srcport, dstport);
+ if(as) {
+ /* TODO: the expires time also needs to take the Age: value (if any)
+ into account. [See RFC 7838 section 3.1] */
+ as->expires = maxage + time(NULL);
+ as->persist = persist;
+ Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+ asi->num++; /* one more entry */
+ infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
+ Curl_alpnid2str(dstalpnid));
+ }
+ }
+ /* after the double quote there can be a comma if there's another
+ string or a semicolon if no more */
+ if(*p == ',') {
+ /* comma means another alternative is presented */
+ p++;
+ result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+ if(result)
+ /* failed to parse, but since we already did at least one host we
+ return OK */
+ return CURLE_OK;
+ }
+ }
+ } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
+
+ return CURLE_OK;
+}
+
+/*
+ * Return TRUE on a match
+ */
+bool Curl_altsvc_lookup(struct altsvcinfo *asi,
+ enum alpnid srcalpnid, const char *srchost,
+ int srcport,
+ enum alpnid *dstalpnid, const char **dsthost,
+ int *dstport)
+{
+ struct curl_llist_element *e;
+ struct curl_llist_element *n;
+ time_t now = time(NULL);
+ DEBUGASSERT(asi);
+ DEBUGASSERT(srchost);
+ DEBUGASSERT(dsthost);
+
+ for(e = asi->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ if(as->expires < now) {
+ /* an expired entry, remove */
+ altsvc_free(as);
+ continue;
+ }
+ if((as->srcalpnid == srcalpnid) &&
+ strcasecompare(as->srchost, srchost) &&
+ as->srcport == srcport) {
+ /* match */
+ *dstalpnid = as->dstalpnid;
+ *dsthost = as->dsthost;
+ *dstport = as->dstport;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
diff --git a/lib/altsvc.h b/lib/altsvc.h
new file mode 100644
index 000000000..eefb45bf6
--- /dev/null
+++ b/lib/altsvc.h
@@ -0,0 +1,77 @@
+#ifndef HEADER_CURL_ALTSVC_H
+#define HEADER_CURL_ALTSVC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, 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 https://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 "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#include <curl/curl.h>
+#include "llist.h"
+
+enum alpnid {
+ ALPN_none,
+ ALPN_h1,
+ ALPN_h2,
+ ALPN_h2c,
+ ALPN_h3
+};
+
+struct altsvc {
+ char *srchost;
+ char *dsthost;
+ unsigned short srcport;
+ unsigned short dstport;
+ enum alpnid srcalpnid;
+ enum alpnid dstalpnid;
+ time_t expires;
+ bool persist;
+ int prio;
+ struct curl_llist_element node;
+};
+
+struct altsvcinfo {
+ char *filename;
+ struct curl_llist list; /* list of entries */
+ size_t num; /* number of alt-svc entries */
+ long flags; /* the publicly set bitmask */
+};
+
+const char *Curl_alpnid2str(enum alpnid id);
+struct altsvcinfo *Curl_altsvc_init(void);
+CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
+void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
+CURLcode Curl_altsvc_parse(struct Curl_easy *data,
+ struct altsvcinfo *altsvc, const char *value,
+ enum alpnid srcalpn, const char *srchost,
+ unsigned short srcport);
+bool Curl_altsvc_lookup(struct altsvcinfo *asi,
+ enum alpnid srcalpnid, const char *srchost,
+ int srcport,
+ enum alpnid *dstalpnid, const char **dsthost,
+ int *dstport);
+#else
+/* disabled */
+#define Curl_altsvc_save(a,b)
+#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
+#endif /* HEADER_CURL_ALTSVC_H */
diff --git a/lib/amigaos.c b/lib/amigaos.c
index 4f55b30e7..cf44bdc8d 100644
--- a/lib/amigaos.c
+++ b/lib/amigaos.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -22,17 +22,26 @@
#include "curl_setup.h"
-#if defined(__AMIGA__) && !defined(__ixemul__)
-
-#include <amitcp/socketbasetags.h>
+#ifdef __AMIGA__
+# include "amigaos.h"
+# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
+# include <amitcp/socketbasetags.h>
+# endif
+# ifdef __libnix__
+# include <stabs.h>
+# endif
+#endif
-#include "amigaos.h"
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+#ifdef __AMIGA__
+#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
struct Library *SocketBase = NULL;
extern int errno, h_errno;
#ifdef __libnix__
-#include <stabs.h>
void __request(const char *msg);
#else
# define __request(msg) Printf(msg "\n\a")
@@ -74,4 +83,13 @@ bool Curl_amiga_init()
ADD2EXIT(Curl_amiga_cleanup, -50);
#endif
-#endif /* __AMIGA__ && ! __ixemul__ */
+#endif /* HAVE_PROTO_BSDSOCKET_H */
+
+#ifdef USE_AMISSL
+void Curl_amiga_X509_free(X509 *a)
+{
+ X509_free(a);
+}
+#endif /* USE_AMISSL */
+#endif /* __AMIGA__ */
+
diff --git a/lib/amigaos.h b/lib/amigaos.h
index 7c0926cc3..c776c9c9b 100644
--- a/lib/amigaos.h
+++ b/lib/amigaos.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -23,7 +23,7 @@
***************************************************************************/
#include "curl_setup.h"
-#if defined(__AMIGA__) && !defined(__ixemul__)
+#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL)
bool Curl_amiga_init();
void Curl_amiga_cleanup();
@@ -35,4 +35,10 @@ void Curl_amiga_cleanup();
#endif
+#ifdef USE_AMISSL
+#include <openssl/x509v3.h>
+void Curl_amiga_X509_free(X509 *a);
+#endif /* USE_AMISSL */
+
#endif /* HEADER_CURL_AMIGAOS_H */
+
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index a9679d062..55e0811c5 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -461,6 +461,42 @@ static CURLcode resolver_error(struct connectdata *conn)
return result;
}
+static CURLcode thread_wait_resolv(struct connectdata *conn,
+ struct Curl_dns_entry **entry,
+ bool report)
+{
+ struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(conn && td);
+ DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
+
+ /* wait for the thread to resolve the name */
+ if(Curl_thread_join(&td->thread_hnd)) {
+ if(entry)
+ result = getaddrinfo_complete(conn);
+ }
+ else
+ DEBUGASSERT(0);
+
+ conn->async.done = TRUE;
+
+ if(entry)
+ *entry = conn->async.dns;
+
+ if(!conn->async.dns && report)
+ /* a name was not resolved, report error */
+ result = resolver_error(conn);
+
+ destroy_async_data(&conn->async);
+
+ if(!conn->async.dns && report)
+ connclose(conn, "asynch resolve failed");
+
+ return result;
+}
+
+
/*
* Until we gain a way to signal the resolver threads to stop early, we must
* simply wait for them and ignore their results.
@@ -473,7 +509,7 @@ void Curl_resolver_kill(struct connectdata *conn)
unfortunately. Otherwise, we can simply cancel to clean up any resolver
data. */
if(td && td->thread_hnd != curl_thread_t_null)
- (void)Curl_resolver_wait_resolv(conn, NULL);
+ (void)thread_wait_resolv(conn, NULL, FALSE);
else
Curl_resolver_cancel(conn);
}
@@ -494,35 +530,7 @@ void Curl_resolver_kill(struct connectdata *conn)
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry)
{
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
- CURLcode result = CURLE_OK;
-
- DEBUGASSERT(conn && td);
- DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
-
- /* wait for the thread to resolve the name */
- if(Curl_thread_join(&td->thread_hnd)) {
- if(entry)
- result = getaddrinfo_complete(conn);
- }
- else
- DEBUGASSERT(0);
-
- conn->async.done = TRUE;
-
- if(entry)
- *entry = conn->async.dns;
-
- if(!conn->async.dns)
- /* a name was not resolved, report error */
- result = resolver_error(conn);
-
- destroy_async_data(&conn->async);
-
- if(!conn->async.dns)
- connclose(conn, "asynch resolve failed");
-
- return result;
+ return thread_wait_resolv(conn, entry, TRUE);
}
/*
diff --git a/lib/config-os400.h b/lib/config-os400.h
index 7844444fe..bde4f0b33 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -425,6 +425,9 @@
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME
+/* Define to enable alt-svc support (experimental) */
+#undef USE_ALTSVC
+
/* Version number of package */
#undef VERSION
diff --git a/lib/config-vxworks.h b/lib/config-vxworks.h
index a03e341e6..8790f8266 100644
--- a/lib/config-vxworks.h
+++ b/lib/config-vxworks.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -161,9 +161,6 @@
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#define HAVE_FCNTL_O_NONBLOCK 1
-/* Define to 1 if you have the fdopen function. */
-#define HAVE_FDOPEN 1
-
/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1
diff --git a/lib/conncache.c b/lib/conncache.c
index 463c57a3d..2c5d6b443 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -392,8 +392,8 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
NOTE: no locking is done here as this is presumably only done when cleaning
up a cache!
*/
-struct connectdata *
-Curl_conncache_find_first_connection(struct conncache *connc)
+static struct connectdata *
+conncache_find_first_connection(struct conncache *connc)
{
struct curl_hash_iterator iter;
struct curl_hash_element *he;
@@ -433,6 +433,7 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
data->multi->maxconnects;
struct connectdata *conn_candidate = NULL;
+ conn->data = NULL; /* no owner anymore */
if(maxconnects > 0 &&
Curl_conncache_size(data) > maxconnects) {
infof(data, "Connection cache is full, closing the oldest one.\n");
@@ -476,7 +477,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
while(curr) {
conn = curr->ptr;
- if(!CONN_INUSE(conn)) {
+ if(!CONN_INUSE(conn) && !conn->data) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@@ -534,7 +535,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
while(curr) {
conn = curr->ptr;
- if(!CONN_INUSE(conn)) {
+ if(!CONN_INUSE(conn) && !conn->data) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@@ -566,7 +567,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
{
struct connectdata *conn;
- conn = Curl_conncache_find_first_connection(connc);
+ conn = conncache_find_first_connection(connc);
while(conn) {
SIGPIPE_VARIABLE(pipe_st);
conn->data = connc->closure_handle;
@@ -577,7 +578,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
sigpipe_restore(&pipe_st);
- conn = Curl_conncache_find_first_connection(connc);
+ conn = conncache_find_first_connection(connc);
}
if(connc->closure_handle) {
diff --git a/lib/connect.c b/lib/connect.c
index ec3cd3a79..a53d79c21 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -446,9 +446,10 @@ static CURLcode bindlocal(struct connectdata *conn,
curl_socklen_t size = sizeof(add);
memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+ char buffer[STRERROR_LEN];
data->state.os_errno = error = SOCKERRNO;
failf(data, "getsockname() failed with errno %d: %s",
- error, Curl_strerror(conn, error));
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
return CURLE_INTERFACE_FAILED;
}
infof(data, "Local port: %hu\n", port);
@@ -470,10 +471,12 @@ static CURLcode bindlocal(struct connectdata *conn,
else
break;
}
-
- data->state.os_errno = error = SOCKERRNO;
- failf(data, "bind failed with errno %d: %s",
- error, Curl_strerror(conn, error));
+ {
+ char buffer[STRERROR_LEN];
+ data->state.os_errno = error = SOCKERRNO;
+ failf(data, "bind failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ }
return CURLE_INTERFACE_FAILED;
}
@@ -617,10 +620,13 @@ void Curl_persistconninfo(struct connectdata *conn)
conn->data->info.conn_local_port = conn->local_port;
}
+UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
+ long *port);
+
/* retrieves ip address and port from a sockaddr structure.
note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
-bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
- long *port)
+UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
+ long *port)
{
unsigned short us_port;
struct sockaddr_in *si = NULL;
@@ -683,11 +689,12 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
return;
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+ char buffer[STRERROR_LEN];
len = sizeof(struct Curl_sockaddr_storage);
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
int error = SOCKERRNO;
failf(data, "getpeername() failed with errno %d: %s",
- error, Curl_strerror(conn, error));
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
@@ -696,22 +703,22 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
int error = SOCKERRNO;
failf(data, "getsockname() failed with errno %d: %s",
- error, Curl_strerror(conn, error));
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
- if(!Curl_getaddressinfo((struct sockaddr*)&ssrem,
- conn->primary_ip, &conn->primary_port)) {
+ if(!getaddressinfo((struct sockaddr*)&ssrem,
+ conn->primary_ip, &conn->primary_port)) {
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
- if(!Curl_getaddressinfo((struct sockaddr*)&ssloc,
- conn->local_ip, &conn->local_port)) {
+ if(!getaddressinfo((struct sockaddr*)&ssloc,
+ conn->local_ip, &conn->local_port)) {
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
@@ -836,9 +843,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(conn->tempaddr[i]) {
CURLcode status;
char ipaddress[MAX_IPADR_LEN];
+ char buffer[STRERROR_LEN];
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
infof(data, "connect to %s port %ld failed: %s\n",
- ipaddress, conn->port, Curl_strerror(conn, error));
+ ipaddress, conn->port,
+ Curl_strerror(error, buffer, sizeof(buffer)));
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
allow : allow / 2;
@@ -854,8 +863,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(result) {
/* no more addresses to try */
-
const char *hostname;
+ char buffer[STRERROR_LEN];
/* if the first address family runs out of addresses to try before
the happy eyeball timeout, go ahead and try the next family now */
@@ -875,13 +884,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
hostname = conn->host.name;
failf(data, "Failed to connect to %s port %ld: %s",
- hostname, conn->port, Curl_strerror(conn, error));
+ hostname, conn->port,
+ Curl_strerror(error, buffer, sizeof(buffer)));
}
return result;
}
-void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
+static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
{
#if defined(TCP_NODELAY)
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -889,6 +899,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
#endif
curl_socklen_t onoff = (curl_socklen_t) 1;
int level = IPPROTO_TCP;
+ char buffer[STRERROR_LEN];
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
(void) conn;
@@ -897,7 +908,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s\n",
- Curl_strerror(conn, SOCKERRNO));
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
else
infof(data, "TCP_NODELAY set\n");
#else
@@ -917,9 +928,11 @@ static void nosigpipe(struct connectdata *conn,
struct Curl_easy *data = conn->data;
int onoff = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
- sizeof(onoff)) < 0)
+ sizeof(onoff)) < 0) {
+ char buffer[STRERROR_LEN];
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
- Curl_strerror(conn, SOCKERRNO));
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+ }
}
#else
#define nosigpipe(x,y) Curl_nop_stmt
@@ -995,6 +1008,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
#ifdef TCP_FASTOPEN_CONNECT
int optval = 1;
#endif
+ char buffer[STRERROR_LEN];
*sockp = CURL_SOCKET_BAD;
@@ -1006,11 +1020,11 @@ static CURLcode singleipconnect(struct connectdata *conn,
return CURLE_OK;
/* store remote address and port used in this connection attempt */
- if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr,
- ipaddress, &port)) {
+ if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
+ ipaddress, &port)) {
/* malformed address or bug in inet_ntop, try next address */
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
Curl_closesocket(conn, sockfd);
return CURLE_OK;
}
@@ -1023,7 +1037,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
#endif
if(is_tcp && data->set.tcp_nodelay)
- Curl_tcpnodelay(conn, sockfd);
+ tcpnodelay(conn, sockfd);
nosigpipe(conn, sockfd);
@@ -1146,7 +1160,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
default:
/* unknown error, fallthrough and try another address! */
infof(data, "Immediate connect fail for %s: %s\n",
- ipaddress, Curl_strerror(conn, error));
+ ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
data->state.os_errno = error;
/* connect failed */
@@ -1420,7 +1434,7 @@ void Curl_conncontrol(struct connectdata *conn,
if((ctrl == CONNCTRL_STREAM) &&
(conn->handler->flags & PROTOPT_STREAM))
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
- else if(closeit != conn->bits.close) {
+ else if((bit)closeit != conn->bits.close) {
DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
closeit?"closure":"keep alive", reason));
conn->bits.close = closeit; /* the only place in the source code that
diff --git a/lib/connect.h b/lib/connect.h
index 193dc6397..6a5c755cc 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -76,11 +76,6 @@ void Curl_persistconninfo(struct connectdata *conn);
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
/*
- * Get presentation format IP address and port from a sockaddr.
- */
-bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port);
-
-/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold any
* protocol-specific address structures. The variable declared here will be
@@ -111,8 +106,6 @@ CURLcode Curl_socket(struct connectdata *conn,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
-void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
-
/*
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
* argument specifies if it is the end of a connection or a stream.
diff --git a/lib/cookie.c b/lib/cookie.c
index 4fb992ac9..44851a52f 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -528,6 +528,19 @@ Curl_cookie_add(struct Curl_easy *data,
while(*whatptr && ISBLANK(*whatptr))
whatptr++;
+ /*
+ * Check if we have a reserved prefix set before anything else, as we
+ * otherwise have to test for the prefix in both the cookie name and
+ * "the rest". Prefixes must start with '__' and end with a '-', so
+ * only test for names where that can possibly be true.
+ */
+ if(nlen > 3 && name[0] == '_' && name[1] == '_') {
+ if(strncasecompare("__Secure-", name, 9))
+ co->prefix |= COOKIE_PREFIX__SECURE;
+ else if(strncasecompare("__Host-", name, 7))
+ co->prefix |= COOKIE_PREFIX__HOST;
+ }
+
if(!co->name) {
/* The very first name/value pair is the actual cookie name */
if(!sep) {
@@ -803,8 +816,6 @@ Curl_cookie_add(struct Curl_easy *data,
co->domain = strdup(ptr);
if(!co->domain)
badcookie = TRUE;
- else if(bad_domain(co->domain))
- badcookie = TRUE;
break;
case 1:
/* This field got its explanation on the 23rd of May 2001 by
@@ -862,6 +873,11 @@ Curl_cookie_add(struct Curl_easy *data,
co->name = strdup(ptr);
if(!co->name)
badcookie = TRUE;
+ /* For Netscape file format cookies we check prefix on the name */
+ if(strncasecompare("__Secure-", co->name, 9))
+ co->prefix |= COOKIE_PREFIX__SECURE;
+ else if(strncasecompare("__Host-", co->name, 7))
+ co->prefix |= COOKIE_PREFIX__HOST;
break;
case 6:
co->value = strdup(ptr);
@@ -890,6 +906,26 @@ Curl_cookie_add(struct Curl_easy *data,
}
+ if(co->prefix & COOKIE_PREFIX__SECURE) {
+ /* The __Secure- prefix only requires that the cookie be set secure */
+ if(!co->secure) {
+ freecookie(co);
+ return NULL;
+ }
+ }
+ if(co->prefix & COOKIE_PREFIX__HOST) {
+ /*
+ * The __Host- prefix requires the cookie to be secure, have a "/" path
+ * and not have a domain set.
+ */
+ if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
+ ;
+ else {
+ freecookie(co);
+ return NULL;
+ }
+ }
+
if(!c->running && /* read from a file */
c->newsession && /* clean session cookies */
!co->expires) { /* this is a session cookie since it doesn't expire! */
@@ -908,20 +944,18 @@ Curl_cookie_add(struct Curl_easy *data,
if(!noexpire)
remove_expired(c);
- if(domain && co->domain && !isip(co->domain)) {
- int acceptable;
#ifdef USE_LIBPSL
+ /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
+ if(domain && co->domain && !isip(co->domain)) {
const psl_ctx_t *psl = Curl_psl_use(data);
+ int acceptable;
- /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
if(psl) {
acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
Curl_psl_release(data);
}
else
-#endif
- /* Without libpsl, do the best we can. */
- acceptable = !bad_domain(co->domain);
+ acceptable = !bad_domain(domain);
if(!acceptable) {
infof(data, "cookie '%s' dropped, domain '%s' must not "
@@ -930,6 +964,7 @@ Curl_cookie_add(struct Curl_easy *data,
return NULL;
}
}
+#endif
myhash = cookiehash(co->domain);
clist = c->cookies[myhash];
@@ -1054,7 +1089,7 @@ Curl_cookie_add(struct Curl_easy *data,
* get_line() makes sure to only return complete whole lines that fit in 'len'
* bytes and end with a newline.
*/
-static char *get_line(char *buf, int len, FILE *input)
+char *Curl_get_line(char *buf, int len, FILE *input)
{
bool partial = FALSE;
while(1) {
@@ -1134,7 +1169,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
line = malloc(MAX_COOKIE_LINE);
if(!line)
goto fail;
- while(get_line(line, MAX_COOKIE_LINE, fp)) {
+ while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) {
if(checkprefix("Set-Cookie:", line)) {
/* This is a cookie line, get it! */
lineptr = &line[11];
@@ -1503,6 +1538,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
unsigned int j;
struct Cookie **array;
+ if(!c)
+ /* no cookie engine alive */
+ return 0;
+
/* at first, remove expired cookies */
remove_expired(c);
diff --git a/lib/cookie.h b/lib/cookie.h
index 609c30b1e..6e4108bb1 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -44,8 +44,16 @@ struct Cookie {
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
int creationtime; /* time when the cookie was written */
+ unsigned char prefix; /* bitmap fields indicating which prefix are set */
};
+/*
+ * Available cookie prefixes, as defined in
+ * draft-ietf-httpbis-rfc6265bis-02
+ */
+#define COOKIE_PREFIX__SECURE (1<<0)
+#define COOKIE_PREFIX__HOST (1<<1)
+
#define COOKIE_HASH_SIZE 256
struct CookieInfo {
@@ -93,6 +101,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
void Curl_cookie_freelist(struct Cookie *cookies);
void Curl_cookie_clearall(struct CookieInfo *cookies);
void Curl_cookie_clearsess(struct CookieInfo *cookies);
+char *Curl_get_line(char *buf, int len, FILE *input);
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
#define Curl_cookie_list(x) NULL
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index af1e65cef..05287fa9e 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -539,7 +539,7 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
defined(HAVE_FREEADDRINFO)
/*
- * curl_dofreeaddrinfo()
+ * curl_dbg_freeaddrinfo()
*
* This is strictly for memory tracing and are using the same style as the
* family otherwise present in memdebug.c. I put these ones here since they
@@ -547,23 +547,23 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
*/
void
-curl_dofreeaddrinfo(struct addrinfo *freethis,
- int line, const char *source)
+curl_dbg_freeaddrinfo(struct addrinfo *freethis,
+ int line, const char *source)
{
+ curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n",
+ source, line, (void *)freethis);
#ifdef USE_LWIPSOCK
lwip_freeaddrinfo(freethis);
#else
(freeaddrinfo)(freethis);
#endif
- curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
- source, line, (void *)freethis);
}
#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
/*
- * curl_dogetaddrinfo()
+ * curl_dbg_getaddrinfo()
*
* This is strictly for memory tracing and are using the same style as the
* family otherwise present in memdebug.c. I put these ones here since they
@@ -571,11 +571,11 @@ curl_dofreeaddrinfo(struct addrinfo *freethis,
*/
int
-curl_dogetaddrinfo(const char *hostname,
- const char *service,
- const struct addrinfo *hints,
- struct addrinfo **result,
- int line, const char *source)
+curl_dbg_getaddrinfo(const char *hostname,
+ const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **result,
+ int line, const char *source)
{
#ifdef USE_LWIPSOCK
int res = lwip_getaddrinfo(hostname, service, hints, result);
@@ -584,11 +584,11 @@ curl_dogetaddrinfo(const char *hostname,
#endif
if(0 == res)
/* success */
- curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
- source, line, (void *)*result);
+ curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
+ source, line, (void *)*result);
else
- curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
- source, line);
+ curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n",
+ source, line);
return res;
}
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index 8f6f3d106..205e121ea 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -86,17 +86,14 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
defined(HAVE_FREEADDRINFO)
void
-curl_dofreeaddrinfo(struct addrinfo *freethis,
- int line, const char *source);
+curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
#endif
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
int
-curl_dogetaddrinfo(const char *hostname,
- const char *service,
- const struct addrinfo *hints,
- struct addrinfo **result,
- int line, const char *source);
+curl_dbg_getaddrinfo(const char *hostname, const char *service,
+ const struct addrinfo *hints, struct addrinfo **result,
+ int line, const char *source);
#endif
#ifdef HAVE_GETADDRINFO
diff --git a/lib/curl_endian.c b/lib/curl_endian.c
index c25db4956..b7563b3de 100644
--- a/lib/curl_endian.c
+++ b/lib/curl_endian.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -82,7 +82,7 @@ unsigned short Curl_read16_be(const unsigned char *buf)
}
/*
- * Curl_write32_le()
+ * write32_le()
*
* This function converts a 32-bit integer from the native endian format,
* to little endian format ready for sending down the wire.
@@ -92,7 +92,7 @@ unsigned short Curl_read16_be(const unsigned char *buf)
* value [in] - The 32-bit integer value.
* buffer [in] - A pointer to the output buffer.
*/
-void Curl_write32_le(const int value, unsigned char *buffer)
+static void write32_le(const int value, unsigned char *buffer)
{
buffer[0] = (char)(value & 0x000000FF);
buffer[1] = (char)((value & 0x0000FF00) >> 8);
@@ -118,7 +118,7 @@ void Curl_write64_le(const long long value, unsigned char *buffer)
void Curl_write64_le(const __int64 value, unsigned char *buffer)
#endif
{
- Curl_write32_le((int)value, buffer);
- Curl_write32_le((int)(value >> 32), buffer + 4);
+ write32_le((int)value, buffer);
+ write32_le((int)(value >> 32), buffer + 4);
}
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index cad851569..3b7fc5026 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -21,7 +21,7 @@
***************************************************************************/
#include "curl_setup.h"
-
+#ifndef CURL_DISABLE_FTP
#include <gnurl/curl.h>
#include "curl_fnmatch.h"
@@ -394,3 +394,5 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
}
#endif
+
+#endif /* if FTP is disabled */
diff --git a/lib/curl_gssapi.h b/lib/curl_gssapi.h
index 9700a2817..88f68dbbb 100644
--- a/lib/curl_gssapi.h
+++ b/lib/curl_gssapi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2019, 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
@@ -26,19 +26,6 @@
#include "urldata.h"
#ifdef HAVE_GSSAPI
-
-#ifdef HAVE_GSSGNU
-# include <gss.h>
-#elif defined HAVE_GSSMIT
- /* MIT style */
-# include <gssapi/gssapi.h>
-# include <gssapi/gssapi_generic.h>
-# include <gssapi/gssapi_krb5.h>
-#else
- /* Heimdal-style */
-# include <gssapi.h>
-#endif
-
extern gss_OID_desc Curl_spnego_mech_oid;
extern gss_OID_desc Curl_krb5_mech_oid;
@@ -71,5 +58,4 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
#define GSSAUTH_P_PRIVACY 4
#endif /* HAVE_GSSAPI */
-
#endif /* HEADER_CURL_GSSAPI_H */
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 9eb6c43c8..e7060eb29 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -38,7 +38,7 @@
3. USE_GNUTLS
4. USE_NSS
5. USE_MBEDTLS
- 6. USE_DARWINSSL
+ 6. USE_SECTRANSP
7. USE_OS400CRYPTO
8. USE_WIN32_CRYPTO
@@ -101,7 +101,7 @@
# include "curl_md4.h"
# endif
-#elif defined(USE_DARWINSSL)
+#elif defined(USE_SECTRANSP)
# include <CommonCrypto/CommonCryptor.h>
# include <CommonCrypto/CommonDigest.h>
@@ -290,7 +290,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
}
-#elif defined(USE_DARWINSSL)
+#elif defined(USE_SECTRANSP)
static bool encrypt_des(const unsigned char *in, unsigned char *out,
const unsigned char *key_56)
@@ -437,7 +437,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
setup_des_key(keys + 14, &des);
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
gcry_cipher_close(des);
-#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \
+#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
encrypt_des(plaintext, results, keys);
encrypt_des(plaintext, results + 8, keys + 7);
@@ -501,7 +501,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
setup_des_key(pw + 7, &des);
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
gcry_cipher_close(des);
-#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \
+#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
encrypt_des(magic, lmbuffer, pw);
encrypt_des(magic, lmbuffer + 8, pw + 7);
@@ -591,7 +591,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
#else
Curl_md4it(ntbuffer, pw, 2 * len);
#endif
-#elif defined(USE_DARWINSSL)
+#elif defined(USE_SECTRANSP)
(void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
#elif defined(USE_OS400CRYPTO)
Curl_md4it(ntbuffer, pw, 2 * len);
@@ -621,9 +621,9 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
/* This returns the HMAC MD5 digest */
-CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
- const unsigned char *data, unsigned int datalen,
- unsigned char *output)
+static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen,
+ const unsigned char *data, unsigned int datalen,
+ unsigned char *output)
{
HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
@@ -668,9 +668,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
ascii_uppercase_to_unicode_le(identity, user, userlen);
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
- result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
- ntlmv2hash);
-
+ result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
+ ntlmv2hash);
free(identity);
return result;
@@ -756,8 +755,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
memcpy(ptr + 8, &ntlm->nonce[0], 8);
- result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
- NTLMv2_BLOB_LEN + 8, hmac_output);
+ result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+ NTLMv2_BLOB_LEN + 8, hmac_output);
if(result) {
free(ptr);
return result;
@@ -799,7 +798,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
memcpy(&data[0], challenge_server, 8);
memcpy(&data[8], challenge_client, 8);
- result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+ result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
if(result)
return result;
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index a4791eb41..18ee75dd9 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -124,6 +124,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
struct passwd pw, *pw_res;
char pwbuf[1024];
#endif
+ char buffer[STRERROR_LEN];
/* Return if communication with ntlm_auth already set up */
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
@@ -179,13 +180,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
if(access(ntlm_auth, X_OK) != 0) {
failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
- ntlm_auth, errno, Curl_strerror(conn, errno));
+ ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
failf(conn->data, "Could not open socket pair. errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
@@ -194,7 +195,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
sclose(sockfds[0]);
sclose(sockfds[1]);
failf(conn->data, "Could not fork. errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
else if(!child_pid) {
@@ -206,13 +207,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
sclose_nolog(sockfds[0]);
if(dup2(sockfds[1], STDIN_FILENO) == -1) {
failf(conn->data, "Could not redirect child stdin. errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
failf(conn->data, "Could not redirect child stdout. errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
@@ -232,7 +233,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
sclose_nolog(sockfds[1]);
failf(conn->data, "Could not execl(). errno %d: %s",
- errno, Curl_strerror(conn, errno));
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
diff --git a/lib/curl_path.c b/lib/curl_path.c
index 163b8d229..74406ace4 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -22,6 +22,8 @@
#include "curl_setup.h"
+#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+
#include <gnurl/curl.h>
#include "curl_memory.h"
#include "curl_path.h"
@@ -193,3 +195,5 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
Curl_safefree(*path);
return CURLE_QUOTE_ERROR;
}
+
+#endif /* if SSH is used */
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index f5c94c73c..d92b0b39d 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
@@ -239,17 +239,18 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
static CURLcode rtmp_do(struct connectdata *conn, bool *done)
{
+ struct Curl_easy *data = conn->data;
RTMP *r = conn->proto.generic;
if(!RTMP_ConnectStream(r, 0))
return CURLE_FAILED_INIT;
if(conn->data->set.upload) {
- Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
}
else
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
*done = TRUE;
return CURLE_OK;
}
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index a4dd1de43..26c3646e8 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -310,11 +310,12 @@
#endif
#ifdef __AMIGA__
-# ifndef __ixemul__
-# include <exec/types.h>
-# include <exec/execbase.h>
-# include <proto/exec.h>
-# include <proto/dos.h>
+# include <exec/types.h>
+# include <exec/execbase.h>
+# include <proto/exec.h>
+# include <proto/dos.h>
+# ifdef HAVE_PROTO_BSDSOCKET_H
+# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
# endif
#endif
@@ -648,7 +649,7 @@ int netware_init(void);
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
- defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK)
+ defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK)
#define USE_SSL /* SSL support has been enabled */
#endif
@@ -667,7 +668,7 @@ int netware_init(void);
/* Single point where USE_NTLM definition might be defined */
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
- defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
+ defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
defined(USE_MBEDTLS)
@@ -816,4 +817,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
size_t buflen, struct passwd **result);
#endif
+#ifdef DEBUGBUILD
+#define UNITTEST
+#else
+#define UNITTEST static
+#endif
+
#endif /* HEADER_CURL_SETUP_H */
diff --git a/lib/dict.c b/lib/dict.c
index 02141cace..c93bf575a 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -137,7 +137,6 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
char *path = data->state.up.path;
- curl_off_t *bytecount = &data->req.bytecount;
*done = TRUE; /* unconditionally */
@@ -200,8 +199,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
failf(data, "Failed sending DICT request");
return result;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL); /* no upload */
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */
}
else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
@@ -247,8 +245,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
failf(data, "Failed sending DICT request");
return result;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL); /* no upload */
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
}
else {
@@ -270,7 +267,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
return result;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
}
}
diff --git a/lib/doh.c b/lib/doh.c
index f06ed3311..b5327c4ae 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -173,8 +173,12 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result)
return 0;
}
-#define ERROR_CHECK_SETOPT(x,y) result = curl_easy_setopt(doh, x, y); \
- if(result) goto error
+#define ERROR_CHECK_SETOPT(x,y) \
+do { \
+ result = curl_easy_setopt(doh, x, y); \
+ if(result) \
+ goto error; \
+} WHILE_FALSE
static CURLcode dohprobe(struct Curl_easy *data,
struct dnsprobe *p, DNStype dnstype,
@@ -242,7 +246,68 @@ static CURLcode dohprobe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
#endif
ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms);
- ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L);
+ if(data->set.verbose)
+ ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L);
+ if(data->set.no_signal)
+ ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L);
+
+ /* Inherit *some* SSL options from the user's transfer. This is a
+ best-guess as to which options are needed for compatibility. #3661 */
+ if(data->set.ssl.falsestart)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L);
+ if(data->set.ssl.primary.verifyhost)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L);
+ if(data->set.proxy_ssl.primary.verifyhost)
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L);
+ if(data->set.ssl.primary.verifypeer)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
+ if(data->set.proxy_ssl.primary.verifypeer)
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+ if(data->set.ssl.primary.verifystatus)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L);
+ if(data->set.str[STRING_SSL_CAFILE_ORIG]) {
+ ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
+ data->set.str[STRING_SSL_CAFILE_ORIG]);
+ }
+ if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
+ data->set.str[STRING_SSL_CAFILE_PROXY]);
+ }
+ if(data->set.str[STRING_SSL_CAPATH_ORIG]) {
+ ERROR_CHECK_SETOPT(CURLOPT_CAPATH,
+ data->set.str[STRING_SSL_CAPATH_ORIG]);
+ }
+ if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
+ data->set.str[STRING_SSL_CAPATH_PROXY]);
+ }
+ if(data->set.str[STRING_SSL_CRLFILE_ORIG]) {
+ ERROR_CHECK_SETOPT(CURLOPT_CRLFILE,
+ data->set.str[STRING_SSL_CRLFILE_ORIG]);
+ }
+ if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
+ data->set.str[STRING_SSL_CRLFILE_PROXY]);
+ }
+ if(data->set.ssl.certinfo)
+ ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L);
+ if(data->set.str[STRING_SSL_RANDOM_FILE]) {
+ ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE,
+ data->set.str[STRING_SSL_RANDOM_FILE]);
+ }
+ if(data->set.str[STRING_SSL_EGDSOCKET]) {
+ ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET,
+ data->set.str[STRING_SSL_EGDSOCKET]);
+ }
+ if(data->set.ssl.no_revoke)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+ if(data->set.proxy_ssl.no_revoke)
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+ if(data->set.ssl.fsslctx)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
+ if(data->set.ssl.fsslctxp)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp);
+
doh->set.fmultidone = Curl_doh_done;
doh->set.dohfor = data; /* identify for which transfer this is done */
p->easy = doh;
diff --git a/lib/easy.c b/lib/easy.c
index 0574372f8..9e902623b 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -75,6 +75,7 @@
#include "ssh.h"
#include "setopt.h"
#include "http_digest.h"
+#include "system_win32.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -83,70 +84,6 @@
void Curl_version_init(void);
-/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
- of win32_init() */
-static void win32_cleanup(void)
-{
-#ifdef USE_WINSOCK
- WSACleanup();
-#endif
-#ifdef USE_WINDOWS_SSPI
- Curl_sspi_global_cleanup();
-#endif
-}
-
-/* win32_init() performs win32 socket initialization to properly setup the
- stack to allow networking */
-static CURLcode win32_init(void)
-{
-#ifdef USE_WINSOCK
- WORD wVersionRequested;
- WSADATA wsaData;
- int res;
-
-#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
- Error IPV6_requires_winsock2
-#endif
-
- wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
-
- res = WSAStartup(wVersionRequested, &wsaData);
-
- if(res != 0)
- /* Tell the user that we couldn't find a usable */
- /* winsock.dll. */
- return CURLE_FAILED_INIT;
-
- /* Confirm that the Windows Sockets DLL supports what we need.*/
- /* Note that if the DLL supports versions greater */
- /* than wVersionRequested, it will still return */
- /* wVersionRequested in wVersion. wHighVersion contains the */
- /* highest supported version. */
-
- if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
- HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
- /* Tell the user that we couldn't find a usable */
-
- /* winsock.dll. */
- WSACleanup();
- return CURLE_FAILED_INIT;
- }
- /* The Windows Sockets DLL is acceptable. Proceed. */
-#elif defined(USE_LWIPSOCK)
- lwip_init();
-#endif
-
-#ifdef USE_WINDOWS_SSPI
- {
- CURLcode result = Curl_sspi_global_init();
- if(result)
- return result;
- }
-#endif
-
- return CURLE_OK;
-}
-
/* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized;
static long init_flags;
@@ -223,11 +160,12 @@ static CURLcode global_init(long flags, bool memoryfuncs)
return CURLE_FAILED_INIT;
}
- if(flags & CURL_GLOBAL_WIN32)
- if(win32_init()) {
- DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
- return CURLE_FAILED_INIT;
- }
+#ifdef WIN32
+ if(Curl_win32_init(flags)) {
+ DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+#endif
#ifdef __AMIGA__
if(!Curl_amiga_init()) {
@@ -331,8 +269,9 @@ void curl_global_cleanup(void)
Curl_ssl_cleanup();
Curl_resolver_global_cleanup();
- if(init_flags & CURL_GLOBAL_WIN32)
- win32_cleanup();
+#ifdef WIN32
+ Curl_win32_cleanup(init_flags);
+#endif
Curl_amiga_cleanup();
diff --git a/lib/file.c b/lib/file.c
index 2d2963f0b..45b16de48 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -311,7 +311,7 @@ static CURLcode file_upload(struct connectdata *conn)
if(result)
break;
- if(readcount <= 0) /* fix questionable compare error. curlvms */
+ if(!readcount)
break;
nread = readcount;
diff --git a/lib/ftp.c b/lib/ftp.c
index 820da228f..132813666 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -448,7 +448,6 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
static CURLcode InitiateTransfer(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
CURLcode result = CURLE_OK;
if(conn->bits.ftp_use_data_ssl) {
@@ -461,24 +460,19 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
}
if(conn->proto.ftpc.state_saved == FTP_STOR) {
- *(ftp->bytecountp) = 0;
-
/* When we know we're uploading a specified file, we can get the file
size prior to the actual upload. */
-
Curl_pgrsSetUploadSize(data, data->state.infilesize);
/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
- SECONDARYSOCKET, ftp->bytecountp);
+ Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET);
}
else {
/* FTP download: */
- Curl_setup_transfer(conn, SECONDARYSOCKET,
- conn->proto.ftpc.retr_size_saved, FALSE,
- ftp->bytecountp, -1, NULL); /* no upload here */
+ Curl_setup_transfer(data, SECONDARYSOCKET,
+ conn->proto.ftpc.retr_size_saved, FALSE, -1);
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
@@ -955,7 +949,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
unsigned short port_max = 0;
unsigned short port;
bool possibly_non_local = TRUE;
-
+ char buffer[STRERROR_LEN];
char *addr = NULL;
/* Step 1, figure out what is requested,
@@ -1064,11 +1058,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(!host) {
/* not an interface and not a host name, get default by extracting
the IP from the control connection */
-
sslen = sizeof(ss);
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, SOCKERRNO) );
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
free(addr);
return CURLE_FTP_PORT_FAILED;
}
@@ -1121,7 +1114,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
break;
}
if(!ai) {
- failf(data, "socket failure: %s", Curl_strerror(conn, error));
+ failf(data, "socket failure: %s",
+ Curl_strerror(error, buffer, sizeof(buffer)));
return CURLE_FTP_PORT_FAILED;
}
@@ -1145,14 +1139,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
/* The requested bind address is not local. Use the address used for
* the control connection instead and restart the port loop
*/
-
infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
- Curl_strerror(conn, error) );
+ Curl_strerror(error, buffer, sizeof(buffer)));
sslen = sizeof(ss);
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, SOCKERRNO) );
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
Curl_closesocket(conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
@@ -1162,7 +1155,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
}
if(error != EADDRINUSE && error != EACCES) {
failf(data, "bind(port=%hu) failed: %s", port,
- Curl_strerror(conn, error) );
+ Curl_strerror(error, buffer, sizeof(buffer)));
Curl_closesocket(conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
@@ -1185,7 +1178,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
sslen = sizeof(ss);
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, SOCKERRNO) );
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
Curl_closesocket(conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
@@ -1193,7 +1186,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
/* step 4, listen on the socket */
if(listen(portsock, 1)) {
- failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
+ failf(data, "socket failure: %s",
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
Curl_closesocket(conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
@@ -1658,7 +1652,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
infof(data, "File already completely uploaded\n");
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
/* Set ->transfer so that we won't get any error in
* ftp_done() because we didn't transfer anything! */
@@ -2230,7 +2224,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
if(ftp->downloadsize == 0) {
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
infof(data, "File already completely downloaded\n");
/* Set ->transfer so that we won't get any error in ftp_done()
@@ -3308,33 +3302,33 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
;
else if(data->set.upload) {
if((-1 != data->state.infilesize) &&
- (data->state.infilesize != *ftp->bytecountp) &&
+ (data->state.infilesize != data->req.writebytecount) &&
!data->set.crlf &&
(ftp->transfer == FTPTRANSFER_BODY)) {
failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
" out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
- *ftp->bytecountp, data->state.infilesize);
+ data->req.bytecount, data->state.infilesize);
result = CURLE_PARTIAL_FILE;
}
}
else {
if((-1 != data->req.size) &&
- (data->req.size != *ftp->bytecountp) &&
+ (data->req.size != data->req.bytecount) &&
#ifdef CURL_DO_LINEEND_CONV
/* Most FTP servers don't adjust their file SIZE response for CRLFs, so
* we'll check to see if the discrepancy can be explained by the number
* of CRLFs we've changed to LFs.
*/
((data->req.size + data->state.crlf_conversions) !=
- *ftp->bytecountp) &&
+ data->req.bytecount) &&
#endif /* CURL_DO_LINEEND_CONV */
- (data->req.maxdownload != *ftp->bytecountp)) {
+ (data->req.maxdownload != data->req.bytecount)) {
failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
- " bytes", *ftp->bytecountp);
+ " bytes", data->req.bytecount);
result = CURLE_PARTIAL_FILE;
}
else if(!ftpc->dont_check &&
- !*ftp->bytecountp &&
+ !data->req.bytecount &&
(data->req.size>0)) {
failf(data, "No data was received!");
result = CURLE_FTP_COULDNT_RETR_FILE;
@@ -3629,7 +3623,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
if(!result && (ftp->transfer != FTPTRANSFER_BODY))
/* no data to transfer. FIX: it feels like a kludge to have this here
too! */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
if(!ftpc->wait_data_conn) {
/* no waiting for the data connection so this is now complete */
@@ -4308,7 +4302,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
if(ftp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
else if(!connected)
/* since we didn't connect now, we want do_more to get called */
conn->bits.do_more = TRUE;
@@ -4395,7 +4389,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY;
ftp->path = &data->state.up.path[1]; /* don't include the initial slash */
- data->state.slash_removed = TRUE; /* we've skipped the slash */
/* FTP URLs support an extension like ";type=<typecode>" that
* we'll try to get now! */
@@ -4428,7 +4421,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
}
/* get some initial data into the ftp struct */
- ftp->bytecountp = &conn->data->req.bytecount;
ftp->transfer = FTPTRANSFER_BODY;
ftp->downloadsize = 0;
diff --git a/lib/ftp.h b/lib/ftp.h
index 38d03223c..828d69a21 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -102,7 +102,6 @@ typedef enum {
perhaps the Curl_easy is changed between the times the connection is
used. */
struct FTP {
- curl_off_t *bytecountp;
char *user; /* user name string */
char *passwd; /* password string */
char *path; /* points to the urlpieces struct field */
diff --git a/lib/getinfo.c b/lib/getinfo.c
index a883bb497..5305090b4 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -163,10 +163,10 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
*param_longp = (long)data->info.filetime;
break;
case CURLINFO_HEADER_SIZE:
- *param_longp = data->info.header_size;
+ *param_longp = (long)data->info.header_size;
break;
case CURLINFO_REQUEST_SIZE:
- *param_longp = data->info.request_size;
+ *param_longp = (long)data->info.request_size;
break;
case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->set.ssl.certverifyresult;
diff --git a/lib/gopher.c b/lib/gopher.c
index d1bcadf5b..a7e3ebb08 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -78,8 +78,6 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-
- curl_off_t *bytecount = &data->req.bytecount;
char *gopherpath;
char *path = data->state.up.path;
char *query = data->state.up.query;
@@ -90,7 +88,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
*done = TRUE; /* unconditionally */
- if(path && query)
+ /* path is guaranteed non-NULL */
+ DEBUGASSERT(path);
+
+ if(query)
gopherpath = aprintf("%s?%s", path, query);
else
gopherpath = strdup(path);
@@ -167,8 +168,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
if(result)
return result;
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL); /* no upload */
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
return CURLE_OK;
}
#endif /*CURL_DISABLE_GOPHER*/
diff --git a/lib/hostasyn.c b/lib/hostasyn.c
index 6ff60ba61..99d872b35 100644
--- a/lib/hostasyn.c
+++ b/lib/hostasyn.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -85,14 +85,14 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
dns = Curl_cache_addr(data, ai,
conn->async.hostname,
conn->async.port);
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
if(!dns) {
/* failed to store, cleanup and return error */
Curl_freeaddrinfo(ai);
result = CURLE_OUT_OF_MEMORY;
}
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
else {
result = CURLE_OUT_OF_MEMORY;
diff --git a/lib/hostip.c b/lib/hostip.c
index 89b88e932..7909141c1 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -73,6 +73,8 @@
#define USE_ALARM_TIMEOUT
#endif
+#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */
+
/*
* hostip.c explained
* ==================
@@ -198,23 +200,19 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
}
/*
- * Return a hostcache id string for the provided host + port, to be used by
- * the DNS caching.
+ * Create a hostcache id string for the provided host + port, to be used by
+ * the DNS caching. Without alloc.
*/
-static char *
-create_hostcache_id(const char *name, int port)
+static void
+create_hostcache_id(const char *name, int port, char *ptr, size_t buflen)
{
- /* create and return the new allocated entry */
- char *id = aprintf("%s:%d", name, port);
- char *ptr = id;
- if(ptr) {
- /* lower case the name part */
- while(*ptr && (*ptr != ':')) {
- *ptr = (char)TOLOWER(*ptr);
- ptr++;
- }
- }
- return id;
+ size_t len = strlen(name);
+ if(len > (buflen - 7))
+ len = buflen - 7;
+ /* store and lower case the name */
+ while(len--)
+ *ptr++ = (char)TOLOWER(*name++);
+ msnprintf(ptr, 7, ":%u", port);
}
struct hostcache_prune_data {
@@ -296,17 +294,13 @@ fetch_addr(struct connectdata *conn,
const char *hostname,
int port)
{
- char *entry_id = NULL;
struct Curl_dns_entry *dns = NULL;
size_t entry_len;
struct Curl_easy *data = conn->data;
+ char entry_id[MAX_HOSTCACHE_LEN];
/* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if(!entry_id)
- return dns;
-
+ create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
entry_len = strlen(entry_id);
/* See if its already in our dns cache */
@@ -314,18 +308,7 @@ fetch_addr(struct connectdata *conn,
/* No entry found in cache, check if we might have a wildcard entry */
if(!dns && data->change.wildcard_resolve) {
- /*
- * Free the previous entry_id before requesting a new one to avoid leaking
- * memory
- */
- free(entry_id);
-
- entry_id = create_hostcache_id("*", port);
-
- /* If we can't create the entry id, fail */
- if(!entry_id)
- return dns;
-
+ create_hostcache_id("*", port, entry_id, sizeof(entry_id));
entry_len = strlen(entry_id);
/* See if it's already in our dns cache */
@@ -346,9 +329,6 @@ fetch_addr(struct connectdata *conn,
}
}
- /* free the allocated entry_id again */
- free(entry_id);
-
return dns;
}
@@ -388,6 +368,9 @@ Curl_fetch_addr(struct connectdata *conn,
return dns;
}
+UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
+ Curl_addrinfo **addr);
+
/*
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
* struct by re-linking its linked list.
@@ -400,7 +383,8 @@ Curl_fetch_addr(struct connectdata *conn,
*
* @unittest: 1608
*/
-CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr)
+UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
+ Curl_addrinfo **addr)
{
CURLcode result = CURLE_OK;
const int num_addrs = Curl_num_addresses(*addr);
@@ -467,7 +451,7 @@ Curl_cache_addr(struct Curl_easy *data,
const char *hostname,
int port)
{
- char *entry_id;
+ char entry_id[MAX_HOSTCACHE_LEN];
size_t entry_len;
struct Curl_dns_entry *dns;
struct Curl_dns_entry *dns2;
@@ -479,20 +463,16 @@ Curl_cache_addr(struct Curl_easy *data,
return NULL;
}
- /* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if(!entry_id)
- return NULL;
- entry_len = strlen(entry_id);
-
/* Create a new cache entry */
dns = calloc(1, sizeof(struct Curl_dns_entry));
if(!dns) {
- free(entry_id);
return NULL;
}
+ /* Create an entry id, based upon the hostname and port */
+ create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
+ entry_len = strlen(entry_id);
+
dns->inuse = 1; /* the cache has the first reference */
dns->addr = addr; /* this is the address(es) */
time(&dns->timestamp);
@@ -504,16 +484,11 @@ Curl_cache_addr(struct Curl_easy *data,
(void *)dns);
if(!dns2) {
free(dns);
- free(entry_id);
return NULL;
}
dns = dns2;
dns->inuse++; /* mark entry as in-use */
-
- /* free the allocated entry_id */
- free(entry_id);
-
return dns;
}
@@ -568,7 +543,7 @@ int Curl_resolv(struct connectdata *conn,
/* The entry was not in the cache. Resolve it to IP address */
Curl_addrinfo *addr;
- int respwait;
+ int respwait = 0;
/* Check what IP specifics the app has requested and if we can provide it.
* If not, bail out. */
@@ -896,10 +871,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
data->change.wildcard_resolve = false;
for(hostp = data->change.resolve; hostp; hostp = hostp->next) {
+ char entry_id[MAX_HOSTCACHE_LEN];
if(!hostp->data)
continue;
if(hostp->data[0] == '-') {
- char *entry_id;
size_t entry_len;
if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
@@ -909,12 +884,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
}
/* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if(!entry_id) {
- return CURLE_OUT_OF_MEMORY;
- }
-
+ create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
entry_len = strlen(entry_id);
if(data->share)
@@ -925,14 +895,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-
- /* free the allocated entry_id again */
- free(entry_id);
}
else {
struct Curl_dns_entry *dns;
Curl_addrinfo *head = NULL, *tail = NULL;
- char *entry_id;
size_t entry_len;
char address[64];
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -1028,12 +994,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
}
/* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if(!entry_id) {
- Curl_freeaddrinfo(head);
- return CURLE_OUT_OF_MEMORY;
- }
+ create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
entry_len = strlen(entry_id);
if(data->share)
@@ -1054,8 +1015,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
}
- /* free the allocated entry_id again */
- free(entry_id);
/* put this new host in the cache */
dns = Curl_cache_addr(data, head, hostname, port);
diff --git a/lib/hostip.h b/lib/hostip.h
index 29fd1ef7c..cd43882af 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -179,16 +179,6 @@ Curl_fetch_addr(struct connectdata *conn,
int port);
/*
- * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
- * struct by re-linking its linked list.
- *
- * The addr argument should be the address of a pointer to the head node of a
- * `Curl_addrinfo` list and it will be modified to point to the new head after
- * shuffling.
- */
-CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr);
-
-/*
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
*
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
diff --git a/lib/hostip6.c b/lib/hostip6.c
index e06d0343a..fb2f35ce3 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -101,14 +101,15 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
{
printf("dump_addrinfo:\n");
for(; ai; ai = ai->ai_next) {
- char buf[INET6_ADDRSTRLEN];
-
+ char buf[INET6_ADDRSTRLEN];
+ char buffer[STRERROR_LEN];
printf(" fam %2d, CNAME %s, ",
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
if(Curl_printable_address(ai, buf, sizeof(buf)))
printf("%s\n", buf);
else
- printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
+ printf("failed; %s\n",
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
}
}
#else
diff --git a/lib/http.c b/lib/http.c
index 83d23c258..5a70c4d23 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -77,6 +77,7 @@
#include "http2.h"
#include "connect.h"
#include "strdup.h"
+#include "altsvc.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -102,13 +103,14 @@ static int https_getsock(struct connectdata *conn,
#else
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
#endif
+static CURLcode http_setup_conn(struct connectdata *conn);
/*
* HTTP handler interface.
*/
const struct Curl_handler Curl_handler_http = {
"HTTP", /* scheme */
- Curl_http_setup_conn, /* setup_connection */
+ http_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
ZERO_NULL, /* do_more */
@@ -133,7 +135,7 @@ const struct Curl_handler Curl_handler_http = {
*/
const struct Curl_handler Curl_handler_https = {
"HTTPS", /* scheme */
- Curl_http_setup_conn, /* setup_connection */
+ http_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
ZERO_NULL, /* do_more */
@@ -153,7 +155,7 @@ const struct Curl_handler Curl_handler_https = {
};
#endif
-CURLcode Curl_http_setup_conn(struct connectdata *conn)
+static CURLcode http_setup_conn(struct connectdata *conn)
{
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
@@ -415,7 +417,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
break;
}
- bytessent = http->writebytecount;
+ bytessent = data->req.writebytecount;
if(conn->bits.authneg) {
/* This is a state where we are known to be negotiating and we don't send
@@ -479,8 +481,36 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
(curl_off_t)(expectsend - bytessent));
}
#endif
+#if defined(USE_SPNEGO)
+ /* There is still data left to send */
+ if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
+ (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
+ if(((expectsend - bytessent) < 2000) ||
+ (conn->negotiate.state != GSS_AUTHNONE) ||
+ (conn->proxyneg.state != GSS_AUTHNONE)) {
+ /* The NEGOTIATE-negotiation has started *OR*
+ there is just a little (<2K) data left to send, keep on sending. */
+
+ /* rewind data when completely done sending! */
+ if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
+ conn->bits.rewindaftersend = TRUE;
+ infof(data, "Rewind stream after send\n");
+ }
+
+ return CURLE_OK;
+ }
+
+ if(conn->bits.close)
+ /* this is already marked to get closed */
+ return CURLE_OK;
- /* This is not NTLM or many bytes left to send: close */
+ infof(data, "NEGOTIATE send, close instead of sending %"
+ CURL_FORMAT_CURL_OFF_T " bytes\n",
+ (curl_off_t)(expectsend - bytessent));
+ }
+#endif
+
+ /* This is not NEGOTIATE/NTLM or many bytes left to send: close */
streamclose(conn, "Mid-auth HTTP and much data left to send");
data->req.size = 0; /* don't download any more than 0 bytes */
@@ -598,10 +628,6 @@ output_auth_headers(struct connectdata *conn,
#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
struct Curl_easy *data = conn->data;
#endif
-#ifdef USE_SPNEGO
- struct negotiatedata *negdata = proxy ?
- &data->state.proxyneg : &data->state.negotiate;
-#endif
#ifdef CURL_DISABLE_CRYPTO_AUTH
(void)request;
@@ -609,15 +635,11 @@ output_auth_headers(struct connectdata *conn,
#endif
#ifdef USE_SPNEGO
- negdata->state = GSS_AUTHNONE;
- if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
- negdata->context && !GSS_ERROR(negdata->status)) {
+ if((authstatus->picked == CURLAUTH_NEGOTIATE)) {
auth = "Negotiate";
result = Curl_output_negotiate(conn, proxy);
if(result)
return result;
- authstatus->done = TRUE;
- negdata->state = GSS_AUTHSENT;
}
else
#endif
@@ -750,7 +772,7 @@ Curl_http_output_auth(struct connectdata *conn,
#ifndef CURL_DISABLE_PROXY
/* Send proxy authentication header if needed */
if(conn->bits.httpproxy &&
- (conn->bits.tunnel_proxy == proxytunnel)) {
+ (conn->bits.tunnel_proxy == (bit)proxytunnel)) {
result = output_auth_headers(conn, authproxy, request, path, TRUE);
if(result)
return result;
@@ -794,7 +816,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
#ifdef USE_SPNEGO
struct negotiatedata *negdata = proxy?
- &data->state.proxyneg:&data->state.negotiate;
+ &conn->proxyneg:&conn->negotiate;
#endif
unsigned long *availp;
struct auth *authp;
@@ -833,21 +855,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
authp->avail |= CURLAUTH_NEGOTIATE;
if(authp->picked == CURLAUTH_NEGOTIATE) {
- if(negdata->state == GSS_AUTHSENT ||
- negdata->state == GSS_AUTHNONE) {
- CURLcode result = Curl_input_negotiate(conn, proxy, auth);
- if(!result) {
- DEBUGASSERT(!data->req.newurl);
- data->req.newurl = strdup(data->change.url);
- if(!data->req.newurl)
- return CURLE_OUT_OF_MEMORY;
- data->state.authproblem = FALSE;
- /* we received a GSS auth token and we dealt with it fine */
- negdata->state = GSS_AUTHRECV;
- }
- else
- data->state.authproblem = TRUE;
+ CURLcode result = Curl_input_negotiate(conn, proxy, auth);
+ if(!result) {
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(data->change.url);
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+ data->state.authproblem = FALSE;
+ /* we received a GSS auth token and we dealt with it fine */
+ negdata->state = GSS_AUTHRECV;
}
+ else
+ data->state.authproblem = TRUE;
}
}
}
@@ -1117,14 +1136,13 @@ void Curl_add_buffer_free(Curl_send_buffer **inp)
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
struct connectdata *conn,
- /* add the number of sent bytes to this
- counter */
- long *bytes_written,
+ /* add the number of sent bytes to this
+ counter */
+ curl_off_t *bytes_written,
- /* how much of the buffer contains body data */
+ /* how much of the buffer contains body data */
size_t included_body_bytes,
int socketindex)
-
{
ssize_t amount;
CURLcode result;
@@ -1220,7 +1238,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
if(http) {
/* if we sent a piece of the body here, up the byte counter for it
accordingly */
- http->writebytecount += bodylen;
+ data->req.writebytecount += bodylen;
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
if((size_t)amount != size) {
/* The whole request could not be sent in one system call. We must
@@ -1553,20 +1572,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
Curl_unencode_cleanup(conn);
-#ifdef USE_SPNEGO
- if(data->state.proxyneg.state == GSS_AUTHSENT ||
- data->state.negotiate.state == GSS_AUTHSENT) {
- /* add forbid re-use if http-code != 401/407 as a WA only needed for
- * 401/407 that signal auth failure (empty) otherwise state will be RECV
- * with current code.
- * Do not close CONNECT_ONLY connections. */
- if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- !data->set.connect_only)
- streamclose(conn, "Negotiate transfer completed");
- Curl_cleanup_negotiate(data);
- }
-#endif
-
/* set the proper values (possibly modified on POST) */
conn->seek_func = data->set.seek_func; /* restore */
conn->seek_client = data->set.seek_client; /* restore */
@@ -1582,16 +1587,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
Curl_mime_cleanpart(&http->form);
- switch(data->set.httpreq) {
- case HTTPREQ_PUT:
- case HTTPREQ_POST_FORM:
- case HTTPREQ_POST_MIME:
- data->req.bytecount = http->readbytecount + http->writebytecount;
- break;
- default:
- break;
- }
-
if(status)
return status;
@@ -1599,7 +1594,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
entire operation is complete */
!conn->bits.retry &&
!data->set.connect_only &&
- (http->readbytecount +
+ (data->req.bytecount +
data->req.headerbytecount -
data->req.deductheadercount) <= 0) {
/* If this connection isn't simply closed to be retried, AND nothing was
@@ -1789,9 +1784,16 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
}
else {
if(*(--ptr) == ';') {
- /* send no-value custom header if terminated by semicolon */
- *ptr = ':';
- semicolonp = ptr;
+ /* copy the source */
+ semicolonp = strdup(headers->data);
+ if(!semicolonp) {
+ Curl_add_buffer_free(&req_buffer);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ /* put a colon where the semicolon is */
+ semicolonp[ptr - headers->data] = ':';
+ /* point at the colon */
+ optr = &semicolonp [ptr - headers->data];
}
}
ptr = optr;
@@ -1807,36 +1809,37 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
if(*ptr || semicolonp) {
/* only send this if the contents was non-blank or done special */
CURLcode result = CURLE_OK;
+ char *compare = semicolonp ? semicolonp : headers->data;
if(conn->allocptr.host &&
/* a Host: header was sent already, don't pass on any custom Host:
header as that will produce *two* in the same request! */
- checkprefix("Host:", headers->data))
+ checkprefix("Host:", compare))
;
else if(data->set.httpreq == HTTPREQ_POST_FORM &&
/* this header (extended by formdata.c) is sent later */
- checkprefix("Content-Type:", headers->data))
+ checkprefix("Content-Type:", compare))
;
else if(data->set.httpreq == HTTPREQ_POST_MIME &&
/* this header is sent later */
- checkprefix("Content-Type:", headers->data))
+ checkprefix("Content-Type:", compare))
;
else if(conn->bits.authneg &&
/* while doing auth neg, don't allow the custom length since
we will force length zero then */
- checkprefix("Content-Length:", headers->data))
+ checkprefix("Content-Length:", compare))
;
else if(conn->allocptr.te &&
/* when asking for Transfer-Encoding, don't pass on a custom
Connection: */
- checkprefix("Connection:", headers->data))
+ checkprefix("Connection:", compare))
;
else if((conn->httpversion == 20) &&
- checkprefix("Transfer-Encoding:", headers->data))
+ checkprefix("Transfer-Encoding:", compare))
/* HTTP/2 doesn't support chunked requests */
;
- else if((checkprefix("Authorization:", headers->data) ||
- checkprefix("Cookie:", headers->data)) &&
+ else if((checkprefix("Authorization:", compare) ||
+ checkprefix("Cookie:", compare)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
(data->state.this_is_a_follow &&
@@ -1845,10 +1848,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
!strcasecompare(data->state.first_host, conn->host.name)))
;
else {
- result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data);
+ result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare);
}
if(semicolonp)
- *semicolonp = ';'; /* put back the semicolon */
+ free(semicolonp);
if(result)
return result;
}
@@ -2000,7 +2003,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->state.first_remote_port = conn->remote_port;
}
- http->writebytecount = http->readbytecount = 0;
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
data->set.upload) {
@@ -2061,7 +2063,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
- if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
+ if(((data->state.authhost.multipass && !data->state.authhost.done)
+ || (data->state.authproxy.multipass && !data->state.authproxy.done)) &&
(httpreq != HTTPREQ_GET) &&
(httpreq != HTTPREQ_HEAD)) {
/* Auth is required and we are not authenticated yet. Make a PUT or POST
@@ -2697,9 +2700,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending PUT request");
else
/* prepare for transfer */
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount, postsize?FIRSTSOCKET:-1,
- postsize?&http->writebytecount:NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
+ postsize?FIRSTSOCKET:-1);
if(result)
return result;
break;
@@ -2719,12 +2721,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending POST request");
else
/* setup variables for the upcoming transfer */
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
- -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
break;
}
- postsize = http->postsize;
+ data->state.infilesize = postsize = http->postsize;
/* We only set Content-Length and allow a custom Content-Length if
we don't upload data chunked, as RFC2616 forbids us to set both
@@ -2788,9 +2789,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending POST request");
else
/* prepare for transfer */
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount, postsize?FIRSTSOCKET:-1,
- postsize?&http->writebytecount:NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
+ postsize?FIRSTSOCKET:-1);
if(result)
return result;
@@ -2944,9 +2944,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result)
failf(data, "Failed sending HTTP POST request");
else
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
- http->postdata?&http->writebytecount:NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
+ http->postdata?FIRSTSOCKET:-1);
break;
default:
@@ -2962,33 +2961,30 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending HTTP request");
else
/* HTTP GET/HEAD download: */
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
- http->postdata?FIRSTSOCKET:-1,
- http->postdata?&http->writebytecount:NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
+ http->postdata?FIRSTSOCKET:-1);
}
if(result)
return result;
- if(http->writebytecount) {
+ if(data->req.writebytecount) {
/* if a request-body has been sent off, we make sure this progress is noted
properly */
- Curl_pgrsSetUploadCounter(data, http->writebytecount);
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
if(Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
- if(http->writebytecount >= postsize) {
+ if(data->req.writebytecount >= postsize) {
/* already sent the entire request body, mark the "upload" as
complete */
infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
" out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
- http->writebytecount, postsize);
+ data->req.writebytecount, postsize);
data->req.upload_done = TRUE;
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
}
- else
- data->req.writebytecount = http->writebytecount;
}
if((conn->httpversion == 20) && data->req.upload_chunky)
@@ -3383,7 +3379,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
data->state.authproblem = TRUE;
}
#endif
-
+#if defined(USE_SPNEGO)
+ if(conn->bits.close &&
+ (((data->req.httpcode == 401) &&
+ (conn->negotiate.state == GSS_AUTHRECV)) ||
+ ((data->req.httpcode == 407) &&
+ (conn->proxyneg.state == GSS_AUTHRECV)))) {
+ infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
+ data->state.authproblem = TRUE;
+ }
+ if((conn->negotiate.state == GSS_AUTHDONE) &&
+ (data->req.httpcode != 401)) {
+ conn->negotiate.state = GSS_AUTHSUCC;
+ }
+ if((conn->proxyneg.state == GSS_AUTHDONE) &&
+ (data->req.httpcode != 407)) {
+ conn->proxyneg.state = GSS_AUTHSUCC;
+ }
+#endif
/*
* When all the headers have been parsed, see if we should give
* up and return an error.
@@ -3960,6 +3973,22 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(result)
return result;
}
+ #ifdef USE_SPNEGO
+ else if(checkprefix("Persistent-Auth", k->p)) {
+ struct negotiatedata *negdata = &conn->negotiate;
+ struct auth *authp = &data->state.authhost;
+ if(authp->picked == CURLAUTH_NEGOTIATE) {
+ char *persistentauth = Curl_copy_header_value(k->p);
+ if(!persistentauth)
+ return CURLE_OUT_OF_MEMORY;
+ negdata->noauthpersist = checkprefix("false", persistentauth);
+ negdata->havenoauthpersist = TRUE;
+ infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
+ negdata->noauthpersist, persistentauth);
+ free(persistentauth);
+ }
+ }
+ #endif
else if((k->httpcode >= 300 && k->httpcode < 400) &&
checkprefix("Location:", k->p) &&
!data->req.location) {
@@ -3987,6 +4016,27 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
}
+#ifdef USE_ALTSVC
+ /* If enabled, the header is incoming and this is over HTTPS */
+ else if(data->asi && checkprefix("Alt-Svc:", k->p) &&
+ ((conn->handler->flags & PROTOPT_SSL) ||
+#ifdef CURLDEBUG
+ /* allow debug builds to circumvent the HTTPS restriction */
+ getenv("CURL_ALTSVC_HTTP")
+#else
+ 0
+#endif
+ )) {
+ /* the ALPN of the current request */
+ enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
+ result = Curl_altsvc_parse(data, data->asi,
+ &k->p[ strlen("Alt-Svc:") ],
+ id, conn->host.name,
+ curlx_uitous(conn->remote_port));
+ if(result)
+ return result;
+ }
+#endif
else if(conn->handler->protocol & CURLPROTO_RTSP) {
result = Curl_rtsp_parseheader(conn, k->p);
if(result)
diff --git a/lib/http.h b/lib/http.h
index c265cb71c..15fe22d37 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -65,7 +65,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
size_t size) WARN_UNUSED_RESULT;
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
struct connectdata *conn,
- long *bytes_written,
+ curl_off_t *bytes_written,
size_t included_body_bytes,
int socketindex);
@@ -139,8 +139,6 @@ struct HTTP {
const char *p_pragma; /* Pragma: string */
const char *p_accept; /* Accept: string */
- curl_off_t readbytecount;
- curl_off_t writebytecount;
/* For FORM posting */
curl_mimepart form;
diff --git a/lib/http2.c b/lib/http2.c
index d8030b6fe..ef74704ac 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -357,7 +357,7 @@ int Curl_http2_ver(char *p, size_t len)
https://tools.ietf.org/html/rfc7540#page-77
nghttp2_error_code enums are identical.
*/
-const char *Curl_http2_strerror(uint32_t err)
+static const char *http2_strerror(uint32_t err)
{
#ifndef NGHTTP2_HAS_HTTP2_STRERROR
const char *str[] = {
@@ -618,6 +618,18 @@ static int push_promise(struct Curl_easy *data,
return rv;
}
+/*
+ * multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (pipelining become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+static void multi_connchanged(struct Curl_multi *multi)
+{
+ multi->recheckstate = TRUE;
+}
+
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
void *userp)
{
@@ -650,7 +662,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
infof(conn->data,
"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
httpc->settings.max_concurrent_streams);
- Curl_multi_connchanged(conn->data->multi);
+ multi_connchanged(conn->data->multi);
}
}
return 0;
@@ -837,7 +849,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return 0;
}
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
- Curl_http2_strerror(error_code), error_code, stream_id));
+ http2_strerror(error_code), error_code, stream_id));
stream = data_s->req.protop;
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -957,6 +969,28 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
char *h;
+ if(!strcmp(":authority", (const char *)name)) {
+ /* psuedo headers are lower case */
+ int rc = 0;
+ char *check = aprintf("%s:%d", conn->host.name, conn->remote_port);
+ if(!check)
+ /* no memory */
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ if(!Curl_strcasecompare(check, (const char *)value)) {
+ /* This is push is not for the same authority that was asked for in
+ * the URL. RFC 7540 section 8.2 says: "A client MUST treat a
+ * PUSH_PROMISE for which the server is not authoritative as a stream
+ * error of type PROTOCOL_ERROR."
+ */
+ (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+ stream_id, NGHTTP2_PROTOCOL_ERROR);
+ rc = NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+ free(check);
+ if(rc)
+ return rc;
+ }
+
if(!stream->push_headers) {
stream->push_headers_alloc = 10;
stream->push_headers = malloc(stream->push_headers_alloc *
@@ -1197,7 +1231,7 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
/*
* Initialize nghttp2 for a Curl connection
*/
-CURLcode Curl_http2_init(struct connectdata *conn)
+static CURLcode http2_init(struct connectdata *conn)
{
if(!conn->proto.httpc.h2) {
int rc;
@@ -1431,7 +1465,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
}
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
- stream->stream_id, Curl_http2_strerror(httpc->error_code),
+ stream->stream_id, http2_strerror(httpc->error_code),
httpc->error_code);
*err = CURLE_HTTP2_STREAM;
return -1;
@@ -2141,7 +2175,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
else
conn->handler = &Curl_handler_http2;
- result = Curl_http2_init(conn);
+ result = http2_init(conn);
if(result) {
Curl_add_buffer_free(&stream->header_recvbuf);
return result;
@@ -2163,7 +2197,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
- Curl_multi_connchanged(conn->data->multi);
+ multi_connchanged(conn->data->multi);
return CURLE_OK;
}
diff --git a/lib/http2.h b/lib/http2.h
index 67db3dffb..db6217b11 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -63,7 +63,6 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
bool Curl_h2_http_1_1_error(struct connectdata *conn);
#else /* USE_NGHTTP2 */
-#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 2a97707eb..9415236fb 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -56,7 +56,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.host.name;
- neg_ctx = &data->state.proxyneg;
+ neg_ctx = &conn->proxyneg;
}
else {
userp = conn->user;
@@ -64,7 +64,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->host.name;
- neg_ctx = &data->state.negotiate;
+ neg_ctx = &conn->negotiate;
}
/* Not set means empty */
@@ -80,11 +80,16 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
header++;
len = strlen(header);
+ neg_ctx->havenegdata = len != 0;
if(!len) {
- /* Is this the first call in a new negotiation? */
- if(neg_ctx->context) {
- /* The server rejected our authentication and hasn't suppled any more
+ if(neg_ctx->state == GSS_AUTHSUCC) {
+ infof(conn->data, "Negotiate auth restarted\n");
+ Curl_cleanup_negotiate(conn);
+ }
+ else if(neg_ctx->state != GSS_AUTHNONE) {
+ /* The server rejected our authentication and hasn't supplied any more
negotiation mechanisms */
+ Curl_cleanup_negotiate(conn);
return CURLE_LOGIN_DENIED;
}
}
@@ -106,38 +111,96 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
{
- struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
- &conn->data->state.negotiate;
+ struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg :
+ &conn->negotiate;
+ struct auth *authp = proxy ? &conn->data->state.authproxy :
+ &conn->data->state.authhost;
char *base64 = NULL;
size_t len = 0;
char *userp;
CURLcode result;
- result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
- if(result)
- return result;
+ authp->done = FALSE;
+
+ if(neg_ctx->state == GSS_AUTHRECV) {
+ if(neg_ctx->havenegdata) {
+ neg_ctx->havemultiplerequests = TRUE;
+ }
+ }
+ else if(neg_ctx->state == GSS_AUTHSUCC) {
+ if(!neg_ctx->havenoauthpersist) {
+ neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests;
+ }
+ }
- userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
- base64);
+ if(neg_ctx->noauthpersist ||
+ (neg_ctx->state != GSS_AUTHDONE && neg_ctx->state != GSS_AUTHSUCC)) {
- if(proxy) {
- Curl_safefree(conn->allocptr.proxyuserpwd);
- conn->allocptr.proxyuserpwd = userp;
+ if(neg_ctx->noauthpersist && neg_ctx->state == GSS_AUTHSUCC) {
+ infof(conn->data, "Curl_output_negotiate, "
+ "no persistent authentication: cleanup existing context");
+ Curl_auth_spnego_cleanup(neg_ctx);
+ }
+ if(!neg_ctx->context) {
+ result = Curl_input_negotiate(conn, proxy, "Negotiate");
+ if(result)
+ return result;
+ }
+
+ result = Curl_auth_create_spnego_message(conn->data,
+ neg_ctx, &base64, &len);
+ if(result)
+ return result;
+
+ userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+ base64);
+
+ if(proxy) {
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ conn->allocptr.proxyuserpwd = userp;
+ }
+ else {
+ Curl_safefree(conn->allocptr.userpwd);
+ conn->allocptr.userpwd = userp;
+ }
+
+ free(base64);
+
+ if(userp == NULL) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ neg_ctx->state = GSS_AUTHSENT;
+ #ifdef HAVE_GSSAPI
+ if(neg_ctx->status == GSS_S_COMPLETE ||
+ neg_ctx->status == GSS_S_CONTINUE_NEEDED) {
+ neg_ctx->state = GSS_AUTHDONE;
+ }
+ #else
+ #ifdef USE_WINDOWS_SSPI
+ if(neg_ctx->status == SEC_E_OK ||
+ neg_ctx->status == SEC_I_CONTINUE_NEEDED) {
+ neg_ctx->state = GSS_AUTHDONE;
+ }
+ #endif
+ #endif
}
- else {
- Curl_safefree(conn->allocptr.userpwd);
- conn->allocptr.userpwd = userp;
+
+ if(neg_ctx->state == GSS_AUTHDONE || neg_ctx->state == GSS_AUTHSUCC) {
+ /* connection is already authenticated,
+ * don't send a header in future requests */
+ authp->done = TRUE;
}
- free(base64);
+ neg_ctx->havenegdata = FALSE;
- return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+ return CURLE_OK;
}
-void Curl_cleanup_negotiate(struct Curl_easy *data)
+void Curl_cleanup_negotiate(struct connectdata *conn)
{
- Curl_auth_spnego_cleanup(&data->state.negotiate);
- Curl_auth_spnego_cleanup(&data->state.proxyneg);
+ Curl_auth_spnego_cleanup(&conn->negotiate);
+ Curl_auth_spnego_cleanup(&conn->proxyneg);
}
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
index c64e54825..d4a7f09e0 100644
--- a/lib/http_negotiate.h
+++ b/lib/http_negotiate.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -31,7 +31,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
/* this is for creating Negotiate header output */
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
-void Curl_cleanup_negotiate(struct Curl_easy *data);
+void Curl_cleanup_negotiate(struct connectdata *conn);
#endif /* USE_SPNEGO */
diff --git a/lib/imap.c b/lib/imap.c
index dab893cf7..df069647f 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1177,11 +1177,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
if(data->req.bytecount == size)
/* The entire data is already transferred! */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
else {
/* IMAP download */
data->req.maxdownload = size;
- Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1);
}
}
else {
@@ -1231,7 +1231,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
Curl_pgrsSetUploadSize(data, data->state.infilesize);
/* IMAP upload */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
state(conn, IMAP_STOP);
@@ -1660,7 +1660,7 @@ static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
if(imap->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
return CURLE_OK;
}
diff --git a/lib/ldap.c b/lib/ldap.c
index f45bb008b..734a4ae24 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -744,7 +744,7 @@ quit:
#endif
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
connclose(conn, "LDAP connection always disable re-use");
return result;
diff --git a/lib/md5.c b/lib/md5.c
index 079da3ead..f88688b34 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -83,7 +83,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
gcry_md_close(*ctx);
}
-#elif defined(USE_OPENSSL)
+#elif defined(USE_OPENSSL) && !defined(USE_AMISSL)
/* When OpenSSL is available we use the MD5-function from OpenSSL */
#include <openssl/md5.h>
#include "curl_memory.h"
diff --git a/lib/memdebug.c b/lib/memdebug.c
index d53d618d3..639a9bb45 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -100,19 +100,18 @@ struct memdebug {
* Don't use these with multithreaded test programs!
*/
-#define logfile curl_debuglogfile
-FILE *curl_debuglogfile = NULL;
+FILE *curl_dbg_logfile = NULL;
static bool memlimit = FALSE; /* enable memory limit */
static long memsize = 0; /* set number of mallocs allowed */
/* this sets the log file name */
-void curl_memdebug(const char *logname)
+void curl_dbg_memdebug(const char *logname)
{
- if(!logfile) {
+ if(!curl_dbg_logfile) {
if(logname && *logname)
- logfile = fopen(logname, FOPEN_WRITETEXT);
+ curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT);
else
- logfile = stderr;
+ curl_dbg_logfile = stderr;
#ifdef MEMDEBUG_LOG_SYNC
/* Flush the log file after every line so the log isn't lost in a crash */
if(logfile)
@@ -123,7 +122,7 @@ void curl_memdebug(const char *logname)
/* This function sets the number of malloc() calls that should return
successfully! */
-void curl_memlimit(long limit)
+void curl_dbg_memlimit(long limit)
{
if(!memlimit) {
memlimit = TRUE;
@@ -140,12 +139,12 @@ static bool countcheck(const char *func, int line, const char *source)
if(!memsize) {
if(source) {
/* log to file */
- curl_memlog("LIMIT %s:%d %s reached memlimit\n",
- source, line, func);
+ curl_dbg_log("LIMIT %s:%d %s reached memlimit\n",
+ source, line, func);
/* log to stderr also */
fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
source, line, func);
- fflush(logfile); /* because it might crash now */
+ fflush(curl_dbg_logfile); /* because it might crash now */
}
errno = ENOMEM;
return TRUE; /* RETURN ERROR! */
@@ -159,7 +158,7 @@ static bool countcheck(const char *func, int line, const char *source)
return FALSE; /* allow this */
}
-void *curl_domalloc(size_t wantedsize, int line, const char *source)
+void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
{
struct memdebug *mem;
size_t size;
@@ -180,15 +179,15 @@ void *curl_domalloc(size_t wantedsize, int line, const char *source)
}
if(source)
- curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
- source, line, wantedsize,
- mem ? (void *)mem->mem : (void *)0);
+ curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n",
+ source, line, wantedsize,
+ mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
-void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
- int line, const char *source)
+void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size,
+ int line, const char *source)
{
struct memdebug *mem;
size_t size, user_size;
@@ -208,14 +207,14 @@ void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
mem->size = user_size;
if(source)
- curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
- source, line, wanted_elements, wanted_size,
- mem ? (void *)mem->mem : (void *)0);
+ curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n",
+ source, line, wanted_elements, wanted_size,
+ mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
-char *curl_dostrdup(const char *str, int line, const char *source)
+char *curl_dbg_strdup(const char *str, int line, const char *source)
{
char *mem;
size_t len;
@@ -227,19 +226,19 @@ char *curl_dostrdup(const char *str, int line, const char *source)
len = strlen(str) + 1;
- mem = curl_domalloc(len, 0, NULL); /* NULL prevents logging */
+ mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */
if(mem)
memcpy(mem, str, len);
if(source)
- curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
- source, line, (const void *)str, len, (const void *)mem);
+ curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n",
+ source, line, (const void *)str, len, (const void *)mem);
return mem;
}
#if defined(WIN32) && defined(UNICODE)
-wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
+wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source)
{
wchar_t *mem;
size_t wsiz, bsiz;
@@ -252,12 +251,12 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
wsiz = wcslen(str) + 1;
bsiz = wsiz * sizeof(wchar_t);
- mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
+ mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */
if(mem)
memcpy(mem, str, bsiz);
if(source)
- curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
+ curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
source, line, (void *)str, bsiz, (void *)mem);
return mem;
@@ -266,8 +265,8 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
/* We provide a realloc() that accepts a NULL as pointer, which then
performs a malloc(). In order to work with ares. */
-void *curl_dorealloc(void *ptr, size_t wantedsize,
- int line, const char *source)
+void *curl_dbg_realloc(void *ptr, size_t wantedsize,
+ int line, const char *source)
{
struct memdebug *mem = NULL;
@@ -293,7 +292,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
mem = (Curl_crealloc)(mem, size);
if(source)
- curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
+ curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n",
source, line, (void *)ptr, wantedsize,
mem ? (void *)mem->mem : (void *)0);
@@ -305,7 +304,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
return NULL;
}
-void curl_dofree(void *ptr, int line, const char *source)
+void curl_dbg_free(void *ptr, int line, const char *source)
{
struct memdebug *mem;
@@ -331,11 +330,11 @@ void curl_dofree(void *ptr, int line, const char *source)
}
if(source)
- curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
+ curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
}
-curl_socket_t curl_socket(int domain, int type, int protocol,
- int line, const char *source)
+curl_socket_t curl_dbg_socket(int domain, int type, int protocol,
+ int line, const char *source)
{
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
"FD %s:%d socket() = %d\n" :
@@ -351,44 +350,44 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
sockfd = socket(domain, type, protocol);
if(source && (sockfd != CURL_SOCKET_BAD))
- curl_memlog(fmt, source, line, sockfd);
+ curl_dbg_log(fmt, source, line, sockfd);
return sockfd;
}
-SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
- SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
- SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line,
- const char *source)
+SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd,
+ SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
+ SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line,
+ const char *source)
{
SEND_TYPE_RETV rc;
if(countcheck("send", line, source))
return -1;
rc = send(sockfd, buf, len, flags);
if(source)
- curl_memlog("SEND %s:%d send(%lu) = %ld\n",
+ curl_dbg_log("SEND %s:%d send(%lu) = %ld\n",
source, line, (unsigned long)len, (long)rc);
return rc;
}
-RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
- RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line,
- const char *source)
+RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
+ RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line,
+ const char *source)
{
RECV_TYPE_RETV rc;
if(countcheck("recv", line, source))
return -1;
rc = recv(sockfd, buf, len, flags);
if(source)
- curl_memlog("RECV %s:%d recv(%lu) = %ld\n",
+ curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n",
source, line, (unsigned long)len, (long)rc);
return rc;
}
#ifdef HAVE_SOCKETPAIR
-int curl_socketpair(int domain, int type, int protocol,
- curl_socket_t socket_vector[2],
- int line, const char *source)
+int curl_dbg_socketpair(int domain, int type, int protocol,
+ curl_socket_t socket_vector[2],
+ int line, const char *source)
{
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
"FD %s:%d socketpair() = %d %d\n" :
@@ -399,14 +398,14 @@ int curl_socketpair(int domain, int type, int protocol,
int res = socketpair(domain, type, protocol, socket_vector);
if(source && (0 == res))
- curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
+ curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]);
return res;
}
#endif
-curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
- int line, const char *source)
+curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen,
+ int line, const char *source)
{
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
"FD %s:%d accept() = %d\n" :
@@ -420,13 +419,13 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
curl_socket_t sockfd = accept(s, addr, addrlen);
if(source && (sockfd != CURL_SOCKET_BAD))
- curl_memlog(fmt, source, line, sockfd);
+ curl_dbg_log(fmt, source, line, sockfd);
return sockfd;
}
/* separate function to allow libcurl to mark a "faked" close */
-void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
+void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source)
{
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
"FD %s:%d sclose(%d)\n":
@@ -435,54 +434,40 @@ void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
"FD %s:%d sclose(%zd)\n";
if(source)
- curl_memlog(fmt, source, line, sockfd);
+ curl_dbg_log(fmt, source, line, sockfd);
}
/* this is our own defined way to close sockets on *ALL* platforms */
-int curl_sclose(curl_socket_t sockfd, int line, const char *source)
+int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source)
{
int res = sclose(sockfd);
- curl_mark_sclose(sockfd, line, source);
+ curl_dbg_mark_sclose(sockfd, line, source);
return res;
}
-FILE *curl_fopen(const char *file, const char *mode,
- int line, const char *source)
+FILE *curl_dbg_fopen(const char *file, const char *mode,
+ int line, const char *source)
{
FILE *res = fopen(file, mode);
if(source)
- curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
+ curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
source, line, file, mode, (void *)res);
return res;
}
-#ifdef HAVE_FDOPEN
-FILE *curl_fdopen(int filedes, const char *mode,
- int line, const char *source)
-{
- FILE *res = fdopen(filedes, mode);
-
- if(source)
- curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
- source, line, filedes, mode, (void *)res);
-
- return res;
-}
-#endif
-
-int curl_fclose(FILE *file, int line, const char *source)
+int curl_dbg_fclose(FILE *file, int line, const char *source)
{
int res;
DEBUGASSERT(file != NULL);
- res = fclose(file);
-
if(source)
- curl_memlog("FILE %s:%d fclose(%p)\n",
- source, line, (void *)file);
+ curl_dbg_log("FILE %s:%d fclose(%p)\n",
+ source, line, (void *)file);
+
+ res = fclose(file);
return res;
}
@@ -490,13 +475,13 @@ int curl_fclose(FILE *file, int line, const char *source)
#define LOGLINE_BUFSIZE 1024
/* this does the writing to the memory tracking log file */
-void curl_memlog(const char *format, ...)
+void curl_dbg_log(const char *format, ...)
{
char *buf;
int nchars;
va_list ap;
- if(!logfile)
+ if(!curl_dbg_logfile)
return;
buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
@@ -511,7 +496,7 @@ void curl_memlog(const char *format, ...)
nchars = LOGLINE_BUFSIZE - 1;
if(nchars > 0)
- fwrite(buf, 1, (size_t)nchars, logfile);
+ fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile);
(Curl_cfree)(buf);
}
diff --git a/lib/memdebug.h b/lib/memdebug.h
index 233de65a4..5236f60fa 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -30,97 +30,92 @@
#define CURL_MT_LOGFNAME_BUFSIZE 512
-#define logfile curl_debuglogfile
-
-extern FILE *logfile;
+extern FILE *curl_dbg_logfile;
/* memory functions */
-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_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 char *curl_dostrdup(const char *str, int line, const char *source);
-#if defined(WIN32) && defined(UNICODE)
-CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
+CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source);
+CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line,
+ const char *source);
+CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line,
const char *source);
+CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source);
+CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src);
+#if defined(WIN32) && defined(UNICODE)
+CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line,
+ const char *source);
#endif
-CURL_EXTERN void curl_memdebug(const char *logname);
-CURL_EXTERN void curl_memlimit(long limit);
-CURL_EXTERN void curl_memlog(const char *format, ...);
+CURL_EXTERN void curl_dbg_memdebug(const char *logname);
+CURL_EXTERN void curl_dbg_memlimit(long limit);
+CURL_EXTERN void curl_dbg_log(const char *format, ...);
/* file descriptor manipulators */
-CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
- int line, const char *source);
-CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
- int line, const char *source);
-CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
- int line, const char *source);
-CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
+CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol,
+ int line, const char *source);
+CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd,
int line, const char *source);
-#ifdef HAVE_SOCKETPAIR
-CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
- curl_socket_t socket_vector[2],
+CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd,
int line, const char *source);
+CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen,
+ int line, const char *source);
+#ifdef HAVE_SOCKETPAIR
+CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol,
+ curl_socket_t socket_vector[2],
+ int line, const char *source);
#endif
/* send/receive sockets */
-CURL_EXTERN SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
- SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
- SEND_TYPE_ARG3 len,
- SEND_TYPE_ARG4 flags, int line,
- const char *source);
-CURL_EXTERN RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd,
- RECV_TYPE_ARG2 buf, RECV_TYPE_ARG3 len,
- RECV_TYPE_ARG4 flags, int line,
- const char *source);
+CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd,
+ SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
+ SEND_TYPE_ARG3 len,
+ SEND_TYPE_ARG4 flags, int line,
+ const char *source);
+CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
+ RECV_TYPE_ARG2 buf,
+ RECV_TYPE_ARG3 len,
+ RECV_TYPE_ARG4 flags, int line,
+ const char *source);
/* FILE functions */
-CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
- const char *source);
-#ifdef HAVE_FDOPEN
-CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
- const char *source);
-#endif
-CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
+CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line,
+ const char *source);
+CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
#ifndef MEMDEBUG_NODEFINES
/* Set this symbol on the command-line, recompile all lib-sources */
#undef strdup
-#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
-#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
-#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
-#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
-#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
-#define send(a,b,c,d) curl_dosend(a,b,c,d, __LINE__, __FILE__)
-#define recv(a,b,c,d) curl_dorecv(a,b,c,d, __LINE__, __FILE__)
+#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__)
+#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__)
+#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__)
+#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__)
+#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__)
+#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
+#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
#ifdef WIN32
# ifdef UNICODE
# undef wcsdup
-# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
# undef _wcsdup
-# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
# undef _tcsdup
-# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
# else
# undef _tcsdup
-# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__)
# endif
#endif
#undef socket
#define socket(domain,type,protocol)\
- curl_socket(domain, type, protocol, __LINE__, __FILE__)
+ curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__)
#undef accept /* for those with accept as a macro */
#define accept(sock,addr,len)\
- curl_accept(sock, addr, len, __LINE__, __FILE__)
+ curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
#ifdef HAVE_SOCKETPAIR
#define socketpair(domain,type,protocol,socket_vector)\
- curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
+ curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
#endif
#ifdef HAVE_GETADDRINFO
@@ -129,31 +124,31 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
our macro as for other platforms. Instead, we redefine the new name they
define getaddrinfo to become! */
#define ogetaddrinfo(host,serv,hint,res) \
- curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+ curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
#else
#undef getaddrinfo
#define getaddrinfo(host,serv,hint,res) \
- curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+ curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
#endif
#endif /* HAVE_GETADDRINFO */
#ifdef HAVE_FREEADDRINFO
#undef freeaddrinfo
#define freeaddrinfo(data) \
- curl_dofreeaddrinfo(data, __LINE__, __FILE__)
+ curl_dbg_freeaddrinfo(data, __LINE__, __FILE__)
#endif /* HAVE_FREEADDRINFO */
/* sclose is probably already defined, redefine it! */
#undef sclose
-#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
+#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__)
-#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
+#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__)
#undef fopen
-#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
+#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
#undef fdopen
-#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
-#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
+#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)
+#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__)
#endif /* MEMDEBUG_NODEFINES */
diff --git a/lib/mime.c b/lib/mime.c
index 0912e101e..4f6789398 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -1122,8 +1122,6 @@ void curl_mime_free(curl_mime *mime)
Curl_mime_cleanpart(part);
free(part);
}
-
- free(mime->boundary);
free(mime);
}
}
@@ -1220,18 +1218,10 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
mime->firstpart = NULL;
mime->lastpart = NULL;
- /* Get a part boundary. */
- mime->boundary = malloc(24 + MIME_RAND_BOUNDARY_CHARS + 1);
- if(!mime->boundary) {
- free(mime);
- return NULL;
- }
-
memset(mime->boundary, '-', 24);
- if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
+ if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24],
MIME_RAND_BOUNDARY_CHARS + 1)) {
/* failed to get random separator, bail out */
- free(mime->boundary);
free(mime);
return NULL;
}
diff --git a/lib/mime.h b/lib/mime.h
index 4d5c70404..0721c8ca4 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -88,13 +88,16 @@ typedef struct {
size_t offset; /* State-dependent offset. */
} mime_state;
+/* minimum buffer size for the boundary string */
+#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
+
/* A mime multipart. */
struct curl_mime_s {
struct Curl_easy *easy; /* The associated easy handle. */
curl_mimepart *parent; /* Parent part. */
curl_mimepart *firstpart; /* First part. */
curl_mimepart *lastpart; /* Last part. */
- char *boundary; /* The part boundary. */
+ char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
mime_state state; /* Current readback state. */
};
diff --git a/lib/multi.c b/lib/multi.c
index 5c09a04f5..a3422c2ad 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -80,6 +80,7 @@ static CURLMcode add_next_timeout(struct curltime now,
static CURLMcode multi_timeout(struct Curl_multi *multi,
long *timeout_ms);
static void process_pending_handles(struct Curl_multi *multi);
+static void detach_connnection(struct Curl_easy *data);
#ifdef DEBUGBUILD
static const char * const statename[]={
@@ -114,7 +115,7 @@ static void Curl_init_completed(struct Curl_easy *data)
/* Important: reset the conn pointer so that we don't point to memory
that could be freed anytime */
- Curl_detach_connnection(data);
+ detach_connnection(data);
Curl_expire_clear(data); /* stop all timers */
}
@@ -496,6 +497,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->set.server_response_timeout;
data->state.conn_cache->closure_handle->set.no_signal =
data->set.no_signal;
+ data->state.conn_cache->closure_handle->set.verbose =
+ data->set.verbose;
update_timer(multi);
return CURLM_OK;
@@ -572,7 +575,7 @@ static CURLcode multi_done(struct Curl_easy *data,
if(conn->send_pipe.size || conn->recv_pipe.size) {
/* Stop if pipeline is not empty . */
- Curl_detach_connnection(data);
+ detach_connnection(data);
DEBUGF(infof(data, "Connection still in use %zu/%zu, "
"no more multi_done now!\n",
conn->send_pipe.size, conn->recv_pipe.size));
@@ -597,7 +600,7 @@ static CURLcode multi_done(struct Curl_easy *data,
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this connection. This is ignored for requests taking
- place in a NTLM authentication handshake
+ place in a NTLM/NEGOTIATE authentication handshake
if conn->bits.close is TRUE, it means that the connection should be
closed in spite of all our efforts to be nice, due to protocol
@@ -615,6 +618,10 @@ static CURLcode multi_done(struct Curl_easy *data,
&& !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
conn->proxyntlm.state == NTLMSTATE_TYPE2)
#endif
+#if defined(USE_SPNEGO)
+ && !(conn->negotiate.state == GSS_AUTHRECV ||
+ conn->proxyneg.state == GSS_AUTHRECV)
+#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
CURLcode res2 = Curl_disconnect(data, conn, premature);
@@ -645,7 +652,7 @@ static CURLcode multi_done(struct Curl_easy *data,
data->state.lastconnect = NULL;
}
- Curl_detach_connnection(data);
+ detach_connnection(data);
Curl_free_request_state(data);
return result;
}
@@ -752,7 +759,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
/* Remove the association between the connection and the handle */
if(data->conn) {
data->conn->data = NULL;
- Curl_detach_connnection(data);
+ detach_connnection(data);
}
#ifdef USE_LIBPSL
@@ -804,7 +811,7 @@ bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
/* This is the only function that should clear data->conn. This will
occasionally be called with the pointer already cleared. */
-void Curl_detach_connnection(struct Curl_easy *data)
+static void detach_connnection(struct Curl_easy *data)
{
data->conn = NULL;
}
@@ -998,11 +1005,11 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
unsigned int i;
unsigned int nfds = 0;
unsigned int curlfds;
- struct pollfd *ufds = NULL;
bool ufds_malloc = FALSE;
long timeout_internal;
int retcode = 0;
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
+ struct pollfd *ufds = &a_few_on_stack[0];
if(gotsocket)
*gotsocket = FALSE;
@@ -1047,19 +1054,15 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
curlfds = nfds; /* number of internal file descriptors */
nfds += extra_nfds; /* add the externally provided ones */
- if(nfds) {
- if(nfds > NUM_POLLS_ON_STACK) {
- /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
- big, so at 2^29 sockets this value might wrap. When a process gets
- the capability to actually handle over 500 million sockets this
- calculation needs a integer overflow check. */
- ufds = malloc(nfds * sizeof(struct pollfd));
- if(!ufds)
- return CURLM_OUT_OF_MEMORY;
- ufds_malloc = TRUE;
- }
- else
- ufds = &a_few_on_stack[0];
+ if(nfds > NUM_POLLS_ON_STACK) {
+ /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
+ big, so at 2^29 sockets this value might wrap. When a process gets
+ the capability to actually handle over 500 million sockets this
+ calculation needs a integer overflow check. */
+ ufds = malloc(nfds * sizeof(struct pollfd));
+ if(!ufds)
+ return CURLM_OUT_OF_MEMORY;
+ ufds_malloc = TRUE;
}
nfds = 0;
@@ -1154,17 +1157,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
{
return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL);
}
-/*
- * Curl_multi_connchanged() is called to tell that there is a connection in
- * this multi handle that has changed state (pipelining become possible, the
- * number of allowed streams changed or similar), and a subsequent use of this
- * multi handle should move CONNECT_PEND handles back to CONNECT to have them
- * retry.
- */
-void Curl_multi_connchanged(struct Curl_multi *multi)
-{
- multi->recheckstate = TRUE;
-}
/*
* multi_ischanged() is called
@@ -1207,57 +1199,6 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
return rc;
}
-static CURLcode multi_reconnect_request(struct Curl_easy *data)
-{
- CURLcode result = CURLE_OK;
- struct connectdata *conn = data->conn;
-
- /* This was a re-use of a connection and we got a write error in the
- * DO-phase. Then we DISCONNECT this connection and have another attempt to
- * CONNECT and then DO again! The retry cannot possibly find another
- * connection to re-use, since we only keep one possible connection for
- * each. */
-
- infof(data, "Re-used connection seems dead, get a new one\n");
-
- connclose(conn, "Reconnect dead connection"); /* enforce close */
- result = multi_done(data, result, FALSE); /* we are so done with this */
-
- /* data->conn was detached in multi_done() */
-
- /*
- * We need to check for CURLE_SEND_ERROR here as well. This could happen
- * when the request failed on a FTP connection and thus multi_done() itself
- * tried to use the connection (again).
- */
- if(!result || (CURLE_SEND_ERROR == result)) {
- bool async;
- bool protocol_done = TRUE;
-
- /* Now, redo the connect and get a new connection */
- result = Curl_connect(data, &async, &protocol_done);
- if(!result) {
- /* We have connected or sent away a name resolve query fine */
-
- conn = data->conn; /* in case it was updated */
- if(async) {
- /* Now, if async is TRUE here, we need to wait for the name
- to resolve */
- result = Curl_resolver_wait_resolv(conn, NULL);
- if(result)
- return result;
-
- /* Resolved, continue with the connection */
- result = Curl_once_resolved(conn, &protocol_done);
- if(result)
- return result;
- }
- }
- }
-
- return result;
-}
-
/*
* do_complete is called when the DO actions are complete.
*
@@ -1267,8 +1208,6 @@ static CURLcode multi_reconnect_request(struct Curl_easy *data)
static void do_complete(struct connectdata *conn)
{
conn->data->req.chunk = FALSE;
- conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
- conn->sockfd:conn->writesockfd) + 1;
Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
}
@@ -1281,27 +1220,6 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
/* generic protocol-specific function pointer set in curl_connect() */
result = conn->handler->do_it(conn, done);
- /* This was formerly done in transfer.c, but we better do it here */
- if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
- /*
- * If the connection is using an easy handle, call reconnect
- * to re-establish the connection. Otherwise, let the multi logic
- * figure out how to re-establish the connection.
- */
- if(!data->multi) {
- result = multi_reconnect_request(data);
-
- if(!result) {
- /* ... finally back to actually retry the DO phase */
- conn = data->conn; /* re-assign conn since multi_reconnect_request
- creates a new connection */
- result = conn->handler->do_it(conn, done);
- }
- }
- else
- return result;
- }
-
if(!result && *done)
/* do_complete must be called after the protocol-specific DO function */
do_complete(conn);
@@ -1549,7 +1467,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(result)
/* if Curl_once_resolved() returns failure, the connection struct
is already freed and gone */
- Curl_detach_connnection(data); /* no more connection */
+ detach_connnection(data); /* no more connection */
else {
/* call again please so that we get the next socket setup */
rc = CURLM_CALL_MULTI_PERFORM;
@@ -1620,7 +1538,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
else if(result) {
/* failure detected */
- /* Just break, the cleaning up is handled all in one place */
+ Curl_posttransfer(data);
+ multi_done(data, result, TRUE);
stream_error = TRUE;
break;
}
@@ -1933,13 +1852,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
k = &data->req;
- if(!(k->keepon & KEEP_RECV))
+ if(!(k->keepon & KEEP_RECV)) {
/* We're done receiving */
Curl_pipeline_leave_read(data->conn);
+ }
- if(!(k->keepon & KEEP_SEND))
+ if(!(k->keepon & KEEP_SEND)) {
/* We're done sending */
Curl_pipeline_leave_write(data->conn);
+ }
if(done || (result == CURLE_RECV_ERROR)) {
/* If CURLE_RECV_ERROR happens early enough, we assume it was a race
@@ -2087,7 +2008,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
* removed before we perform the processing in CURLM_STATE_COMPLETED
*/
if(data->conn)
- Curl_detach_connnection(data);
+ detach_connnection(data);
}
if(data->state.wildcardmatch) {
@@ -2145,7 +2066,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* This is where we make sure that the conn pointer is reset.
We don't have to do this in every case block above where a
failure is detected */
- Curl_detach_connnection(data);
+ detach_connnection(data);
}
}
else if(data->mstate == CURLM_STATE_CONNECT) {
@@ -2298,8 +2219,9 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_psl_destroy(&multi->psl);
/* Free the blacklists by setting them to NULL */
- Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
- Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
+ (void)Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
+ (void)Curl_pipeline_set_server_blacklist(NULL,
+ &multi->pipelining_server_bl);
free(multi);
@@ -2360,8 +2282,6 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
int num;
unsigned int curraction;
int actions[MAX_SOCKSPEREASYHANDLE];
- unsigned int comboaction;
- bool sincebefore = FALSE;
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
socks[i] = CURL_SOCKET_BAD;
@@ -2380,6 +2300,8 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
i++) {
unsigned int action = CURL_POLL_NONE;
unsigned int prevaction = 0;
+ unsigned int comboaction;
+ bool sincebefore = FALSE;
s = socks[i];
@@ -3028,9 +2950,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
DEBUGASSERT(id < EXPIRE_LAST);
- infof(data, "Expire in %ld ms for %x (transfer %p)\n",
- (long)milli, id, data);
-
set = Curl_now();
set.tv_sec += milli/1000;
set.tv_usec += (unsigned int)(milli%1000)*1000;
diff --git a/lib/non-ascii.c b/lib/non-ascii.c
index 42400b3cb..ba3240551 100644
--- a/lib/non-ascii.c
+++ b/lib/non-ascii.c
@@ -78,7 +78,7 @@ CURLcode Curl_convert_clone(struct Curl_easy *data,
/*
* Curl_convert_to_network() is an internal function for performing ASCII
- * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ * conversions on non-ASCII platforms. It converts the buffer _in place_.
*/
CURLcode Curl_convert_to_network(struct Curl_easy *data,
char *buffer, size_t length)
@@ -144,7 +144,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
/*
* Curl_convert_from_network() is an internal function for performing ASCII
- * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ * conversions on non-ASCII platforms. It converts the buffer _in place_.
*/
CURLcode Curl_convert_from_network(struct Curl_easy *data,
char *buffer, size_t length)
diff --git a/lib/openldap.c b/lib/openldap.c
index 0d9eaae5d..935632a60 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2019, 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
@@ -414,7 +414,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
lr->msgid = msgid;
data->req.protop = lr;
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
*done = TRUE;
return CURLE_OK;
}
diff --git a/lib/pop3.c b/lib/pop3.c
index 49474157e..0edbad461 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -912,7 +912,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
if(pop3->transfer == FTPTRANSFER_BODY) {
/* POP3 download */
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
if(pp->cache) {
/* The header "cache" contains a bunch of data that is actually body
diff --git a/lib/rand.h b/lib/rand.h
index c6fae3553..5deb04161 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -39,8 +39,11 @@
*/
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
-/* Same as above but outputs only random lowercase hex characters.
- Does NOT terminate.*/
+/*
+ * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
+ * hexadecimal digits PLUS a zero terminating byte. It must be an odd number
+ * size.
+ */
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
size_t num);
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 4e5366987..73c681556 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -80,8 +80,6 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
bool *readmore);
static CURLcode rtsp_setup_connection(struct connectdata *conn);
-
-bool rtsp_connisdead(struct connectdata *check);
static unsigned int rtsp_conncheck(struct connectdata *check,
unsigned int checks_to_perform);
@@ -147,7 +145,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn)
* Instead, if it is readable, run Curl_connalive() to peek at the socket
* and distinguish between closed and data.
*/
-bool rtsp_connisdead(struct connectdata *check)
+static bool rtsp_connisdead(struct connectdata *check)
{
int sval;
bool ret_val = TRUE;
@@ -251,7 +249,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
CURLcode result = CURLE_OK;
Curl_RtspReq rtspreq = data->set.rtspreq;
struct RTSP *rtsp = data->req.protop;
- struct HTTP *http;
Curl_send_buffer *req_buffer;
curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
@@ -270,10 +267,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
*done = TRUE;
- http = &(rtsp->http_wrapper);
- /* Assert that no one has changed the RTSP struct in an evil way */
- DEBUGASSERT((void *)http == (void *)rtsp);
-
rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
rtsp->CSeq_recv = 0;
@@ -330,8 +323,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
}
if(rtspreq == RTSPREQ_RECEIVE) {
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
return result;
}
@@ -599,17 +591,15 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
return result;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
- putsize?FIRSTSOCKET:-1,
- putsize?&http->writebytecount:NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1);
/* Increment the CSeq on success */
data->state.rtsp_next_client_CSeq++;
- if(http->writebytecount) {
+ if(data->req.writebytecount) {
/* if a request-body has been sent off, we make sure this progress is
noted properly */
- Curl_pgrsSetUploadCounter(data, http->writebytecount);
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
if(Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
}
diff --git a/lib/security.c b/lib/security.c
index 7f13071f6..eec6e6f44 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -10,7 +10,7 @@
* Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
*
- * Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* All rights reserved.
*
@@ -142,7 +142,7 @@ socket_read(curl_socket_t fd, void *to, size_t len)
{
char *to_p = to;
CURLcode result;
- ssize_t nread;
+ ssize_t nread = 0;
while(len > 0) {
result = Curl_read_plain(fd, to_p, len, &nread);
diff --git a/lib/sendf.c b/lib/sendf.c
index aca0f58ba..9a04b4af2 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -411,8 +411,9 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
*code = CURLE_AGAIN;
}
else {
+ char buffer[STRERROR_LEN];
failf(conn->data, "Send failure: %s",
- Curl_strerror(conn, err));
+ Curl_strerror(err, buffer, sizeof(buffer)));
conn->data->state.os_errno = err;
*code = CURLE_SEND_ERROR;
}
@@ -476,8 +477,9 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
*code = CURLE_AGAIN;
}
else {
+ char buffer[STRERROR_LEN];
failf(conn->data, "Recv failure: %s",
- Curl_strerror(conn, err));
+ Curl_strerror(err, buffer, sizeof(buffer)));
conn->data->state.os_errno = err;
*code = CURLE_RECV_ERROR;
}
diff --git a/lib/setopt.c b/lib/setopt.c
index d98ca66c9..b5f74a93d 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -44,6 +44,7 @@
#include "http2.h"
#include "setopt.h"
#include "multiif.h"
+#include "altsvc.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -111,8 +112,8 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
#define C_SSLVERSION_VALUE(x) (x & 0xffff)
#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
-CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
- va_list param)
+static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
+ va_list param)
{
char *argptr;
CURLcode result = CURLE_OK;
@@ -682,7 +683,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
* Set header option.
*/
arg = va_arg(param, long);
- data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
+ data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE);
break;
case CURLOPT_HTTP200ALIASES:
@@ -884,7 +885,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/* the DIGEST_IE bit is only used to set a special marker, for all the
rest we need to handle it as normal DIGEST */
- data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
+ data->state.authhost.iestyle =
+ (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE);
if(auth & CURLAUTH_DIGEST_IE) {
auth |= CURLAUTH_DIGEST; /* set standard digest bit */
@@ -967,7 +969,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/* the DIGEST_IE bit is only used to set a special marker, for all the
rest we need to handle it as normal DIGEST */
- data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
+ data->state.authproxy.iestyle =
+ (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE);
if(auth & CURLAUTH_DIGEST_IE) {
auth |= CURLAUTH_DIGEST; /* set standard digest bit */
@@ -2076,13 +2079,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_SSL_OPTIONS:
arg = va_arg(param, long);
- data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
+ data->set.ssl.enable_beast =
+ (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
case CURLOPT_PROXY_SSL_OPTIONS:
arg = va_arg(param, long);
- data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
+ data->set.proxy_ssl.enable_beast =
+ (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
@@ -2651,6 +2656,31 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
data->set.trailer_data = va_arg(param, void *);
#endif
break;
+#ifdef USE_ALTSVC
+ case CURLOPT_ALTSVC:
+ if(!data->asi) {
+ data->asi = Curl_altsvc_init();
+ if(!data->asi)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ argptr = va_arg(param, char *);
+ result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr);
+ if(result)
+ return result;
+ (void)Curl_altsvc_load(data->asi, argptr);
+ break;
+ case CURLOPT_ALTSVC_CTRL:
+ if(!data->asi) {
+ data->asi = Curl_altsvc_init();
+ if(!data->asi)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ arg = va_arg(param, long);
+ result = Curl_altsvc_ctrl(data->asi, arg);
+ if(result)
+ return result;
+ break;
+#endif
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;
@@ -2679,7 +2709,7 @@ CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
va_start(arg, tag);
- result = Curl_vsetopt(data, tag, arg);
+ result = vsetopt(data, tag, arg);
va_end(arg);
return result;
diff --git a/lib/smtp.c b/lib/smtp.c
index 63f4d468f..b9304a4f7 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -959,7 +959,7 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
Curl_pgrsSetUploadSize(data, data->state.infilesize);
/* SMTP upload */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
state(conn, SMTP_STOP);
@@ -1388,7 +1388,7 @@ static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
if(smtp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
return CURLE_OK;
}
diff --git a/lib/socks.c b/lib/socks.c
index d2209ad89..d0aba0605 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -54,7 +54,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
ssize_t buffersize, /* max amount to read */
ssize_t *n) /* amount bytes read */
{
- ssize_t nread;
+ ssize_t nread = 0;
ssize_t allread = 0;
int result;
*n = 0;
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index bedb01ebb..57027ef68 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
@@ -51,8 +51,9 @@ static int check_sspi_err(struct connectdata *conn,
status != SEC_I_COMPLETE_AND_CONTINUE &&
status != SEC_I_COMPLETE_NEEDED &&
status != SEC_I_CONTINUE_NEEDED) {
+ char buffer[STRERROR_LEN];
failf(conn->data, "SSPI error: %s failed: %s", function,
- Curl_sspi_strerror(conn, status));
+ Curl_sspi_strerror(status, buffer, sizeof(buffer)));
return 1;
}
return 0;
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index 718c0d343..f75fcd5ff 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017 - 2018 Red Hat, Inc.
+ * Copyright (C) 2017 - 2019 Red Hat, Inc.
*
* Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
* Robert Kolcun, Andreas Schneider
@@ -1200,7 +1200,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
Curl_pgrsSetUploadSize(data, data->state.infilesize);
}
/* upload data */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@@ -1462,7 +1462,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->sftp_dir = NULL;
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
state(conn, SSH_STOP);
break;
@@ -1603,13 +1603,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
/* Setup the actual download */
if(data->req.size == 0) {
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
infof(data, "File already completely downloaded\n");
state(conn, SSH_STOP);
break;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
- FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;
@@ -1731,8 +1730,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
/* upload data */
- Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
- FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@@ -1775,8 +1773,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
/* download data */
bytecount = ssh_scp_request_get_size(sshc->scp_session);
data->req.maxdownload = (curl_off_t) bytecount;
- Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1,
- NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;
@@ -2398,13 +2395,9 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
- if(!status && !premature && conn->data->set.postquote &&
- !conn->bits.retry) {
+ if(!premature && conn->data->set.postquote && !conn->bits.retry)
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
- state(conn, SSH_SFTP_CLOSE);
- }
- else
- state(conn, SSH_SFTP_CLOSE);
+ state(conn, SSH_SFTP_CLOSE);
}
return myssh_done(conn, status);
}
diff --git a/lib/ssh.c b/lib/ssh.c
index 910616bb6..b1b7b730a 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -81,11 +81,11 @@
#include "multiif.h"
#include "select.h"
#include "warnless.h"
+#include "curl_path.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
-#include "curl_path.h"
#include "memdebug.h"
#if LIBSSH2_VERSION_NUM >= 0x010206
@@ -1808,7 +1808,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_pgrsSetUploadSize(data, data->state.infilesize);
}
/* upload data */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@@ -2105,7 +2105,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(sshc->readdir_longentry);
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
state(conn, SSH_STOP);
break;
@@ -2245,13 +2245,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* Setup the actual download */
if(data->req.size == 0) {
/* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
infof(data, "File already completely downloaded\n");
state(conn, SSH_STOP);
break;
}
- Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
- FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;
@@ -2395,8 +2394,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
/* upload data */
- Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
- FIRSTSOCKET, NULL);
+ Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@@ -2467,7 +2465,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* download data */
bytecount = (curl_off_t)sb.st_size;
data->req.maxdownload = (curl_off_t)sb.st_size;
- Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;
@@ -2791,9 +2789,12 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
CURLcode result = CURLE_OK;
bool block; /* we store the status and use that to provide a ssh_getsock()
implementation */
-
- result = ssh_statemach_act(conn, &block);
- *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+ do {
+ result = ssh_statemach_act(conn, &block);
+ *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+ /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
+ try again */
+ } while(!result && !*done && !block);
ssh_block2waitfor(conn, block);
return result;
@@ -3222,13 +3223,9 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
- if(!status && !premature && conn->data->set.postquote &&
- !conn->bits.retry) {
+ if(!premature && conn->data->set.postquote && !conn->bits.retry)
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
- state(conn, SSH_SFTP_CLOSE);
- }
- else
- state(conn, SSH_SFTP_CLOSE);
+ state(conn, SSH_SFTP_CLOSE);
}
return ssh_done(conn, status);
}
diff --git a/lib/strerror.c b/lib/strerror.c
index d03bb4a6d..bf027fc0c 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2004 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2004 - 2019, 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
@@ -646,20 +646,18 @@ get_winsock_error (int err, char *buf, size_t len)
* We don't do range checking (on systems other than Windows) since there is
* no good reliable and portable way to do it.
*/
-const char *Curl_strerror(struct connectdata *conn, int err)
+const char *Curl_strerror(int err, char *buf, size_t buflen)
{
#ifdef PRESERVE_WINDOWS_ERROR_CODE
DWORD old_win_err = GetLastError();
#endif
int old_errno = errno;
- char *buf, *p;
+ char *p;
size_t max;
- DEBUGASSERT(conn);
DEBUGASSERT(err >= 0);
- buf = conn->syserr_buf;
- max = sizeof(conn->syserr_buf)-1;
+ max = buflen - 1;
*buf = '\0';
#ifdef USE_WINSOCK
@@ -757,7 +755,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
}
#ifdef USE_WINDOWS_SSPI
-const char *Curl_sspi_strerror (struct connectdata *conn, int err)
+const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
{
#ifdef PRESERVE_WINDOWS_ERROR_CODE
DWORD old_win_err = GetLastError();
@@ -768,15 +766,13 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
size_t outmax;
#ifndef CURL_DISABLE_VERBOSE_STRINGS
char txtbuf[80];
- char msgbuf[sizeof(conn->syserr_buf)];
+ char msgbuf[256];
char *p, *str, *msg = NULL;
bool msg_formatted = FALSE;
#endif
- DEBUGASSERT(conn);
-
- outbuf = conn->syserr_buf;
- outmax = sizeof(conn->syserr_buf)-1;
+ outbuf = buf;
+ outmax = buflen - 1;
*outbuf = '\0';
#ifndef CURL_DISABLE_VERBOSE_STRINGS
diff --git a/lib/strerror.h b/lib/strerror.h
index 627273eb2..683b5b4a3 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -24,14 +24,11 @@
#include "urldata.h"
-const char *Curl_strerror (struct connectdata *conn, int err);
-
-#ifdef USE_LIBIDN2
-const char *Curl_idn_strerror (struct connectdata *conn, int err);
-#endif
+#define STRERROR_LEN 128 /* a suitable length */
+const char *Curl_strerror(int err, char *buf, size_t buflen);
#ifdef USE_WINDOWS_SSPI
-const char *Curl_sspi_strerror (struct connectdata *conn, int err);
+const char *Curl_sspi_strerror(int err, char *buf, size_t buflen);
#endif
#endif /* HEADER_CURL_STRERROR_H */
diff --git a/lib/system_win32.c b/lib/system_win32.c
index f30e9c000..258ef9f4f 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -26,12 +26,94 @@
#include <gnurl/curl.h>
#include "system_win32.h"
+#include "curl_sspi.h"
#include "warnless.h"
/* The last #include files should be: */
#include "curl_memory.h"
#include "memdebug.h"
+LARGE_INTEGER Curl_freq;
+bool Curl_isVistaOrGreater;
+
+/* Curl_win32_init() performs win32 global initialization */
+CURLcode Curl_win32_init(long flags)
+{
+ /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which
+ is just for Winsock at the moment. Any required win32 initialization
+ should take place after this block. */
+ if(flags & CURL_GLOBAL_WIN32) {
+#ifdef USE_WINSOCK
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int res;
+
+#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
+#error IPV6_requires_winsock2
+#endif
+
+ wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+
+ res = WSAStartup(wVersionRequested, &wsaData);
+
+ if(res != 0)
+ /* Tell the user that we couldn't find a usable */
+ /* winsock.dll. */
+ return CURLE_FAILED_INIT;
+
+ /* Confirm that the Windows Sockets DLL supports what we need.*/
+ /* Note that if the DLL supports versions greater */
+ /* than wVersionRequested, it will still return */
+ /* wVersionRequested in wVersion. wHighVersion contains the */
+ /* highest supported version. */
+
+ if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+ HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
+ /* Tell the user that we couldn't find a usable */
+
+ /* winsock.dll. */
+ WSACleanup();
+ return CURLE_FAILED_INIT;
+ }
+ /* The Windows Sockets DLL is acceptable. Proceed. */
+ #elif defined(USE_LWIPSOCK)
+ lwip_init();
+ #endif
+ } /* CURL_GLOBAL_WIN32 */
+
+#ifdef USE_WINDOWS_SSPI
+ {
+ CURLcode result = Curl_sspi_global_init();
+ if(result)
+ return result;
+ }
+#endif
+
+ if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL)) {
+ Curl_isVistaOrGreater = TRUE;
+ QueryPerformanceFrequency(&Curl_freq);
+ }
+ else
+ Curl_isVistaOrGreater = FALSE;
+
+ return CURLE_OK;
+}
+
+/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */
+void Curl_win32_cleanup(long init_flags)
+{
+#ifdef USE_WINDOWS_SSPI
+ Curl_sspi_global_cleanup();
+#endif
+
+ if(init_flags & CURL_GLOBAL_WIN32) {
+#ifdef USE_WINSOCK
+ WSACleanup();
+#endif
+ }
+}
+
#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
defined(USE_WINSOCK))
diff --git a/lib/system_win32.h b/lib/system_win32.h
index 1e772856b..926328a9a 100644
--- a/lib/system_win32.h
+++ b/lib/system_win32.h
@@ -26,6 +26,12 @@
#if defined(WIN32)
+extern LARGE_INTEGER Curl_freq;
+extern bool Curl_isVistaOrGreater;
+
+CURLcode Curl_win32_init(long flags);
+void Curl_win32_cleanup(long init_flags);
+
/* Version condition */
typedef enum {
VERSION_LESS_THAN,
diff --git a/lib/telnet.c b/lib/telnet.c
index b516def75..fa51124dc 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -1692,7 +1692,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
}
#endif
/* mark this as "no further transfer wanted" */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
return result;
}
diff --git a/lib/tftp.c b/lib/tftp.c
index f45cb3935..73ddc1376 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -540,7 +540,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
state->conn->ip_addr->ai_addr,
state->conn->ip_addr->ai_addrlen);
if(senddata != (ssize_t)sbytes) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ char buffer[STRERROR_LEN];
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
}
free(filename);
break;
@@ -590,6 +591,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
ssize_t sbytes;
int rblock;
struct Curl_easy *data = state->conn->data;
+ char buffer[STRERROR_LEN];
switch(event) {
@@ -622,7 +624,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
if(sbytes < 0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_SEND_ERROR;
}
@@ -647,7 +649,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
if(sbytes < 0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_SEND_ERROR;
}
@@ -673,7 +675,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
if(sbytes<0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_SEND_ERROR;
}
}
@@ -713,6 +715,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
CURLcode result = CURLE_OK;
struct SingleRequest *k = &data->req;
size_t cb; /* Bytes currently read */
+ char buffer[STRERROR_LEN];
switch(event) {
@@ -747,7 +750,8 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->remote_addrlen);
/* Check all sbytes were sent */
if(sbytes<0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO,
+ buffer, sizeof(buffer)));
result = CURLE_SEND_ERROR;
}
}
@@ -791,7 +795,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->remote_addrlen);
/* Check all sbytes were sent */
if(sbytes<0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_SEND_ERROR;
}
/* Update the progress meter */
@@ -817,7 +821,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->remote_addrlen);
/* Check all sbytes were sent */
if(sbytes<0) {
- failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_SEND_ERROR;
}
/* since this was a re-send, we remain at the still byte position */
@@ -1030,8 +1034,9 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
conn->ip_addr->ai_addrlen);
if(rc) {
+ char buffer[STRERROR_LEN];
failf(conn->data, "bind() failed; %s",
- Curl_strerror(conn, SOCKERRNO));
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_COULDNT_CONNECT;
}
conn->bits.bound = TRUE;
@@ -1242,7 +1247,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
*done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
if(*done)
/* Tell curl we're done */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
}
else {
/* no timeouts to handle, check our socket */
@@ -1251,7 +1256,8 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
if(rc == -1) {
/* bail out */
int error = SOCKERRNO;
- failf(data, "%s", Curl_strerror(conn, error));
+ char buffer[STRERROR_LEN];
+ failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer)));
state->event = TFTP_EVENT_ERROR;
}
else if(rc != 0) {
@@ -1264,7 +1270,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
*done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
if(*done)
/* Tell curl we're done */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
}
/* if rc == 0, then select() timed out */
}
diff --git a/lib/timeval.c b/lib/timeval.c
index 2569f175c..ff8d8a69a 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -21,30 +21,22 @@
***************************************************************************/
#include "timeval.h"
-#include "system_win32.h"
#if defined(WIN32) && !defined(MSDOS)
+/* set in win32_init() */
+extern LARGE_INTEGER Curl_freq;
+extern bool Curl_isVistaOrGreater;
+
struct curltime Curl_now(void)
{
struct curltime now;
- static LARGE_INTEGER freq;
- static int isVistaOrGreater = -1;
- if(isVistaOrGreater == -1) {
- if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
- VERSION_GREATER_THAN_EQUAL)) {
- isVistaOrGreater = 1;
- QueryPerformanceFrequency(&freq);
- }
- else
- isVistaOrGreater = 0;
- }
- if(isVistaOrGreater == 1) { /* QPC timer might have issues pre-Vista */
+ if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
- now.tv_sec = (time_t)(count.QuadPart / freq.QuadPart);
- now.tv_usec =
- (int)((count.QuadPart % freq.QuadPart) * 1000000 / freq.QuadPart);
+ now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart);
+ now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
+ Curl_freq.QuadPart);
}
else {
/* Disable /analyze warning that GetTickCount64 is preferred */
diff --git a/lib/transfer.c b/lib/transfer.c
index 5d85f3d6b..ea1b1e16f 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -296,10 +296,10 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
here, knowing they'll become CRLFs later on.
*/
- char hexbuffer[11];
+ char hexbuffer[11] = "";
+ int hexlen = 0;
const char *endofline_native;
const char *endofline_network;
- int hexlen = 0;
if(
#ifdef CURL_DO_LINEEND_CONV
@@ -354,12 +354,14 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
length = nread;
else
/* just translate the protocol portion */
- length = strlen(hexbuffer);
- result = Curl_convert_to_network(data, data->req.upload_fromhere,
- length);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(result)
- return result;
+ length = hexlen;
+ if(length) {
+ result = Curl_convert_to_network(data, data->req.upload_fromhere,
+ length);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+ }
}
#endif /* CURL_DOES_CONVERSIONS */
@@ -1196,6 +1198,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
(size_t)bytes_written);
k->writebytecount += bytes_written;
+ Curl_pgrsSetUploadCounter(data, k->writebytecount);
if((!k->upload_chunky || k->forbidchunk) &&
(k->writebytecount == data->state.infilesize)) {
@@ -1229,7 +1232,6 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
}
}
- Curl_pgrsSetUploadCounter(data, k->writebytecount);
} WHILE_FALSE; /* just to break out from! */
@@ -1307,11 +1309,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->now = Curl_now();
if(didwhat) {
- /* Update read/write counters */
- if(k->bytecountp)
- *k->bytecountp = k->bytecount; /* read count */
- if(k->writebytecountp)
- *k->writebytecountp = k->writebytecount; /* write count */
+ ;
}
else {
/* no read no write, this is a timeout? */
@@ -1526,11 +1524,14 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
if(data->set.httpreq == HTTPREQ_PUT)
data->state.infilesize = data->set.filesize;
- else {
+ else if((data->set.httpreq != HTTPREQ_GET) &&
+ (data->set.httpreq != HTTPREQ_HEAD)) {
data->state.infilesize = data->set.postfieldsize;
if(data->set.postfields && (data->state.infilesize == -1))
data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
}
+ else
+ data->state.infilesize = 0;
/* If there is a list of cookie files to read, do it now! */
if(data->change.cookielist)
@@ -1852,8 +1853,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
- struct HTTP *http = data->req.protop;
- if(http->writebytecount) {
+ if(data->req.writebytecount) {
CURLcode result = Curl_readrewind(conn);
if(result) {
Curl_safefree(*url);
@@ -1871,24 +1871,17 @@ CURLcode Curl_retry_request(struct connectdata *conn,
*/
void
Curl_setup_transfer(
- struct connectdata *conn, /* connection data */
+ struct Curl_easy *data, /* transfer */
int sockindex, /* socket index to read from or -1 */
curl_off_t size, /* -1 if unknown at this point */
bool getheader, /* TRUE if header parsing is wanted */
- curl_off_t *bytecountp, /* return number of bytes read or NULL */
- int writesockindex, /* socket index to write to, it may very well be
+ int writesockindex /* socket index to write to, it may very well be
the same we read from. -1 disables */
- curl_off_t *writecountp /* return number of bytes written or NULL */
)
{
- struct Curl_easy *data;
- struct SingleRequest *k;
-
+ struct SingleRequest *k = &data->req;
+ struct connectdata *conn = data->conn;
DEBUGASSERT(conn != NULL);
-
- data = conn->data;
- k = &data->req;
-
DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
if(conn->bits.multiplex || conn->httpversion == 20) {
@@ -1907,8 +1900,6 @@ Curl_setup_transfer(
k->getheader = getheader;
k->size = size;
- k->bytecountp = bytecountp;
- k->writebytecountp = writecountp;
/* The code sequence below is placed in this function just because all
necessary input is not always known in do_complete() as this function may
diff --git a/lib/transfer.h b/lib/transfer.h
index 9742455ae..a9bff6348 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -59,15 +59,13 @@ CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
/* This sets up a forthcoming transfer */
void
-Curl_setup_transfer (struct connectdata *data,
- int sockindex, /* socket index to read from or -1 */
- curl_off_t size, /* -1 if unknown at this point */
- bool getheader, /* TRUE if header parsing is wanted */
- curl_off_t *bytecountp, /* return number of bytes read */
- int writesockindex, /* socket index to write to, it may
- very well be the same we read from.
- -1 disables */
- curl_off_t *writecountp /* return number of bytes written */
-);
+Curl_setup_transfer (struct Curl_easy *data,
+ int sockindex, /* socket index to read from or -1 */
+ curl_off_t size, /* -1 if unknown at this point */
+ bool getheader, /* TRUE if header parsing is wanted */
+ int writesockindex /* socket index to write to. May be
+ the same we read from. -1
+ disables */
+ );
#endif /* HEADER_CURL_TRANSFER_H */
diff --git a/lib/url.c b/lib/url.c
index d5a982008..eb09a24be 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -120,6 +120,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "dotdot.h"
#include "strdup.h"
#include "setopt.h"
+#include "altsvc.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -292,7 +293,7 @@ void Curl_freeset(struct Curl_easy *data)
}
/* free the URL pieces */
-void Curl_up_free(struct Curl_easy *data)
+static void up_free(struct Curl_easy *data)
{
struct urlpieces *up = &data->state.up;
Curl_safefree(up->scheme);
@@ -303,7 +304,8 @@ void Curl_up_free(struct Curl_easy *data)
Curl_safefree(up->options);
Curl_safefree(up->path);
Curl_safefree(up->query);
- curl_url_cleanup(data->state.uh);
+ if(data->set.uh != data->state.uh)
+ curl_url_cleanup(data->state.uh);
data->state.uh = NULL;
}
@@ -369,11 +371,16 @@ CURLcode Curl_close(struct Curl_easy *data)
}
data->change.referer = NULL;
- Curl_up_free(data);
+ up_free(data);
Curl_safefree(data->state.buffer);
Curl_safefree(data->state.headerbuff);
Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, 1);
+#ifdef USE_ALTSVC
+ Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]);
+ Curl_altsvc_cleanup(data->asi);
+ data->asi = NULL;
+#endif
Curl_digest_cleanup(data);
Curl_safefree(data->info.contenttype);
Curl_safefree(data->info.wouldredirect);
@@ -660,11 +667,15 @@ static void conn_reset_all_postponed_data(struct connectdata *conn)
#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
-static void conn_free(struct connectdata *conn)
+
+static void conn_shutdown(struct connectdata *conn)
{
if(!conn)
return;
+ infof(conn->data, "Closing connection %ld\n", conn->connection_id);
+ DEBUGASSERT(conn->data);
+
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(conn);
@@ -688,6 +699,21 @@ static void conn_free(struct connectdata *conn)
Curl_ntlm_wb_cleanup(conn);
#endif
+ /* unlink ourselves. this should be called last since other shutdown
+ procedures need a valid conn->data and this may clear it. */
+ Curl_conncache_remove_conn(conn->data, conn, TRUE);
+}
+
+static void conn_free(struct connectdata *conn)
+{
+ if(!conn)
+ return;
+
+ free_idnconverted_hostname(&conn->host);
+ free_idnconverted_hostname(&conn->conn_to_host);
+ free_idnconverted_hostname(&conn->http_proxy.host);
+ free_idnconverted_hostname(&conn->socks_proxy.host);
+
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
Curl_safefree(conn->oauth_bearer);
@@ -780,27 +806,20 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
/* Cleanup NTLM connection-related data */
Curl_http_ntlm_cleanup(conn);
#endif
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+ /* Cleanup NEGOTIATE connection-related data */
+ Curl_cleanup_negotiate(conn);
+#endif
- /* the protocol specific disconnect handler needs a transfer for its
- connection! */
+ /* the protocol specific disconnect handler and conn_shutdown need a transfer
+ for the connection! */
conn->data = data;
+
if(conn->handler->disconnect)
/* This is set if protocol-specific cleanups should be made */
conn->handler->disconnect(conn, dead_connection);
- /* unlink ourselves! */
- infof(data, "Closing connection %ld\n", conn->connection_id);
- Curl_conncache_remove_conn(data, conn, TRUE);
-
- free_idnconverted_hostname(&conn->host);
- free_idnconverted_hostname(&conn->conn_to_host);
- free_idnconverted_hostname(&conn->http_proxy.host);
- free_idnconverted_hostname(&conn->socks_proxy.host);
-
- /* this assumes that the pointer is still there after the connection was
- detected from the cache */
- Curl_ssl_close(conn, FIRSTSOCKET);
-
+ conn_shutdown(conn);
conn_free(conn);
return CURLE_OK;
}
@@ -956,7 +975,7 @@ static bool extract_if_dead(struct connectdata *conn,
struct Curl_easy *data)
{
size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
- if(!pipeLen && !CONN_INUSE(conn)) {
+ if(!pipeLen && !CONN_INUSE(conn) && !conn->data) {
/* The check for a dead socket makes sense only if there are no
handles in pipeline and the connection isn't already marked in
use */
@@ -965,7 +984,10 @@ static bool extract_if_dead(struct connectdata *conn,
/* The protocol has a special method for checking the state of the
connection. Use it to check if the connection is dead. */
unsigned int state;
+ struct Curl_easy *olddata = conn->data;
+ conn->data = data; /* use this transfer for now */
state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
+ conn->data = olddata;
dead = (state & CONNRESULT_DEAD);
}
else {
@@ -994,7 +1016,6 @@ struct prunedead {
static int call_extract_if_dead(struct connectdata *conn, void *param)
{
struct prunedead *p = (struct prunedead *)param;
- conn->data = p->data; /* transfer to use for this check */
if(extract_if_dead(conn, p->data)) {
/* stop the iteration here, pass back the connection that was extracted */
p->extracted = conn;
@@ -1132,6 +1153,10 @@ ConnectionExists(struct Curl_easy *data,
check = curr->ptr;
curr = curr->next;
+ if(check->bits.connect_only)
+ /* connect-only connections will not be reused */
+ continue;
+
if(extract_if_dead(check, data)) {
/* disconnect it */
(void)Curl_disconnect(data, check, /* dead_connection */TRUE);
@@ -1262,14 +1287,15 @@ ConnectionExists(struct Curl_easy *data,
}
}
- if(!canpipe && CONN_INUSE(check))
+ if(!canpipe && check->data)
/* this request can't be pipelined but the checked connection is
already in use so we skip it */
continue;
- if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
- /* this could be subject for pipeline/multiplex use, but only
- if they belong to the same multi handle */
+ if(CONN_INUSE(check) && check->data &&
+ (check->data->multi != needle->data->multi))
+ /* this could be subject for pipeline/multiplex use, but only if they
+ belong to the same multi handle */
continue;
if(needle->localdev || needle->localport) {
@@ -1685,6 +1711,8 @@ static bool is_ASCII_name(const char *hostname)
static void strip_trailing_dot(struct hostname *host)
{
size_t len;
+ if(!host || !host->name)
+ return;
len = strlen(host->name);
if(len && (host->name[len-1] == '.'))
host->name[len-1] = 0;
@@ -1749,15 +1777,6 @@ static CURLcode idnconvert_hostname(struct connectdata *conn,
infof(data, "IDN support not present, can't parse Unicode domains\n");
#endif
}
- {
- char *hostp;
- for(hostp = host->name; *hostp; hostp++) {
- if(*hostp <= 32) {
- failf(data, "Host name '%s' contains bad letter", host->name);
- return CURLE_URL_MALFORMAT;
- }
- }
- }
return CURLE_OK;
}
@@ -1899,8 +1918,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
-
conn->ip_version = data->set.ipver;
+ conn->bits.connect_only = data->set.connect_only;
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
defined(NTLM_WB_ENABLED)
@@ -2029,11 +2048,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
CURLUcode uc;
char *hostname;
- Curl_up_free(data); /* cleanup previous leftovers first */
+ up_free(data); /* cleanup previous leftovers first */
/* parse the URL */
if(data->set.uh) {
- uh = data->set.uh;
+ uh = data->state.uh = data->set.uh;
}
else {
uh = data->state.uh = curl_url();
@@ -3361,6 +3380,34 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
conn_to_host = conn_to_host->next;
}
+#ifdef USE_ALTSVC
+ if(data->asi && !host && (port == -1) &&
+ (conn->handler->protocol == CURLPROTO_HTTPS)) {
+ /* no connect_to match, try alt-svc! */
+ const char *nhost;
+ int nport;
+ enum alpnid nalpnid;
+ bool hit;
+ host = conn->host.rawalloc;
+ hit = Curl_altsvc_lookup(data->asi,
+ ALPN_h1, host, conn->remote_port, /* from */
+ &nalpnid, &nhost, &nport /* to */);
+ if(hit) {
+ char *hostd = strdup((char *)nhost);
+ if(!hostd)
+ return CURLE_OUT_OF_MEMORY;
+ conn->conn_to_host.rawalloc = hostd;
+ conn->conn_to_host.name = hostd;
+ conn->bits.conn_to_host = TRUE;
+ conn->conn_to_port = nport;
+ conn->bits.conn_to_port = TRUE;
+ infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n",
+ Curl_alpnid2str(ALPN_h1), host, conn->remote_port,
+ Curl_alpnid2str(nalpnid), hostd, nport);
+ }
+ }
+#endif
+
return result;
}
@@ -3374,6 +3421,8 @@ static CURLcode resolve_server(struct Curl_easy *data,
CURLcode result = CURLE_OK;
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ DEBUGASSERT(conn);
+ DEBUGASSERT(data);
/*************************************************************
* Resolve the name of the server or proxy
*************************************************************/
@@ -3789,9 +3838,8 @@ static CURLcode create_conn(struct Curl_easy *data,
(void)conn->handler->done(conn, result, FALSE);
goto out;
}
-
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
- -1, NULL); /* no upload */
+ Curl_attach_connnection(data, conn);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
}
/* since we skip do_init() */
@@ -3877,8 +3925,9 @@ static CURLcode create_conn(struct Curl_easy *data,
/* reuse_fresh is TRUE if we are told to use a new connection by force, but
we only acknowledge this option if this is not a re-used connection
already (which happens due to follow-location or during a HTTP
- authentication phase). */
- if(data->set.reuse_fresh && !data->state.this_is_a_follow)
+ authentication phase). CONNECT_ONLY transfers also refuse reuse. */
+ if((data->set.reuse_fresh && !data->state.this_is_a_follow) ||
+ data->set.connect_only)
reuse = FALSE;
else
reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
@@ -4170,7 +4219,8 @@ CURLcode Curl_connect(struct Curl_easy *data,
connectdata struct, free those here */
Curl_disconnect(data, conn, TRUE);
}
- else
+ else if(!data->conn)
+ /* FILE: transfers already have the connection attached */
Curl_attach_connnection(data, conn);
return result;
diff --git a/lib/urlapi.c b/lib/urlapi.c
index 3af8e9399..a19867eb0 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -67,12 +67,6 @@ struct Curl_URL {
#define DEFAULT_SCHEME "https"
-#ifdef DEBUGBUILD
-#define UNITTEST
-#else
-#define UNITTEST static
-#endif
-
static void free_urlhandle(struct Curl_URL *u)
{
free(u->scheme);
@@ -141,7 +135,7 @@ static bool urlchar_needs_escaping(int c)
* URL encoding should be skipped for host names, otherwise IDN resolution
* will fail.
*/
-size_t Curl_strlen_url(const char *url, bool relative)
+static size_t strlen_url(const char *url, bool relative)
{
const unsigned char *ptr;
size_t newlen = 0;
@@ -183,7 +177,7 @@ size_t Curl_strlen_url(const char *url, bool relative)
* URL encoding should be skipped for host names, otherwise IDN resolution
* will fail.
*/
-void Curl_strcpy_url(char *output, const char *url, bool relative)
+static void strcpy_url(char *output, const char *url, bool relative)
{
/* we must add this with whitespace-replacing */
bool left = TRUE;
@@ -268,7 +262,7 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
* The returned pointer must be freed by the caller unless NULL
* (returns NULL on out of memory).
*/
-char *Curl_concat_url(const char *base, const char *relurl)
+static char *concat_url(const char *base, const char *relurl)
{
/***
TRY to append this new path to the old URL
@@ -392,7 +386,7 @@ char *Curl_concat_url(const char *base, const char *relurl)
letter we replace each space with %20 while it is replaced with '+'
on the right side of the '?' letter.
*/
- newlen = Curl_strlen_url(useurl, !host_changed);
+ newlen = strlen_url(useurl, !host_changed);
urllen = strlen(url_clone);
@@ -414,7 +408,7 @@ char *Curl_concat_url(const char *base, const char *relurl)
newest[urllen++]='/';
/* then append the new piece on the right side */
- Curl_strcpy_url(&newest[urllen], useurl, !host_changed);
+ strcpy_url(&newest[urllen], useurl, !host_changed);
free(url_clone);
@@ -574,15 +568,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
/* scan for byte values < 31 or 127 */
static CURLUcode junkscan(char *part)
{
- char badbytes[]={
- /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x7f,
- 0x00 /* zero terminate */
- };
if(part) {
+ static const char badbytes[]={
+ /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x7f,
+ 0x00 /* zero terminate */
+ };
size_t n = strlen(part);
size_t nfine = strcspn(part, badbytes);
if(nfine != n)
@@ -1083,10 +1077,10 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
return CURLUE_OUT_OF_MEMORY;
*part = url;
return CURLUE_OK;
- break;
}
default:
ptr = NULL;
+ break;
}
if(ptr) {
*part = strdup(ptr);
@@ -1252,7 +1246,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
/* apply the relative part to create a new URL */
- redired_url = Curl_concat_url(oldurl, part);
+ redired_url = concat_url(oldurl, part);
free(oldurl);
if(!redired_url)
return CURLUE_OUT_OF_MEMORY;
diff --git a/lib/urldata.h b/lib/urldata.h
index 73195c7d3..0681e8da7 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -129,12 +129,14 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#ifdef HAVE_GSSAPI
# ifdef HAVE_GSSGNU
# include <gss.h>
-# elif defined HAVE_GSSMIT
+# elif defined HAVE_GSSAPI_GSSAPI_H
# include <gssapi/gssapi.h>
-# include <gssapi/gssapi_generic.h>
# else
# include <gssapi.h>
# endif
+# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
+# include <gssapi/gssapi_generic.h>
+# endif
#endif
#ifdef HAVE_LIBSSH2_H
@@ -154,13 +156,16 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#define GOOD_EASY_HANDLE(x) \
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
+/* the type we use for storing a single boolean bit */
+typedef unsigned int bit;
+
#ifdef HAVE_GSSAPI
/* Types needed for krb5-ftp connections */
struct krb5buffer {
void *data;
size_t size;
size_t index;
- int eof_flag;
+ bit eof_flag:1;
};
enum protection_level {
@@ -198,22 +203,18 @@ struct ssl_connect_data {
/* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
but at least asked to or meaning to use it. See 'state' for the exact
current state of the connection. */
- bool use;
ssl_connection_state state;
ssl_connect_state connecting_state;
#if defined(USE_SSL)
struct ssl_backend_data *backend;
#endif
+ bit use:1;
};
struct ssl_primary_config {
long version; /* what version the client wants to use */
long version_max; /* max supported version the client wants to use*/
- bool verifypeer; /* set TRUE if this is desired */
- bool verifyhost; /* set TRUE if CN/SAN must match hostname */
- bool verifystatus; /* set TRUE if certificate status must be checked */
- bool sessionid; /* cache session IDs or not */
char *CApath; /* certificate dir (doesn't work on windows) */
char *CAfile; /* certificate to verify peer against */
char *clientcert;
@@ -221,32 +222,33 @@ struct ssl_primary_config {
char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
+ bit verifypeer:1; /* set TRUE if this is desired */
+ bit verifyhost:1; /* set TRUE if CN/SAN must match hostname */
+ bit verifystatus:1; /* set TRUE if certificate status must be checked */
+ bit sessionid:1; /* cache session IDs or not */
};
struct ssl_config_data {
struct ssl_primary_config primary;
- bool enable_beast; /* especially allow this flaw for interoperability's
- sake*/
- bool no_revoke; /* disable SSL certificate revocation checks */
long certverifyresult; /* result from the certificate verification */
char *CRLfile; /* CRL to check certificate revocation */
char *issuercert;/* optional issuer certificate filename */
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /* parameter for call back */
- bool certinfo; /* gather lots of certificate info */
- bool falsestart;
-
char *cert; /* client certificate file name */
char *cert_type; /* format for certificate (default: PEM)*/
char *key; /* private key file name */
char *key_type; /* format for private key (default: PEM) */
char *key_passwd; /* plain text private key password */
-
#ifdef USE_TLS_SRP
char *username; /* TLS username (for, e.g., SRP) */
char *password; /* TLS password (for, e.g., SRP) */
enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
#endif
+ bit certinfo:1; /* gather lots of certificate info */
+ bit falsestart:1;
+ bit enable_beast:1; /* allow this flaw for interoperability's sake*/
+ bit no_revoke:1; /* disable SSL certificate revocation checks */
};
struct ssl_general_config {
@@ -285,12 +287,12 @@ struct digestdata {
char *cnonce;
char *realm;
int algo;
- bool stale; /* set true for re-negotiation */
char *opaque;
char *qop;
char *algorithm;
int nc; /* nounce count */
- bool userhash;
+ bit stale:1; /* set true for re-negotiation */
+ bit userhash:1;
#endif
};
@@ -357,7 +359,9 @@ struct ntlmdata {
struct negotiatedata {
/* When doing Negotiate (SPNEGO) auth, we first need to send a token
and then validate the received one. */
- enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
+ enum {
+ GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT, GSS_AUTHDONE, GSS_AUTHSUCC
+ } state;
#ifdef HAVE_GSSAPI
OM_uint32 status;
gss_ctx_id_t context;
@@ -379,6 +383,10 @@ struct negotiatedata {
size_t output_token_length;
#endif
#endif
+ bool noauthpersist;
+ bool havenoauthpersist;
+ bool havenegdata;
+ bool havemultiplerequests;
};
#endif
@@ -388,69 +396,65 @@ struct negotiatedata {
*/
struct ConnectBits {
/* always modify bits.close with the connclose() and connkeep() macros! */
- bool close; /* if set, we close the connection after this request */
- bool reuse; /* if set, this is a re-used connection */
- bool conn_to_host; /* if set, this connection has a "connect to host"
- that overrides the host in the URL */
- bool conn_to_port; /* if set, this connection has a "connect to port"
- that overrides the port in the URL (remote port) */
- bool proxy; /* if set, this transfer is done through a proxy - any type */
- bool httpproxy; /* if set, this transfer is done through a http proxy */
- bool socksproxy; /* if set, this transfer is done through a socks proxy */
- bool user_passwd; /* do we use user+password for this connection? */
- bool proxy_user_passwd; /* user+password for the proxy? */
- bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
- IP address */
- bool ipv6; /* we communicate with a site using an IPv6 address */
-
- bool do_more; /* this is set TRUE if the ->curl_do_more() function is
- supposed to be called, after ->curl_do() */
- bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
- the first time on the first connect function call */
- bool protoconnstart;/* the protocol layer has STARTED its operation after
- the TCP layer connect */
-
- bool retry; /* this connection is about to get closed and then
- re-attempted at another connection. */
- bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy.
- This is implicit when SSL-protocols are used through
- proxies, but can also be enabled explicitly by
- apps */
- bool authneg; /* TRUE when the auth phase has started, which means
- that we are creating a request with an auth header,
- but it is not the final request in the auth
- negotiation. */
- bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
- though it will be discarded. When the whole send
- operation is done, we must call the data rewind
- callback. */
- bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
- EPSV doesn't work we disable it for the forthcoming
- requests */
-
- bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
- EPRT doesn't work we disable it for the forthcoming
- requests */
- bool ftp_use_data_ssl; /* Enabled SSL for the data connection */
- bool netrc; /* name+password provided by netrc */
- bool userpwd_in_url; /* name+password found in url */
- bool stream_was_rewound; /* Indicates that the stream was rewound after a
- request read past the end of its response byte
- boundary */
- bool proxy_connect_closed; /* set true if a proxy disconnected the
- connection in a CONNECT request with auth, so
- that libcurl should reconnect and continue. */
- bool bound; /* set true if bind() has already been done on this socket/
- connection */
- bool type_set; /* type= was used in the URL */
- bool multiplex; /* connection is multiplexed */
-
- bool tcp_fastopen; /* use TCP Fast Open */
- bool tls_enable_npn; /* TLS NPN extension? */
- bool tls_enable_alpn; /* TLS ALPN extension? */
bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
is complete */
- bool socksproxy_connecting; /* connecting through a socks proxy */
+ bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
+ the first time on the first connect function call */
+ bit close:1; /* if set, we close the connection after this request */
+ bit reuse:1; /* if set, this is a re-used connection */
+ bit conn_to_host:1; /* if set, this connection has a "connect to host"
+ that overrides the host in the URL */
+ bit conn_to_port:1; /* if set, this connection has a "connect to port"
+ that overrides the port in the URL (remote port) */
+ bit proxy:1; /* if set, this transfer is done through a proxy - any type */
+ bit httpproxy:1; /* if set, this transfer is done through a http proxy */
+ bit socksproxy:1; /* if set, this transfer is done through a socks proxy */
+ bit user_passwd:1; /* do we use user+password for this connection? */
+ bit proxy_user_passwd:1; /* user+password for the proxy? */
+ bit ipv6_ip:1; /* we communicate with a remote site specified with pure IPv6
+ IP address */
+ bit ipv6:1; /* we communicate with a site using an IPv6 address */
+ bit do_more:1; /* this is set TRUE if the ->curl_do_more() function is
+ supposed to be called, after ->curl_do() */
+ bit protoconnstart:1;/* the protocol layer has STARTED its operation after
+ the TCP layer connect */
+ bit retry:1; /* this connection is about to get closed and then
+ re-attempted at another connection. */
+ bit tunnel_proxy:1; /* if CONNECT is used to "tunnel" through the proxy.
+ This is implicit when SSL-protocols are used through
+ proxies, but can also be enabled explicitly by
+ apps */
+ bit authneg:1; /* TRUE when the auth phase has started, which means
+ that we are creating a request with an auth header,
+ but it is not the final request in the auth
+ negotiation. */
+ bit rewindaftersend:1;/* TRUE when the sending couldn't be stopped even
+ though it will be discarded. When the whole send
+ operation is done, we must call the data rewind
+ callback. */
+ bit ftp_use_epsv:1; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
+ EPSV doesn't work we disable it for the forthcoming
+ requests */
+ bit ftp_use_eprt:1; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
+ EPRT doesn't work we disable it for the forthcoming
+ requests */
+ bit ftp_use_data_ssl:1; /* Enabled SSL for the data connection */
+ bit netrc:1; /* name+password provided by netrc */
+ bit userpwd_in_url:1; /* name+password found in url */
+ bit stream_was_rewound:1; /* The stream was rewound after a request read
+ past the end of its response byte boundary */
+ bit proxy_connect_closed:1; /* TRUE if a proxy disconnected the connection
+ in a CONNECT request with auth, so that
+ libcurl should reconnect and continue. */
+ bit bound:1; /* set true if bind() has already been done on this socket/
+ connection */
+ bit type_set:1; /* type= was used in the URL */
+ bit multiplex:1; /* connection is multiplexed */
+ bit tcp_fastopen:1; /* use TCP Fast Open */
+ bit tls_enable_npn:1; /* TLS NPN extension? */
+ bit tls_enable_alpn:1; /* TLS ALPN extension? */
+ bit socksproxy_connecting:1; /* connecting through a socks proxy */
+ bit connect_only:1;
};
struct hostname {
@@ -477,14 +481,13 @@ struct hostname {
#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
-
struct Curl_async {
char *hostname;
int port;
struct Curl_dns_entry *dns;
- bool done; /* set TRUE when the lookup is complete */
int status; /* if done is TRUE, this is the status from the callback */
void *os_specific; /* 'struct thread_data' for Windows */
+ bit done:1; /* set TRUE when the lookup is complete */
};
#define FIRSTSOCKET 0
@@ -542,25 +545,21 @@ struct dohdata {
*/
struct SingleRequest {
curl_off_t size; /* -1 if unknown at this point */
- curl_off_t *bytecountp; /* return number of bytes read or NULL */
-
curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch,
-1 means unlimited */
- curl_off_t *writebytecountp; /* return number of bytes written or NULL */
-
curl_off_t bytecount; /* total number of bytes read */
curl_off_t writebytecount; /* number of bytes written */
- long headerbytecount; /* only count received headers */
- long deductheadercount; /* this amount of bytes doesn't count when we check
- if anything has been transferred at the end of a
- connection. We use this counter to make only a
- 100 reply (without a following second response
- code) result in a CURLE_GOT_NOTHING error code */
+ curl_off_t headerbytecount; /* only count received headers */
+ curl_off_t deductheadercount; /* this amount of bytes doesn't count when we
+ check if anything has been transferred at
+ the end of a connection. We use this
+ counter to make only a 100 reply (without a
+ following second response code) result in a
+ CURLE_GOT_NOTHING error code */
struct curltime start; /* transfer started at this time */
struct curltime now; /* current time */
- bool header; /* incoming data has HTTP header */
enum {
HEADER_NORMAL, /* no bad header at all */
HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest
@@ -576,7 +575,6 @@ struct SingleRequest {
char *str_start; /* within buf */
char *end_ptr; /* within buf */
char *p; /* within headerbuff */
- bool content_range; /* set TRUE if Content-Range: was found */
curl_off_t offset; /* possible resume offset read from the
Content-Range: header */
int httpcode; /* error code from the 'HTTP/1.? XXX' or
@@ -589,19 +587,8 @@ struct SingleRequest {
/* See sec 3.5, RFC2616. */
time_t timeofdoc;
long bodywrites;
-
char *buf;
- curl_socket_t maxfd;
-
int keepon;
-
- bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
- and we're uploading the last chunk */
-
- bool ignorebody; /* we read a response-body but we ignore it! */
- bool ignorecl; /* This HTTP response has no body so we ignore the Content-
- Length: header */
-
char *location; /* This points to an allocated version of the Location:
header data */
char *newurl; /* Set to the new URL to use when a redirect or a retry is
@@ -611,24 +598,28 @@ struct SingleRequest {
still left in the buffer, aimed for upload. */
ssize_t upload_present;
- /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
- buffer, so the next read should read from where this pointer points to,
- and the 'upload_present' contains the number of bytes available at this
- position */
+ /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
+ buffer, so the next read should read from where this pointer points to,
+ and the 'upload_present' contains the number of bytes available at this
+ position */
char *upload_fromhere;
-
- bool chunk; /* if set, this is a chunked transfer-encoding */
- bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
- on upload */
- bool getheader; /* TRUE if header parsing is wanted */
-
- bool forbidchunk; /* used only to explicitly forbid chunk-upload for
- specific upload buffers. See readmoredata() in
- http.c for details. */
-
void *protop; /* Allocated protocol-specific data. Each protocol
handler makes sure this points to data it needs. */
struct dohdata doh; /* DoH specific data for this request */
+ bit header:1; /* incoming data has HTTP header */
+ bit content_range:1; /* set TRUE if Content-Range: was found */
+ bit upload_done:1; /* set to TRUE when doing chunked transfer-encoding
+ upload and we're uploading the last chunk */
+ bit ignorebody:1; /* we read a response-body but we ignore it! */
+ bit ignorecl:1; /* This HTTP response has no body so we ignore the
+ Content-Length: header */
+ bit chunk:1; /* if set, this is a chunked transfer-encoding */
+ bit upload_chunky:1; /* set TRUE if we are doing chunked transfer-encoding
+ on upload */
+ bit getheader:1; /* TRUE if header parsing is wanted */
+ bit forbidchunk:1; /* used only to explicitly forbid chunk-upload for
+ specific upload buffers. See readmoredata() in http.c
+ for details. */
};
/*
@@ -776,13 +767,13 @@ struct http_connect_state {
char *line_start;
char *ptr; /* where to store more data */
curl_off_t cl; /* size of content to read and ignore */
- bool chunked_encoding;
enum {
TUNNEL_INIT, /* init/default/no tunnel state */
TUNNEL_CONNECT, /* CONNECT has been sent off */
TUNNEL_COMPLETE /* CONNECT response received completely */
} tunnel_state;
- bool close_connection;
+ bit chunked_encoding:1;
+ bit close_connection:1;
};
/*
@@ -899,8 +890,6 @@ struct connectdata {
#endif
struct ssl_primary_config ssl_config;
struct ssl_primary_config proxy_ssl_config;
- bool tls_upgraded;
-
struct ConnectBits bits; /* various state-flags for this connection */
/* connecttime: when connect() is called on the current IP address. Used to
@@ -947,7 +936,7 @@ struct connectdata {
} allocptr;
#ifdef HAVE_GSSAPI
- int sec_complete; /* if Kerberos is enabled for this connection */
+ bit sec_complete:1; /* if Kerberos is enabled for this connection */
enum protection_level command_prot;
enum protection_level data_prot;
enum protection_level request_data_prot;
@@ -962,14 +951,6 @@ struct connectdata {
struct kerberos5data krb5; /* variables into the structure definition, */
#endif /* however, some of them are ftp specific. */
- /* the two following *_inuse fields are only flags, not counters in any way.
- If TRUE it means the channel is in use, and if FALSE it means the channel
- is up for grabs by one. */
-
- bool readchannel_inuse; /* whether the read channel is in use by an easy
- handle */
- bool writechannel_inuse; /* whether the write channel is in use by an easy
- handle */
struct curl_llist send_pipe; /* List of handles waiting to send on this
pipeline */
struct curl_llist recv_pipe; /* List of handles waiting to read their
@@ -1003,7 +984,11 @@ struct connectdata {
#endif
#endif
- char syserr_buf [256]; /* buffer for Curl_strerror() */
+#ifdef USE_SPNEGO
+ struct negotiatedata negotiate; /* state data for host Negotiate auth */
+ struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
+#endif
+
/* data used for the asynch name resolve callback */
struct Curl_async async;
@@ -1046,8 +1031,16 @@ struct connectdata {
#ifdef USE_UNIX_SOCKETS
char *unix_domain_socket;
- bool abstract_unix_socket;
+ bit abstract_unix_socket:1;
#endif
+ bit tls_upgraded:1;
+ /* the two following *_inuse fields are only flags, not counters in any way.
+ If TRUE it means the channel is in use, and if FALSE it means the channel
+ is up for grabs by one. */
+ bit readchannel_inuse:1; /* whether the read channel is in use by an easy
+ handle */
+ bit writechannel_inuse:1; /* whether the write channel is in use by an easy
+ handle */
};
/* The end of connectdata. */
@@ -1062,10 +1055,8 @@ struct PureInfo {
int httpversion; /* the http version number X.Y = X*10+Y */
time_t filetime; /* If requested, this is might get set. Set to -1 if the
time was unretrievable. */
- bool timecond; /* set to TRUE if the time condition didn't match, which
- thus made the document NOT get fetched */
- long header_size; /* size of read header(s) in bytes */
- long request_size; /* the amount of bytes sent in the request(s) */
+ curl_off_t header_size; /* size of read header(s) in bytes */
+ curl_off_t request_size; /* the amount of bytes sent in the request(s) */
unsigned long proxyauthavail; /* what proxy auth types were announced */
unsigned long httpauthavail; /* what host auth types were announced */
long numconnects; /* how many new connection did libcurl created */
@@ -1082,16 +1073,16 @@ struct PureInfo {
char conn_primary_ip[MAX_IPADR_LEN];
long conn_primary_port;
-
char conn_local_ip[MAX_IPADR_LEN];
long conn_local_port;
-
const char *conn_scheme;
unsigned int conn_protocol;
-
struct curl_certinfo certs; /* info about the certs, only populated in
OpenSSL builds. Asked for with
CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+
+ bit timecond:1; /* set to TRUE if the time condition didn't match, which
+ thus made the document NOT get fetched */
};
@@ -1105,7 +1096,6 @@ struct Progress {
curl_off_t current_speed; /* uses the currently fastest transfer */
- bool callback; /* set when progress callback is used */
int width; /* screen width at download start */
int flags; /* see progress.h */
@@ -1126,7 +1116,6 @@ struct Progress {
struct curltime t_startop;
struct curltime t_acceptdata;
- bool is_t_startransfer_set;
/* upload speed limit */
struct curltime ul_limit_start;
@@ -1140,6 +1129,8 @@ struct Progress {
curl_off_t speeder[ CURR_TIME ];
struct curltime speeder_time[ CURR_TIME ];
int speeder_c;
+ bit callback:1; /* set when progress callback is used */
+ bit is_t_startransfer_set:1;
};
typedef enum {
@@ -1151,7 +1142,6 @@ typedef enum {
HTTPREQ_PUT,
HTTPREQ_HEAD,
HTTPREQ_OPTIONS,
- HTTPREQ_CUSTOM,
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
@@ -1188,12 +1178,12 @@ struct auth {
unsigned long picked;
unsigned long avail; /* Bitmask for what the server reports to support for
this resource */
- bool done; /* TRUE when the auth phase is done and ready to do the *actual*
- request */
- bool multipass; /* TRUE if this is not yet authenticated but within the
- auth multipass negotiation */
- bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
- be RFC compliant */
+ bit done:1; /* TRUE when the auth phase is done and ready to do the
+ *actual* request */
+ bit multipass:1; /* TRUE if this is not yet authenticated but within the
+ auth multipass negotiation */
+ bit iestyle:1; /* TRUE if digest should be done IE-style or FALSE if it
+ should be RFC compliant */
};
struct Curl_http2_dep {
@@ -1264,11 +1254,6 @@ struct UrlState {
/* Points to the connection cache */
struct conncache *conn_cache;
- /* when curl_easy_perform() is called, the multi handle is "owned" by
- the easy handle so curl_easy_cleanup() on such an easy handle will
- also close the multi handle! */
- bool multi_owned_by_easy;
-
/* buffers to store authentication data in, as parsed from input options */
struct curltime keeps_speed; /* for the progress meter really */
@@ -1281,8 +1266,6 @@ struct UrlState {
char *ulbuf; /* allocated upload buffer or NULL */
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
- bool this_is_a_follow; /* this is a followed Location: request */
- bool refused_stream; /* this was refused, try again */
char *first_host; /* host name of the first (not followed) request.
if set, this should be the host name that we will
sent authorization to, no else. Used to make Location:
@@ -1295,29 +1278,17 @@ struct UrlState {
unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */
- bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
- This must be set to FALSE every time _easy_perform() is
- called. */
int os_errno; /* filled in with errno whenever an error occurs */
#ifdef HAVE_SIGNAL
/* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
void (*prev_signal)(int sig);
#endif
- bool allow_port; /* Is set.use_port allowed to take effect or not. This
- is always set TRUE when curl_easy_perform() is called. */
struct digestdata digest; /* state data for host Digest auth */
struct digestdata proxydigest; /* state data for proxy Digest auth */
-#ifdef USE_SPNEGO
- struct negotiatedata negotiate; /* state data for host Negotiate auth */
- struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
-#endif
-
struct auth authhost; /* auth details for host */
struct auth authproxy; /* auth details for proxy */
- bool authproblem; /* TRUE if there's some problem authenticating */
-
void *resolver; /* resolver state, if it is used in the URL state -
ares_channel f.e. */
@@ -1333,27 +1304,18 @@ struct UrlState {
/* a place to store the most recently set FTP entrypath */
char *most_recent_ftp_entrypath;
- /* set after initial USER failure, to prevent an authentication loop */
- bool ftp_trying_alternative;
- bool wildcardmatch; /* enable wildcard matching */
int httpversion; /* the lowest HTTP version*10 reported by any server
involved in this request */
- bool expect100header; /* TRUE if we added Expect: 100-continue */
#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
!defined(__SYMBIAN32__)
/* do FTP line-end conversions on most platforms */
#define CURL_DO_LINEEND_CONV
/* for FTP downloads: track CRLF sequences that span blocks */
- bool prev_block_had_trailing_cr;
+ bit prev_block_had_trailing_cr:1;
/* for FTP downloads: how many CRLFs did we converted to LFs? */
curl_off_t crlf_conversions;
#endif
- bool slash_removed; /* set TRUE if the 'path' points to a path where the
- initial URL slash separator has been taken off */
- bool use_range;
- bool rangestringalloc; /* the range string is malloc()'ed */
-
char *range; /* range, if used. See README for detailed specification on
this syntax. */
curl_off_t resume_from; /* continue [ftp] transfer from here */
@@ -1369,19 +1331,12 @@ struct UrlState {
size_t drain; /* Increased when this stream has data to read, even if its
socket is not necessarily is readable. Decreased when
checked. */
- bool done; /* set to FALSE when Curl_init_do() is called and set to TRUE
- when multi_done() is called, to prevent multi_done() to get
- invoked twice when the multi interface is used. */
curl_read_callback fread_func; /* read callback/function */
void *in; /* CURLOPT_READDATA */
struct Curl_easy *stream_depends_on;
- bool stream_depends_e; /* set or don't set the Exclusive bit */
int stream_weight;
-#ifdef CURLDEBUG
- bool conncache_lock;
-#endif
CURLU *uh; /* URL handle for the current parsed URL */
struct urlpieces up;
#ifndef CURL_DISABLE_HTTP
@@ -1391,6 +1346,32 @@ struct UrlState {
#endif
trailers_state trailers_state; /* whether we are sending trailers
and what stage are we at */
+#ifdef CURLDEBUG
+ bit conncache_lock:1;
+#endif
+ /* when curl_easy_perform() is called, the multi handle is "owned" by
+ the easy handle so curl_easy_cleanup() on such an easy handle will
+ also close the multi handle! */
+ bit multi_owned_by_easy:1;
+
+ bit this_is_a_follow:1; /* this is a followed Location: request */
+ bit refused_stream:1; /* this was refused, try again */
+ bit errorbuf:1; /* Set to TRUE if the error buffer is already filled in.
+ This must be set to FALSE every time _easy_perform() is
+ called. */
+ bit allow_port:1; /* Is set.use_port allowed to take effect or not. This
+ is always set TRUE when curl_easy_perform() is called. */
+ bit authproblem:1; /* TRUE if there's some problem authenticating */
+ /* set after initial USER failure, to prevent an authentication loop */
+ bit ftp_trying_alternative:1;
+ bit wildcardmatch:1; /* enable wildcard matching */
+ bit expect100header:1; /* TRUE if we added Expect: 100-continue */
+ bit use_range:1;
+ bit rangestringalloc:1; /* the range string is malloc()'ed */
+ bit done:1; /* set to FALSE when Curl_init_do() is called and set to TRUE
+ when multi_done() is called, to prevent multi_done() to get
+ invoked twice when the multi interface is used. */
+ bit stream_depends_e:1; /* set or don't set the Exclusive bit */
};
@@ -1403,14 +1384,15 @@ struct UrlState {
struct DynamicStatic {
char *url; /* work URL, copied from UserDefined */
- bool url_alloc; /* URL string is malloc()'ed */
char *referer; /* referer string */
- bool referer_alloc; /* referer string is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by
curl_easy_setopt(COOKIEFILE) calls */
struct curl_slist *resolve; /* set to point to the set.resolve list when
this should be dealt with in pretransfer */
- bool wildcard_resolve; /* Set to true if any resolve change is a wildcard */
+ bit url_alloc:1; /* URL string is malloc()'ed */
+ bit referer_alloc:1; /* referer string is malloc()ed */
+ bit wildcard_resolve:1; /* Set to true if any resolve change is a
+ wildcard */
};
/*
@@ -1503,6 +1485,9 @@ enum dupstring {
#endif
STRING_TARGET, /* CURLOPT_REQUEST_TARGET */
STRING_DOH, /* CURLOPT_DOH_URL */
+#ifdef USE_ALTSVC
+ STRING_ALTSVC, /* CURLOPT_ALTSVC */
+#endif
/* -- end of zero-terminated strings -- */
STRING_LASTZEROTERMINATED,
@@ -1540,8 +1525,6 @@ struct UserDefined {
int keep_post; /* keep POSTs as POSTs after a 30x request; each
bit represents a request, from 301 to 303 */
- bool free_referer; /* set TRUE if 'referer' points to a string we
- allocated */
void *postfields; /* if POST, set the fields' values here */
curl_seek_callback seek_func; /* function that seeks the input */
curl_off_t postfieldsize; /* if POST, this might have a size to use instead
@@ -1554,8 +1537,6 @@ struct UserDefined {
curl_write_callback fwrite_header; /* function that stores headers */
curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */
curl_read_callback fread_func_set; /* function that reads the input */
- int is_fread_set; /* boolean, has read callback been set to non-NULL? */
- int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
curl_progress_callback fprogress; /* OLD and deprecated progress callback */
curl_xferinfo_callback fxferinfo; /* progress callback */
curl_debug_callback fdebug; /* function that write informational data */
@@ -1587,7 +1568,6 @@ struct UserDefined {
long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */
long server_response_timeout; /* in milliseconds, 0 means no timeout */
long tftp_blksize; /* in bytes, 0 means use default */
- bool tftp_no_options; /* do not send TFTP options requests */
curl_off_t filesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
@@ -1599,9 +1579,6 @@ struct UserDefined {
struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */
struct curl_httppost *httppost; /* linked list of old POST data */
curl_mimepart mimepost; /* MIME/POST data. */
- bool sep_headers; /* handle host and proxy headers separately */
- bool cookiesession; /* new cookie session? */
- bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* after connection is established */
struct curl_slist *postquote; /* after the transfer */
struct curl_slist *prequote; /* before the transfer, after type */
@@ -1620,7 +1597,6 @@ struct UserDefined {
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
long httpversion; /* when non-zero, a specific HTTP version requested to
be used in the library's request(s) */
- bool strip_path_slash; /* strip off initial slash from path */
struct ssl_config_data ssl; /* user defined SSL stuff */
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
@@ -1630,87 +1606,33 @@ struct UserDefined {
size_t upload_buffer_size; /* size of upload buffer to use,
keep it >= CURL_MAX_WRITE_SIZE */
void *private_data; /* application-private data */
-
struct curl_slist *http200aliases; /* linked list of aliases for http200 */
-
long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
0 - whatever, 1 - v2, 2 - v6 */
-
curl_off_t max_filesize; /* Maximum file size to download */
-
curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
-
int ftp_create_missing_dirs; /* 1 - create directories that don't exist
2 - the same but also allow MKD to fail once
*/
-
curl_sshkeycallback ssh_keyfunc; /* key matching callback */
void *ssh_keyfunc_userp; /* custom pointer to callback */
- bool ssh_compression; /* enable SSH compression */
-
-/* Here follows boolean settings that define how to behave during
- this session. They are STATIC, set by libcurl users or at least initially
- and they don't change during operations. */
- bool get_filetime; /* get the time and get of the remote file */
- bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
- bool prefer_ascii; /* ASCII rather than binary */
- bool ftp_append; /* append, not overwrite, on upload */
- bool ftp_list_only; /* switch FTP command for listing directories */
- bool ftp_use_port; /* use the FTP PORT command */
- bool hide_progress; /* don't use the progress meter */
- bool http_fail_on_error; /* fail on HTTP error codes >= 400 */
- bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
- bool http_follow_location; /* follow HTTP redirects */
- bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
- bool allow_auth_to_other_hosts;
- bool include_header; /* include received protocol headers in data output */
- bool http_set_referer; /* is a custom referer used */
- bool http_auto_referer; /* set "correct" referer when following location: */
- bool opt_no_body; /* as set with CURLOPT_NOBODY */
- bool upload; /* upload request */
enum CURL_NETRC_OPTION
use_netrc; /* defined in include/gnurl.h */
- bool verbose; /* output verbosity */
- bool krb; /* Kerberos connection requested */
- bool reuse_forbid; /* forbidden to be reused, close after use */
- bool reuse_fresh; /* do not re-use an existing connection */
- bool ftp_use_epsv; /* if EPSV is to be attempted or not */
- bool ftp_use_eprt; /* if EPRT is to be attempted or not */
- bool ftp_use_pret; /* if PRET is to be used before PASV or not */
-
curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
IMAP or POP3 or others! */
curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
curl_ftpccc ftp_ccc; /* FTP CCC options */
- bool no_signal; /* do not use any signal/alarm handler */
- bool global_dns_cache; /* subject for future removal */
- bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */
- bool ignorecl; /* ignore content length */
- bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
- us */
- bool connect_only; /* make connection, let application use the socket */
- long ssh_auth_types; /* allowed SSH auth types */
- bool http_te_skip; /* pass the raw body data to the user, even when
- transfer-encoded (chunked, compressed) */
- bool http_ce_skip; /* pass the raw body data to the user, even when
- content-encoded (chunked, compressed) */
long new_file_perms; /* Permissions to use when creating remote files */
long new_directory_perms; /* Permissions to use when creating remote dirs */
- bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
- via an HTTP proxy */
+ long ssh_auth_types; /* allowed SSH auth types */
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
unsigned int scope_id; /* Scope id for IPv6 */
long allowed_protocols;
long redir_protocols;
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- bool socks5_gssapi_nec; /* Flag to support NEC SOCKS5 server */
-#endif
struct curl_slist *mail_rcpt; /* linked list of mail recipients */
- bool sasl_ir; /* Enable/disable SASL initial response */
/* Common RTSP header options */
Curl_RtspReq rtspreq; /* RTSP request type */
long rtspversion; /* like httpversion, for RTSP */
- bool wildcard_enabled; /* enable wildcard matching */
curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer
starts */
curl_chunk_end_callback chunk_end; /* called after part transferring
@@ -1722,47 +1644,102 @@ struct UserDefined {
long gssapi_delegation; /* GSS-API credential delegation, see the
documentation of CURLOPT_GSSAPI_DELEGATION */
- bool tcp_keepalive; /* use TCP keepalives */
long tcp_keepidle; /* seconds in idle before sending keepalive probe */
long tcp_keepintvl; /* seconds between TCP keepalive probes */
- bool tcp_fastopen; /* use TCP Fast Open */
- size_t maxconnects; /* Max idle connections in the connection cache */
+ size_t maxconnects; /* Max idle connections in the connection cache */
- bool ssl_enable_npn; /* TLS NPN extension? */
- bool ssl_enable_alpn; /* TLS ALPN extension? */
- bool path_as_is; /* allow dotdots? */
- bool pipewait; /* wait for pipe/multiplex status before starting a
- new connection */
long expect_100_timeout; /* in milliseconds */
- bool suppress_connect_headers; /* suppress proxy CONNECT response headers
- from user callbacks */
-
- bool dns_shuffle_addresses; /* whether to shuffle addresses before use */
-
struct Curl_easy *stream_depends_on;
- bool stream_depends_e; /* set or don't set the Exclusive bit */
int stream_weight;
-
- bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */
-
struct Curl_http2_dep *stream_dependents;
- bool abstract_unix_socket;
-
curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
void *resolver_start_client; /* pointer to pass to resolver start callback */
- bool disallow_username_in_url; /* disallow username in url */
long upkeep_interval_ms; /* Time between calls for connection upkeep. */
- bool doh; /* DNS-over-HTTPS enabled */
- bool doh_get; /* use GET for DoH requests, instead of POST */
- bool http09_allowed; /* allow HTTP/0.9 responses */
multidone_func fmultidone;
struct Curl_easy *dohfor; /* this is a DoH request for that transfer */
CURLU *uh; /* URL handle for the current parsed URL */
void *trailer_data; /* pointer to pass to trailer data callback */
curl_trailer_callback trailer_callback; /* trailing data callback */
+ bit is_fread_set:1; /* has read callback been set to non-NULL? */
+ bit is_fwrite_set:1; /* has write callback been set to non-NULL? */
+ bit free_referer:1; /* set TRUE if 'referer' points to a string we
+ allocated */
+ bit tftp_no_options:1; /* do not send TFTP options requests */
+ bit sep_headers:1; /* handle host and proxy headers separately */
+ bit cookiesession:1; /* new cookie session? */
+ bit crlf:1; /* convert crlf on ftp upload(?) */
+ bit strip_path_slash:1; /* strip off initial slash from path */
+ bit ssh_compression:1; /* enable SSH compression */
+
+/* Here follows boolean settings that define how to behave during
+ this session. They are STATIC, set by libcurl users or at least initially
+ and they don't change during operations. */
+ bit get_filetime:1; /* get the time and get of the remote file */
+ bit tunnel_thru_httpproxy:1; /* use CONNECT through a HTTP proxy */
+ bit prefer_ascii:1; /* ASCII rather than binary */
+ bit ftp_append:1; /* append, not overwrite, on upload */
+ bit ftp_list_only:1; /* switch FTP command for listing directories */
+ bit ftp_use_port:1; /* use the FTP PORT command */
+ bit hide_progress:1; /* don't use the progress meter */
+ bit http_fail_on_error:1; /* fail on HTTP error codes >= 400 */
+ bit http_keep_sending_on_error:1; /* for HTTP status codes >= 300 */
+ bit http_follow_location:1; /* follow HTTP redirects */
+ bit http_transfer_encoding:1; /* request compressed HTTP
+ transfer-encoding */
+ bit allow_auth_to_other_hosts:1;
+ bit include_header:1; /* include received protocol headers in data output */
+ bit http_set_referer:1; /* is a custom referer used */
+ bit http_auto_referer:1; /* set "correct" referer when following
+ location: */
+ bit opt_no_body:1; /* as set with CURLOPT_NOBODY */
+ bit upload:1; /* upload request */
+ bit verbose:1; /* output verbosity */
+ bit krb:1; /* Kerberos connection requested */
+ bit reuse_forbid:1; /* forbidden to be reused, close after use */
+ bit reuse_fresh:1; /* do not re-use an existing connection */
+ bit ftp_use_epsv:1; /* if EPSV is to be attempted or not */
+ bit ftp_use_eprt:1; /* if EPRT is to be attempted or not */
+ bit ftp_use_pret:1; /* if PRET is to be used before PASV or not */
+
+ bit no_signal:1; /* do not use any signal/alarm handler */
+ bit global_dns_cache:1; /* subject for future removal */
+ bit tcp_nodelay:1; /* whether to enable TCP_NODELAY or not */
+ bit ignorecl:1; /* ignore content length */
+ bit ftp_skip_ip:1; /* skip the IP address the FTP server passes on to
+ us */
+ bit connect_only:1; /* make connection, let application use the socket */
+ bit http_te_skip:1; /* pass the raw body data to the user, even when
+ transfer-encoded (chunked, compressed) */
+ bit http_ce_skip:1; /* pass the raw body data to the user, even when
+ content-encoded (chunked, compressed) */
+ bit proxy_transfer_mode:1; /* set transfer mode (;type=<a|i>) when doing
+ FTP via an HTTP proxy */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ bit socks5_gssapi_nec:1; /* Flag to support NEC SOCKS5 server */
+#endif
+ bit sasl_ir:1; /* Enable/disable SASL initial response */
+ bit wildcard_enabled:1; /* enable wildcard matching */
+ bit tcp_keepalive:1; /* use TCP keepalives */
+ bit tcp_fastopen:1; /* use TCP Fast Open */
+ bit ssl_enable_npn:1; /* TLS NPN extension? */
+ bit ssl_enable_alpn:1;/* TLS ALPN extension? */
+ bit path_as_is:1; /* allow dotdots? */
+ bit pipewait:1; /* wait for pipe/multiplex status before starting a
+ new connection */
+ bit suppress_connect_headers:1; /* suppress proxy CONNECT response headers
+ from user callbacks */
+ bit dns_shuffle_addresses:1; /* whether to shuffle addresses before use */
+ bit stream_depends_e:1; /* set or don't set the Exclusive bit */
+ bit haproxyprotocol:1; /* whether to send HAProxy PROXY protocol v1
+ header */
+ bit abstract_unix_socket:1;
+ bit disallow_username_in_url:1; /* disallow username in url */
+ bit doh:1; /* DNS-over-HTTPS enabled */
+ bit doh_get:1; /* use GET for DoH requests, instead of POST */
+ bit http09_allowed:1; /* allow HTTP/0.9 responses */
};
struct Names {
@@ -1827,6 +1804,9 @@ struct Curl_easy {
NOTE that the 'cookie' field in the
UserDefined struct defines if the "engine"
is to be used or not. */
+#ifdef USE_ALTSVC
+ struct altsvcinfo *asi; /* the alt-svc cache */
+#endif
struct Progress progress; /* for all the progress meter data */
struct UrlState state; /* struct for fields used for state info and
other dynamic purposes */
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index 8cf21264c..7d2b9ac31 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -273,6 +273,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
+ nego->state = GSS_AUTHNONE;
+ nego->noauthpersist = FALSE;
+ nego->havenoauthpersist = FALSE;
+ nego->havenegdata = FALSE;
+ nego->havemultiplerequests = FALSE;
}
#endif /* HAVE_GSSAPI && USE_SPNEGO */
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index aacc5d272..ddd983cf2 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -248,8 +248,9 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
free(chlg);
if(GSS_ERROR(nego->status)) {
+ char buffer[STRERROR_LEN];
failf(data, "InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(data->conn, nego->status));
+ Curl_sspi_strerror(nego->status, buffer, sizeof(buffer)));
return CURLE_OUT_OF_MEMORY;
}
@@ -342,6 +343,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
nego->token_max = 0;
+ nego->state = GSS_AUTHNONE;
+ nego->noauthpersist = FALSE;
+ nego->havenoauthpersist = FALSE;
+ nego->havenegdata = FALSE;
+ nego->havemultiplerequests = FALSE;
}
#endif /* USE_WINDOWS_SSPI && USE_SPNEGO */
diff --git a/lib/version.c b/lib/version.c
index 6aecdd260..020b2b018 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -212,6 +212,10 @@ char *curl_version(void)
}
#endif
+ /* Silent scan-build even if librtmp is not enabled. */
+ (void) left;
+ (void) ptr;
+
initialized = true;
return version;
}
@@ -366,6 +370,9 @@ static curl_version_info_data version_info = {
#if defined(HAVE_BROTLI)
| CURL_VERSION_BROTLI
#endif
+#if defined(USE_ALTSVC)
+ | CURL_VERSION_ALTSVC
+#endif
,
NULL, /* ssl_version */
0, /* ssl_version_num, this is kept at zero */
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index ea96cf65e..c7a3268ef 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -67,15 +67,6 @@ and that's a problem since options.h hasn't been included yet. */
#endif
#endif
-/* HAVE_SUPPORTED_CURVES is wolfSSL's build time symbol for enabling the ECC
- supported curve extension in options.h. Note ECC is enabled separately. */
-#ifndef HAVE_SUPPORTED_CURVES
-#if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \
- defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE)
-#define HAVE_SUPPORTED_CURVES
-#endif
-#endif
-
#include <limits.h>
#include "urldata.h"
@@ -364,16 +355,6 @@ cyassl_connect_step1(struct connectdata *conn,
}
#endif
-#ifdef HAVE_SUPPORTED_CURVES
- /* CyaSSL/wolfSSL does not send the supported ECC curves ext automatically:
- https://github.com/wolfSSL/wolfssl/issues/366
- The supported curves below are those also supported by OpenSSL 1.0.2 and
- in the same order. */
- CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x17); /* secp256r1 */
- CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x19); /* secp521r1 */
- CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x18); /* secp384r1 */
-#endif
-
/* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) {
CURLcode result = CURLE_OK;
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 9035ec483..e224861c4 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -1423,11 +1423,6 @@ gtls_connect_step3(struct connectdata *conn,
size = sizeof(certbuf);
gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
infof(data, "\t issuer: %s\n", certbuf);
-
- /* compression algorithm (if any) */
- ptr = gnutls_compression_get_name(gnutls_compression_get(session));
- /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
- infof(data, "\t compression: %s\n", ptr);
#endif
gnutls_x509_crt_deinit(x509_cert);
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index bb6a757bf..27a9402cb 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -716,6 +716,8 @@ mbed_connect_step3(struct connectdata *conn,
ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
if(ret) {
+ if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
+ mbedtls_ssl_session_free(our_ssl_sessionid);
free(our_ssl_sessionid);
failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
@@ -729,6 +731,7 @@ mbed_connect_step3(struct connectdata *conn,
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
Curl_ssl_sessionid_unlock(conn);
if(retcode) {
+ mbedtls_ssl_session_free(our_ssl_sessionid);
free(our_ssl_sessionid);
failf(data, "failed to store ssl session");
return retcode;
@@ -813,9 +816,14 @@ static void Curl_mbedtls_session_free(void *ptr)
static size_t Curl_mbedtls_version(char *buffer, size_t size)
{
+#ifdef MBEDTLS_VERSION_C
+ /* if mbedtls_version_get_number() is available it is better */
unsigned int version = mbedtls_version_get_number();
return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
(version>>16)&0xff, (version>>8)&0xff);
+#else
+ return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING);
+#endif
}
static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 9d11b89e5..eff5c2106 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -65,6 +65,10 @@
#include <openssl/buffer.h>
#include <openssl/pkcs12.h>
+#ifdef USE_AMISSL
+#include "amigaos.h"
+#endif
+
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP)
#include <openssl/ocsp.h>
#endif
@@ -820,8 +824,11 @@ int cert_stuff(struct connectdata *conn,
fail:
EVP_PKEY_free(pri);
X509_free(x509);
+#ifdef USE_AMISSL
+ sk_X509_pop_free(ca, Curl_amiga_X509_free);
+#else
sk_X509_pop_free(ca, X509_free);
-
+#endif
if(!cert_done)
return 0; /* failure! */
break;
@@ -831,15 +838,15 @@ int cert_stuff(struct connectdata *conn,
return 0;
}
- file_type = do_file_type(key_type);
+ if(!key_file)
+ key_file = cert_file;
+ else
+ file_type = do_file_type(key_type);
switch(file_type) {
case SSL_FILETYPE_PEM:
if(cert_done)
break;
- if(!key_file)
- /* cert & key can only be in PEM case in the same file */
- key_file = cert_file;
/* FALLTHROUGH */
case SSL_FILETYPE_ASN1:
if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
@@ -2808,6 +2815,12 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
connssl->connecting_state = ssl_connect_2_writing;
return CURLE_OK;
}
+#ifdef SSL_ERROR_WANT_ASYNC
+ if(SSL_ERROR_WANT_ASYNC == detail) {
+ connssl->connecting_state = ssl_connect_2;
+ return CURLE_OK;
+ }
+#endif
else {
/* untreated error */
unsigned long errdetail;
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index c8574f56c..39ac080e8 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -324,6 +324,9 @@ get_alg_id_by_name(char *name)
#ifdef CALG_ECDSA
CIPHEROPTION(CALG_ECDSA);
#endif
+#ifdef CALG_ECDH_EPHEM
+ CIPHEROPTION(CALG_ECDH_EPHEM);
+#endif
return 0;
}
@@ -433,8 +436,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
- infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
- hostname, conn->remote_port);
+ DEBUGF(infof(data,
+ "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+ hostname, conn->remote_port));
if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
@@ -494,12 +498,13 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
BACKEND->cred = old_cred;
- infof(data, "schannel: re-using existing credential handle\n");
+ DEBUGF(infof(data, "schannel: re-using existing credential handle\n"));
/* increment the reference counter of the credential/session handle */
BACKEND->cred->refcount++;
- infof(data, "schannel: incremented credential handle refcount = %d\n",
- BACKEND->cred->refcount);
+ DEBUGF(infof(data,
+ "schannel: incremented credential handle refcount = %d\n",
+ BACKEND->cred->refcount));
}
Curl_ssl_sessionid_unlock(conn);
}
@@ -522,26 +527,28 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
- infof(data, "schannel: disabled server certificate revocation "
- "checks\n");
+ DEBUGF(infof(data, "schannel: disabled server certificate revocation "
+ "checks\n"));
}
else {
schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
- infof(data, "schannel: checking server certificate revocation\n");
+ DEBUGF(infof(data,
+ "schannel: checking server certificate revocation\n"));
}
}
else {
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
- infof(data, "schannel: disabled server certificate revocation checks\n");
+ DEBUGF(infof(data,
+ "schannel: disabled server cert revocation checks\n"));
}
if(!conn->ssl_config.verifyhost) {
schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
- infof(data, "schannel: verifyhost setting prevents Schannel from "
- "comparing the supplied target name with the subject "
- "names in server certificates.\n");
+ DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
+ "comparing the supplied target name with the subject "
+ "names in server certificates.\n"));
}
switch(conn->ssl_config.version) {
@@ -680,8 +687,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
CertFreeCertificateContext(client_certs[0]);
if(sspi_status != SEC_E_OK) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
Curl_safefree(BACKEND->cred);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
@@ -796,15 +804,16 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
Curl_unicodefree(host_name);
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
+ char buffer[STRERROR_LEN];
Curl_safefree(BACKEND->ctxt);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_OUT_OF_MEMORY;
case SEC_E_WRONG_PRINCIPAL:
failf(data, "schannel: SNI or certificate check failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_PEER_FAILED_VERIFICATION;
/*
case SEC_E_INVALID_HANDLE:
@@ -819,13 +828,13 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
*/
default:
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_SSL_CONNECT_ERROR;
}
}
- infof(data, "schannel: sending initial handshake data: "
- "sending %lu bytes...\n", outbuf.cbBuffer);
+ DEBUGF(infof(data, "schannel: sending initial handshake data: "
+ "sending %lu bytes...\n", outbuf.cbBuffer));
/* send initial handshake data which is now stored in output buffer */
result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
@@ -837,8 +846,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR;
}
- infof(data, "schannel: sent initial handshake data: "
- "sent %zd bytes\n", written);
+ DEBUGF(infof(data, "schannel: sent initial handshake data: "
+ "sent %zd bytes\n", written));
BACKEND->recv_unrecoverable_err = CURLE_OK;
BACKEND->recv_sspi_close_notify = false;
@@ -874,8 +883,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
- infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
- hostname, conn->remote_port);
+ DEBUGF(infof(data,
+ "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+ hostname, conn->remote_port));
if(!BACKEND->cred || !BACKEND->ctxt)
return CURLE_SSL_CONNECT_ERROR;
@@ -934,8 +944,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
if(result == CURLE_AGAIN) {
if(connssl->connecting_state != ssl_connect_2_writing)
connssl->connecting_state = ssl_connect_2_reading;
- infof(data, "schannel: failed to receive handshake, "
- "need more data\n");
+ DEBUGF(infof(data, "schannel: failed to receive handshake, "
+ "need more data\n"));
return CURLE_OK;
}
else if((result != CURLE_OK) || (nread == 0)) {
@@ -947,11 +957,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* increase encrypted data buffer offset */
BACKEND->encdata_offset += nread;
BACKEND->encdata_is_incomplete = false;
- infof(data, "schannel: encrypted data got %zd\n", nread);
+ DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread));
}
- infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- BACKEND->encdata_offset, BACKEND->encdata_length);
+ DEBUGF(infof(data,
+ "schannel: encrypted data buffer: offset %zu length %zu\n",
+ BACKEND->encdata_offset, BACKEND->encdata_length));
/* setup input buffers */
InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
@@ -994,7 +1005,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
BACKEND->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
- infof(data, "schannel: received incomplete message, need more data\n");
+ DEBUGF(infof(data,
+ "schannel: received incomplete message, need more data\n"));
return CURLE_OK;
}
@@ -1005,7 +1017,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
!(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
connssl->connecting_state = ssl_connect_2_writing;
- infof(data, "schannel: a client certificate has been requested\n");
+ DEBUGF(infof(data,
+ "schannel: a client certificate has been requested\n"));
return CURLE_OK;
}
@@ -1014,8 +1027,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
for(i = 0; i < 3; i++) {
/* search for handshake tokens that need to be send */
if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
- infof(data, "schannel: sending next handshake data: "
- "sending %lu bytes...\n", outbuf[i].cbBuffer);
+ DEBUGF(infof(data, "schannel: sending next handshake data: "
+ "sending %lu bytes...\n", outbuf[i].cbBuffer));
/* send handshake token to server */
result = Curl_write_plain(conn, conn->sock[sockindex],
@@ -1036,14 +1049,15 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
}
}
else {
+ char buffer[STRERROR_LEN];
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
failf(data, "schannel: next InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_OUT_OF_MEMORY;
case SEC_E_WRONG_PRINCIPAL:
failf(data, "schannel: SNI or certificate check failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_PEER_FAILED_VERIFICATION;
/*
case SEC_E_INVALID_HANDLE:
@@ -1058,14 +1072,15 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
*/
default:
failf(data, "schannel: next InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_SSL_CONNECT_ERROR;
}
}
/* check if there was additional remaining encrypted data */
if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
- infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
+ DEBUGF(infof(data, "schannel: encrypted data length: %lu\n",
+ inbuf[1].cbBuffer));
/*
There are two cases where we could be getting extra data here:
1) If we're renegotiating a connection and the handshake is already
@@ -1104,7 +1119,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* check if the handshake is complete */
if(sspi_status == SEC_E_OK) {
connssl->connecting_state = ssl_connect_3;
- infof(data, "schannel: SSL/TLS handshake complete\n");
+ DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n"));
}
pubkey_ptr = SSL_IS_PROXY() ?
@@ -1190,7 +1205,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SECURITY_STATUS sspi_status = SEC_E_OK;
CERT_CONTEXT *ccert_context = NULL;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
+#ifdef DEBUGBUILD
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
#endif
@@ -1200,8 +1215,9 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
- hostname, conn->remote_port);
+ DEBUGF(infof(data,
+ "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+ hostname, conn->remote_port));
if(!BACKEND->cred)
return CURLE_SSL_CONNECT_ERROR;
@@ -1266,7 +1282,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
sockindex));
if(incache) {
if(old_cred != BACKEND->cred) {
- infof(data, "schannel: old credential handle is stale, removing\n");
+ DEBUGF(infof(data,
+ "schannel: old credential handle is stale, removing\n"));
/* we're not taking old_cred ownership here, no refcount++ is needed */
Curl_ssl_delsessionid(conn, (void *)old_cred);
incache = FALSE;
@@ -1284,7 +1301,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
else {
/* this cred session is now also referenced by sessionid cache */
BACKEND->cred->refcount++;
- infof(data, "schannel: stored credential handle in session cache\n");
+ DEBUGF(infof(data,
+ "schannel: stored credential handle in session cache\n"));
}
}
Curl_ssl_sessionid_unlock(conn);
@@ -1615,7 +1633,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
* handled in the cleanup.
*/
- infof(data, "schannel: client wants to read %zu bytes\n", len);
+ DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len));
*err = CURLE_OK;
if(len && len <= BACKEND->decdata_offset) {
@@ -1660,12 +1678,13 @@ schannel_recv(struct connectdata *conn, int sockindex,
BACKEND->encdata_buffer = reallocated_buffer;
BACKEND->encdata_length = reallocated_length;
size = BACKEND->encdata_length - BACKEND->encdata_offset;
- infof(data, "schannel: encdata_buffer resized %zu\n",
- BACKEND->encdata_length);
+ DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n",
+ BACKEND->encdata_length));
}
- infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- BACKEND->encdata_offset, BACKEND->encdata_length);
+ DEBUGF(infof(data,
+ "schannel: encrypted data buffer: offset %zu length %zu\n",
+ BACKEND->encdata_offset, BACKEND->encdata_length));
/* read encrypted data from socket */
*err = Curl_read_plain(conn->sock[sockindex],
@@ -1675,7 +1694,8 @@ schannel_recv(struct connectdata *conn, int sockindex,
if(*err) {
nread = -1;
if(*err == CURLE_AGAIN)
- infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n");
+ DEBUGF(infof(data,
+ "schannel: Curl_read_plain returned CURLE_AGAIN\n"));
else if(*err == CURLE_RECV_ERROR)
infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
else
@@ -1683,17 +1703,18 @@ schannel_recv(struct connectdata *conn, int sockindex,
}
else if(nread == 0) {
BACKEND->recv_connection_closed = true;
- infof(data, "schannel: server closed the connection\n");
+ DEBUGF(infof(data, "schannel: server closed the connection\n"));
}
else if(nread > 0) {
BACKEND->encdata_offset += (size_t)nread;
BACKEND->encdata_is_incomplete = false;
- infof(data, "schannel: encrypted data got %zd\n", nread);
+ DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread));
}
}
- infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- BACKEND->encdata_offset, BACKEND->encdata_length);
+ DEBUGF(infof(data,
+ "schannel: encrypted data buffer: offset %zu length %zu\n",
+ BACKEND->encdata_offset, BACKEND->encdata_length));
/* decrypt loop */
while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
@@ -1721,8 +1742,8 @@ schannel_recv(struct connectdata *conn, int sockindex,
/* check for successfully decrypted data, even before actual
renegotiation or shutdown of the connection context */
if(inbuf[1].BufferType == SECBUFFER_DATA) {
- infof(data, "schannel: decrypted data length: %lu\n",
- inbuf[1].cbBuffer);
+ DEBUGF(infof(data, "schannel: decrypted data length: %lu\n",
+ inbuf[1].cbBuffer));
/* increase buffer in order to fit the received amount of data */
size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
@@ -1754,15 +1775,16 @@ schannel_recv(struct connectdata *conn, int sockindex,
BACKEND->decdata_offset += size;
}
- infof(data, "schannel: decrypted data added: %zu\n", size);
- infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
- BACKEND->decdata_offset, BACKEND->decdata_length);
+ DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size));
+ DEBUGF(infof(data,
+ "schannel: decrypted cached: offset %zu length %zu\n",
+ BACKEND->decdata_offset, BACKEND->decdata_length));
}
/* check for remaining encrypted data */
if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
- infof(data, "schannel: encrypted data length: %lu\n",
- inbuf[3].cbBuffer);
+ DEBUGF(infof(data, "schannel: encrypted data length: %lu\n",
+ inbuf[3].cbBuffer));
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data
@@ -1776,8 +1798,9 @@ schannel_recv(struct connectdata *conn, int sockindex,
BACKEND->encdata_offset = inbuf[3].cbBuffer;
}
- infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
- BACKEND->encdata_offset, BACKEND->encdata_length);
+ DEBUGF(infof(data,
+ "schannel: encrypted cached: offset %zu length %zu\n",
+ BACKEND->encdata_offset, BACKEND->encdata_length));
}
else {
/* reset encrypted buffer offset, because there is no data remaining */
@@ -1831,22 +1854,25 @@ schannel_recv(struct connectdata *conn, int sockindex,
goto cleanup;
}
else {
+ char buffer[STRERROR_LEN];
*err = CURLE_RECV_ERROR;
infof(data, "schannel: failed to read data from server: %s\n",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
goto cleanup;
}
}
- infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- BACKEND->encdata_offset, BACKEND->encdata_length);
+ DEBUGF(infof(data,
+ "schannel: encrypted data buffer: offset %zu length %zu\n",
+ BACKEND->encdata_offset, BACKEND->encdata_length));
- infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
- BACKEND->decdata_offset, BACKEND->decdata_length);
+ DEBUGF(infof(data,
+ "schannel: decrypted data buffer: offset %zu length %zu\n",
+ BACKEND->decdata_offset, BACKEND->decdata_length));
cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
- infof(data, "schannel: schannel_recv cleanup\n");
+ DEBUGF(infof(data, "schannel: schannel_recv cleanup\n"));
/* Error if the connection has closed without a close_notify.
Behavior here is a matter of debate. We don't want to be vulnerable to a
@@ -1879,10 +1905,10 @@ cleanup:
memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
BACKEND->decdata_offset - size);
BACKEND->decdata_offset -= size;
-
- infof(data, "schannel: decrypted data returned %zu\n", size);
- infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
- BACKEND->decdata_offset, BACKEND->decdata_length);
+ DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size));
+ DEBUGF(infof(data,
+ "schannel: decrypted data buffer: offset %zu length %zu\n",
+ BACKEND->decdata_offset, BACKEND->decdata_length));
*err = CURLE_OK;
return (ssize_t)size;
}
@@ -1960,6 +1986,8 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+ DEBUGASSERT(data);
+
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
hostname, conn->remote_port);
@@ -1979,9 +2007,11 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
&BuffDesc);
- if(sspi_status != SEC_E_OK)
+ if(sspi_status != SEC_E_OK) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: ApplyControlToken failure: %s",
- Curl_sspi_strerror(conn, sspi_status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ }
host_name = Curl_convert_UTF8_to_tchar(hostname);
if(!host_name)
@@ -2023,7 +2053,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
/* free SSPI Schannel API security context handle */
if(BACKEND->ctxt) {
- infof(data, "schannel: clear security context handle\n");
+ DEBUGF(infof(data, "schannel: clear security context handle\n"));
s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
Curl_safefree(BACKEND->ctxt);
}
@@ -2035,11 +2065,9 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
* might not have an associated transfer so the check for conn->data is
* necessary.
*/
- if(conn->data)
- Curl_ssl_sessionid_lock(conn);
+ Curl_ssl_sessionid_lock(conn);
Curl_schannel_session_free(BACKEND->cred);
- if(conn->data)
- Curl_ssl_sessionid_unlock(conn);
+ Curl_ssl_sessionid_unlock(conn);
BACKEND->cred = NULL;
}
@@ -2101,7 +2129,7 @@ static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM,
static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
const char *pinnedpubkey)
{
- SECURITY_STATUS status;
+ SECURITY_STATUS sspi_status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CERT_CONTEXT *pCertContextServer = NULL;
@@ -2118,13 +2146,15 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
return CURLE_OK;
do {
- status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
- SECPKG_ATTR_REMOTE_CERT_CONTEXT,
- &pCertContextServer);
+ sspi_status =
+ s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+ &pCertContextServer);
- if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: Failed to read remote certificate context: %s",
- Curl_sspi_strerror(conn, status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
break; /* failed */
}
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index 680f6ec5d..5a09e969e 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -96,9 +96,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file);
if(!ca_file_tstr) {
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: invalid path name for CA file '%s': %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -116,17 +117,19 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(ca_file_handle == INVALID_HANDLE_VALUE) {
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to open CA file '%s': %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(!GetFileSizeEx(ca_file_handle, &file_size)) {
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to determine size of CA file '%s': %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -153,10 +156,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read,
bytes_to_read, &bytes_read, NULL)) {
-
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to read from CA file '%s': %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -215,11 +218,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
NULL,
NULL,
(const void **)&cert_context)) {
-
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to extract certificate from CA file "
"'%s': %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file,
+ Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
@@ -243,10 +247,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
NULL);
CertFreeCertificateContext(cert_context);
if(!add_cert_result) {
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to add certificate from CA file '%s' "
"to certificate store: %s",
- ca_file, Curl_strerror(conn, GetLastError()));
+ ca_file,
+ Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
@@ -408,7 +414,7 @@ cleanup:
CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
{
- SECURITY_STATUS status;
+ SECURITY_STATUS sspi_status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result = CURLE_OK;
@@ -420,13 +426,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
conn->http_proxy.host.name :
conn->host.name;
- status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
- SECPKG_ATTR_REMOTE_CERT_CONTEXT,
- &pCertContextServer);
+ sspi_status =
+ s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+ &pCertContextServer);
- if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: Failed to read remote certificate context: %s",
- Curl_sspi_strerror(conn, status));
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
result = CURLE_PEER_FAILED_VERIFICATION;
}
@@ -450,8 +458,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
CERT_STORE_CREATE_NEW_FLAG,
NULL);
if(!trust_store) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: failed to create certificate store: %s",
- Curl_strerror(conn, GetLastError()));
+ Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
}
else {
@@ -477,9 +486,10 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
CertCreateCertificateChainEngine(
(CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine);
if(!create_engine_result) {
+ char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to create certificate chain engine: %s",
- Curl_strerror(conn, GetLastError()));
+ Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
}
}
@@ -500,8 +510,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
+ char buffer[STRERROR_LEN];
failf(data, "schannel: CertGetCertificateChain failed: %s",
- Curl_sspi_strerror(conn, GetLastError()));
+ Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
pChainContext = NULL;
result = CURLE_PEER_FAILED_VERIFICATION;
}
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/sectransp.c
index bb251cdb3..971dd78e6 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/sectransp.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, 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
@@ -32,7 +32,7 @@
#include "curl_base64.h"
#include "strtok.h"
-#ifdef USE_DARWINSSL
+#ifdef USE_SECTRANSP
#ifdef __clang__
#pragma clang diagnostic push
@@ -59,7 +59,7 @@
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
-#error "The darwinssl back-end requires Leopard or later."
+#error "The Secure Transport back-end requires Leopard or later."
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
#define CURL_BUILD_IOS 0
@@ -105,7 +105,7 @@
#define CURL_SUPPORT_MAC_10_9 0
#else
-#error "The darwinssl back-end requires iOS or OS X."
+#error "The Secure Transport back-end requires iOS or macOS."
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#if CURL_BUILD_MAC
@@ -118,7 +118,7 @@
#include "connect.h"
#include "select.h"
#include "vtls.h"
-#include "darwinssl.h"
+#include "sectransp.h"
#include "curl_printf.h"
#include "strdup.h"
@@ -144,20 +144,20 @@ struct ssl_backend_data {
/* version 1 supports macOS 10.12+ and iOS 10+ */
#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
(!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
-#define DARWIN_SSL_PINNEDPUBKEY_V1 1
+#define SECTRANSP_PINNEDPUBKEY_V1 1
#endif
/* version 2 supports MacOSX 10.7+ */
#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
-#define DARWIN_SSL_PINNEDPUBKEY_V2 1
+#define SECTRANSP_PINNEDPUBKEY_V2 1
#endif
-#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
+#if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2)
/* this backend supports CURLOPT_PINNEDPUBLICKEY */
-#define DARWIN_SSL_PINNEDPUBKEY 1
-#endif /* DARWIN_SSL_PINNEDPUBKEY */
+#define SECTRANSP_PINNEDPUBKEY 1
+#endif /* SECTRANSP_PINNEDPUBKEY */
-#ifdef DARWIN_SSL_PINNEDPUBKEY
+#ifdef SECTRANSP_PINNEDPUBKEY
/* both new and old APIs return rsa keys missing the spki header (not DER) */
static const unsigned char rsa4096SpkiHeader[] = {
0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
@@ -170,7 +170,7 @@ static const unsigned char rsa2048SpkiHeader[] = {
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
-#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+#ifdef SECTRANSP_PINNEDPUBKEY_V1
/* the *new* version doesn't return DER encoded ecdsa certs like the old... */
static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
@@ -184,8 +184,8 @@ static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
0x00, 0x22, 0x03, 0x62, 0x00};
-#endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */
-#endif /* DARWIN_SSL_PINNEDPUBKEY */
+#endif /* SECTRANSP_PINNEDPUBKEY_V1 */
+#endif /* SECTRANSP_PINNEDPUBKEY */
/* The following two functions were ripped from Apple sample code,
* with some modifications: */
@@ -1242,7 +1242,7 @@ CF_INLINE bool is_file(const char *filename)
}
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
+static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
long ssl_version)
{
switch(ssl_version) {
@@ -1312,13 +1312,13 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
if(SSLSetProtocolVersionMax != NULL) {
SSLProtocol darwin_ver_min = kTLSProtocol1;
SSLProtocol darwin_ver_max = kTLSProtocol1;
- CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
+ CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
ssl_version);
if(result) {
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
return result;
}
- result = darwinssl_version_from_curl(&darwin_ver_max,
+ result = sectransp_version_from_curl(&darwin_ver_max,
ssl_version_max >> 16);
if(result) {
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
@@ -1361,12 +1361,12 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
- failf(data, "DarwinSSL: cannot set SSL protocol");
+ failf(data, "Secure Transport: cannot set SSL protocol");
return CURLE_SSL_CONNECT_ERROR;
}
-static CURLcode darwinssl_connect_step1(struct connectdata *conn,
+static CURLcode sectransp_connect_step1(struct connectdata *conn,
int sockindex)
{
struct Curl_easy *data = conn->data;
@@ -1577,7 +1577,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
if(conn->bits.tls_enable_alpn) {
- if(__builtin_available(macOS 10.13.4, iOS 11, *)) {
+ if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
&kCFTypeArrayCallBacks);
@@ -2234,7 +2234,7 @@ static int verify_cert(const char *cafile, struct Curl_easy *data,
}
}
-#ifdef DARWIN_SSL_PINNEDPUBKEY
+#ifdef SECTRANSP_PINNEDPUBKEY
static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
SSLContextRef ctx,
const char *pinnedpubkey)
@@ -2266,14 +2266,14 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
if(keyRef == NULL)
break;
-#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+#ifdef SECTRANSP_PINNEDPUBKEY_V1
publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
CFRelease(keyRef);
if(publicKeyBits == NULL)
break;
-#elif DARWIN_SSL_PINNEDPUBKEY_V2
+#elif SECTRANSP_PINNEDPUBKEY_V2
OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
&publicKeyBits);
@@ -2281,7 +2281,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
if(success != errSecSuccess || publicKeyBits == NULL)
break;
-#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
+#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
pubkeylen = CFDataGetLength(publicKeyBits);
pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
@@ -2295,7 +2295,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
/* 2048 bit RSA pubkeylen == 270 */
spkiHeader = rsa2048SpkiHeader;
break;
-#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+#ifdef SECTRANSP_PINNEDPUBKEY_V1
case 65:
/* ecDSA secp256r1 pubkeylen == 65 */
spkiHeader = ecDsaSecp256r1SpkiHeader;
@@ -2308,7 +2308,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
break;
default:
infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
-#elif DARWIN_SSL_PINNEDPUBKEY_V2
+#elif SECTRANSP_PINNEDPUBKEY_V2
default:
/* ecDSA secp256r1 pubkeylen == 91 header already included?
* ecDSA secp384r1 header already included too
@@ -2316,7 +2316,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
*/
result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
pubkeylen);
-#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
+#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
continue; /* break from loop */
}
@@ -2339,10 +2339,10 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
return result;
}
-#endif /* DARWIN_SSL_PINNEDPUBKEY */
+#endif /* SECTRANSP_PINNEDPUBKEY */
static CURLcode
-darwinssl_connect_step2(struct connectdata *conn, int sockindex)
+sectransp_connect_step2(struct connectdata *conn, int sockindex)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -2376,7 +2376,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
return res;
}
/* the documentation says we need to call SSLHandshake() again */
- return darwinssl_connect_step2(conn, sockindex);
+ return sectransp_connect_step2(conn, sockindex);
/* Problem with encrypt / decrypt */
case errSSLPeerDecodeError:
@@ -2578,7 +2578,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
/* we have been connected fine, we're not waiting for anything else. */
connssl->connecting_state = ssl_connect_3;
-#ifdef DARWIN_SSL_PINNEDPUBKEY
+#ifdef SECTRANSP_PINNEDPUBKEY
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
@@ -2587,7 +2587,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
return result;
}
}
-#endif /* DARWIN_SSL_PINNEDPUBKEY */
+#endif /* SECTRANSP_PINNEDPUBKEY */
/* Informational message */
(void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
@@ -2628,7 +2628,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
if(conn->bits.tls_enable_alpn) {
- if(__builtin_available(macOS 10.13.4, iOS 11, *)) {
+ if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFArrayRef alpnArr = NULL;
CFStringRef chosenProtocol = NULL;
err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr);
@@ -2771,7 +2771,7 @@ show_verbose_server_cert(struct connectdata *conn,
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
static CURLcode
-darwinssl_connect_step3(struct connectdata *conn,
+sectransp_connect_step3(struct connectdata *conn,
int sockindex)
{
struct Curl_easy *data = conn->data;
@@ -2789,11 +2789,11 @@ darwinssl_connect_step3(struct connectdata *conn,
return CURLE_OK;
}
-static Curl_recv darwinssl_recv;
-static Curl_send darwinssl_send;
+static Curl_recv sectransp_recv;
+static Curl_send sectransp_send;
static CURLcode
-darwinssl_connect_common(struct connectdata *conn,
+sectransp_connect_common(struct connectdata *conn,
int sockindex,
bool nonblocking,
bool *done)
@@ -2821,7 +2821,7 @@ darwinssl_connect_common(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
- result = darwinssl_connect_step1(conn, sockindex);
+ result = sectransp_connect_step1(conn, sockindex);
if(result)
return result;
}
@@ -2875,7 +2875,7 @@ darwinssl_connect_common(struct connectdata *conn,
* before step2 has completed while ensuring that a client using select()
* or epoll() will always have a valid fdset to wait on.
*/
- result = darwinssl_connect_step2(conn, sockindex);
+ result = sectransp_connect_step2(conn, sockindex);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -2886,15 +2886,15 @@ darwinssl_connect_common(struct connectdata *conn,
if(ssl_connect_3 == connssl->connecting_state) {
- result = darwinssl_connect_step3(conn, sockindex);
+ result = sectransp_connect_step3(conn, sockindex);
if(result)
return result;
}
if(ssl_connect_done == connssl->connecting_state) {
connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = darwinssl_recv;
- conn->send[sockindex] = darwinssl_send;
+ conn->recv[sockindex] = sectransp_recv;
+ conn->send[sockindex] = sectransp_send;
*done = TRUE;
}
else
@@ -2906,18 +2906,18 @@ darwinssl_connect_common(struct connectdata *conn,
return CURLE_OK;
}
-static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn,
int sockindex, bool *done)
{
- return darwinssl_connect_common(conn, sockindex, TRUE, done);
+ return sectransp_connect_common(conn, sockindex, TRUE, done);
}
-static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
+static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex)
{
CURLcode result;
bool done = FALSE;
- result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
+ result = sectransp_connect_common(conn, sockindex, FALSE, &done);
if(result)
return result;
@@ -2927,7 +2927,7 @@ static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
return CURLE_OK;
}
-static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+static void Curl_sectransp_close(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -2948,7 +2948,7 @@ static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
BACKEND->ssl_sockfd = 0;
}
-static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
@@ -2963,7 +2963,7 @@ static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
- Curl_darwinssl_close(conn, sockindex);
+ Curl_sectransp_close(conn, sockindex);
rc = 0;
@@ -3001,18 +3001,18 @@ static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
return rc;
}
-static void Curl_darwinssl_session_free(void *ptr)
+static void Curl_sectransp_session_free(void *ptr)
{
/* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
cached session ID inside the Security framework. There is a private
function that does this, but I don't want to have to explain to you why I
got your application rejected from the App Store due to the use of a
private API, so the best we can do is free up our own char array that we
- created way back in darwinssl_connect_step1... */
+ created way back in sectransp_connect_step1... */
Curl_safefree(ptr);
}
-static size_t Curl_darwinssl_version(char *buffer, size_t size)
+static size_t Curl_sectransp_version(char *buffer, size_t size)
{
return msnprintf(buffer, size, "SecureTransport");
}
@@ -3025,7 +3025,7 @@ static size_t Curl_darwinssl_version(char *buffer, size_t size)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-static int Curl_darwinssl_check_cxn(struct connectdata *conn)
+static int Curl_sectransp_check_cxn(struct connectdata *conn)
{
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
OSStatus err;
@@ -3040,7 +3040,7 @@ static int Curl_darwinssl_check_cxn(struct connectdata *conn)
return 0;
}
-static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+static bool Curl_sectransp_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
@@ -3057,7 +3057,7 @@ static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
return false;
}
-static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
+static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM,
unsigned char *entropy, size_t length)
{
/* arc4random_buf() isn't available on cats older than Lion, so let's
@@ -3077,7 +3077,7 @@ static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
return CURLE_OK;
}
-static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */
size_t tmplen,
unsigned char *md5sum, /* output */
size_t md5len)
@@ -3087,7 +3087,7 @@ static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
return CURLE_OK;
}
-static CURLcode Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
+static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */
size_t tmplen,
unsigned char *sha256sum, /* output */
size_t sha256len)
@@ -3097,7 +3097,7 @@ static CURLcode Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
return CURLE_OK;
}
-static bool Curl_darwinssl_false_start(void)
+static bool Curl_sectransp_false_start(void)
{
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
if(SSLSetSessionOption != NULL)
@@ -3106,7 +3106,7 @@ static bool Curl_darwinssl_false_start(void)
return FALSE;
}
-static ssize_t darwinssl_send(struct connectdata *conn,
+static ssize_t sectransp_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len,
@@ -3172,7 +3172,7 @@ static ssize_t darwinssl_send(struct connectdata *conn,
return (ssize_t)processed;
}
-static ssize_t darwinssl_recv(struct connectdata *conn,
+static ssize_t sectransp_recv(struct connectdata *conn,
int num,
char *buf,
size_t buffersize,
@@ -3212,48 +3212,48 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
return (ssize_t)processed;
}
-static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
+static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
return BACKEND->ssl_ctx;
}
-const struct Curl_ssl Curl_ssl_darwinssl = {
- { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
+const struct Curl_ssl Curl_ssl_sectransp = {
+ { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */
-#ifdef DARWIN_SSL_PINNEDPUBKEY
+#ifdef SECTRANSP_PINNEDPUBKEY
SSLSUPP_PINNEDPUBKEY,
#else
0,
-#endif /* DARWIN_SSL_PINNEDPUBKEY */
+#endif /* SECTRANSP_PINNEDPUBKEY */
sizeof(struct ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
- Curl_darwinssl_version, /* version */
- Curl_darwinssl_check_cxn, /* check_cxn */
- Curl_darwinssl_shutdown, /* shutdown */
- Curl_darwinssl_data_pending, /* data_pending */
- Curl_darwinssl_random, /* random */
+ Curl_sectransp_version, /* version */
+ Curl_sectransp_check_cxn, /* check_cxn */
+ Curl_sectransp_shutdown, /* shutdown */
+ Curl_sectransp_data_pending, /* data_pending */
+ Curl_sectransp_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
- Curl_darwinssl_connect, /* connect */
- Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
- Curl_darwinssl_get_internals, /* get_internals */
- Curl_darwinssl_close, /* close_one */
+ Curl_sectransp_connect, /* connect */
+ Curl_sectransp_connect_nonblocking, /* connect_nonblocking */
+ Curl_sectransp_get_internals, /* get_internals */
+ Curl_sectransp_close, /* close_one */
Curl_none_close_all, /* close_all */
- Curl_darwinssl_session_free, /* session_free */
+ Curl_sectransp_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
- Curl_darwinssl_false_start, /* false_start */
- Curl_darwinssl_md5sum, /* md5sum */
- Curl_darwinssl_sha256sum /* sha256sum */
+ Curl_sectransp_false_start, /* false_start */
+ Curl_sectransp_md5sum, /* md5sum */
+ Curl_sectransp_sha256sum /* sha256sum */
};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
-#endif /* USE_DARWINSSL */
+#endif /* USE_SECTRANSP */
diff --git a/lib/vtls/darwinssl.h b/lib/vtls/sectransp.h
index 23c7f705c..5cec797b3 100644
--- a/lib/vtls/darwinssl.h
+++ b/lib/vtls/sectransp.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_DARWINSSL_H
-#define HEADER_CURL_DARWINSSL_H
+#ifndef HEADER_CURL_SECTRANSP_H
+#define HEADER_CURL_SECTRANSP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -8,7 +8,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -24,9 +24,9 @@
***************************************************************************/
#include "curl_setup.h"
-#ifdef USE_DARWINSSL
+#ifdef USE_SECTRANSP
-extern const struct Curl_ssl Curl_ssl_darwinssl;
+extern const struct Curl_ssl Curl_ssl_sectransp;
-#endif /* USE_DARWINSSL */
-#endif /* HEADER_CURL_DARWINSSL_H */
+#endif /* USE_SECTRANSP */
+#endif /* HEADER_CURL_SECTRANSP_H */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 5e75f92e9..8a405c05c 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -248,7 +248,7 @@ Curl_ssl_connect(struct connectdata *conn, int sockindex)
conn->ssl[sockindex].use = TRUE;
conn->ssl[sockindex].state = ssl_connection_negotiating;
- result = Curl_ssl->connect(conn, sockindex);
+ result = Curl_ssl->connect_blocking(conn, sockindex);
if(!result)
Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
@@ -513,7 +513,7 @@ void Curl_ssl_close_all(struct Curl_easy *data)
}
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
+ defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \
defined(USE_MBEDTLS) || defined(USE_CYASSL)
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks)
@@ -546,7 +546,7 @@ int Curl_ssl_getsock(struct connectdata *conn,
(void)numsocks;
return GETSOCK_BLANK;
}
-/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
+/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */
#endif
void Curl_ssl_close(struct connectdata *conn, int sockindex)
@@ -557,7 +557,7 @@ void Curl_ssl_close(struct connectdata *conn, int sockindex)
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
{
- if(Curl_ssl->shutdown(conn, sockindex))
+ if(Curl_ssl->shut_down(conn, sockindex))
return CURLE_SSL_SHUTDOWN_FAILED;
conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
@@ -1114,7 +1114,7 @@ static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex)
{
if(multissl_init(NULL))
return CURLE_FAILED_INIT;
- return Curl_ssl->connect(conn, sockindex);
+ return Curl_ssl->connect_blocking(conn, sockindex);
}
static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn,
@@ -1172,8 +1172,8 @@ const struct Curl_ssl *Curl_ssl =
&Curl_ssl_multi;
#elif defined(USE_CYASSL)
&Curl_ssl_cyassl;
-#elif defined(USE_DARWINSSL)
- &Curl_ssl_darwinssl;
+#elif defined(USE_SECTRANSP)
+ &Curl_ssl_sectransp;
#elif defined(USE_GNUTLS)
&Curl_ssl_gnutls;
#elif defined(USE_GSKIT)
@@ -1198,8 +1198,8 @@ static const struct Curl_ssl *available_backends[] = {
#if defined(USE_CYASSL)
&Curl_ssl_cyassl,
#endif
-#if defined(USE_DARWINSSL)
- &Curl_ssl_darwinssl,
+#if defined(USE_SECTRANSP)
+ &Curl_ssl_sectransp,
#endif
#if defined(USE_GNUTLS)
&Curl_ssl_gnutls,
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 1f163631f..2a87ca1f7 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -47,7 +47,7 @@ struct Curl_ssl {
size_t (*version)(char *buffer, size_t size);
int (*check_cxn)(struct connectdata *cxn);
- int (*shutdown)(struct connectdata *conn, int sockindex);
+ int (*shut_down)(struct connectdata *conn, int sockindex);
bool (*data_pending)(const struct connectdata *conn,
int connindex);
@@ -56,7 +56,7 @@ struct Curl_ssl {
size_t length);
bool (*cert_status_request)(void);
- CURLcode (*connect)(struct connectdata *conn, int sockindex);
+ CURLcode (*connect_blocking)(struct connectdata *conn, int sockindex);
CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex,
bool *done);
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
@@ -105,7 +105,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
#include "polarssl.h" /* PolarSSL versions */
#include "cyassl.h" /* CyaSSL versions */
#include "schannel.h" /* Schannel SSPI version */
-#include "darwinssl.h" /* SecureTransport (Darwin) version */
+#include "sectransp.h" /* SecureTransport (Darwin) version */
#include "mbedtls.h" /* mbedTLS versions */
#include "mesalink.h" /* MesaLink versions */
diff --git a/lib/warnless.c b/lib/warnless.c
index 05d9038dc..cfd5e8e14 100644
--- a/lib/warnless.c
+++ b/lib/warnless.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -401,44 +401,6 @@ unsigned short curlx_uitous(unsigned int uinum)
}
/*
-** unsigned int to unsigned char
-*/
-
-unsigned char curlx_uitouc(unsigned int uinum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_UCHAR);
- return (unsigned char) (uinum & (unsigned int) CURL_MASK_UCHAR);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-/*
-** unsigned int to signed int
-*/
-
-int curlx_uitosi(unsigned int uinum)
-{
-#ifdef __INTEL_COMPILER
-# pragma warning(push)
-# pragma warning(disable:810) /* conversion may lose significant bits */
-#endif
-
- DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_SINT);
- return (int) (uinum & (unsigned int) CURL_MASK_SINT);
-
-#ifdef __INTEL_COMPILER
-# pragma warning(pop)
-#endif
-}
-
-/*
** signed int to unsigned size_t
*/
diff --git a/lib/warnless.h b/lib/warnless.h
index 6d515962e..08792c2e1 100644
--- a/lib/warnless.h
+++ b/lib/warnless.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -57,10 +57,6 @@ int curlx_sztosi(ssize_t sznum);
unsigned short curlx_uitous(unsigned int uinum);
-unsigned char curlx_uitouc(unsigned int uinum);
-
-int curlx_uitosi(unsigned int uinum);
-
size_t curlx_sitouz(int sinum);
#ifdef USE_WINSOCK
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index 68abe5b3b..ceab1bcf9 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -120,7 +120,7 @@ static const char *getASN1Element(curl_asn1Element *elem,
if an error occurs. */
if(!beg || !end || beg >= end || !*beg ||
(size_t)(end - beg) > CURL_ASN1_MAX)
- return (const char *) NULL;
+ return NULL;
/* Process header byte. */
elem->header = beg;
@@ -129,12 +129,12 @@ static const char *getASN1Element(curl_asn1Element *elem,
elem->class = (b >> 6) & 3;
b &= 0x1F;
if(b == 0x1F)
- return (const char *) NULL; /* Long tag values not supported here. */
+ return NULL; /* Long tag values not supported here. */
elem->tag = b;
/* Process length. */
if(beg >= end)
- return (const char *) NULL;
+ return NULL;
b = (unsigned char) *beg++;
if(!(b & 0x80))
len = b;
@@ -142,69 +142,72 @@ static const char *getASN1Element(curl_asn1Element *elem,
/* Unspecified length. Since we have all the data, we can determine the
effective length by skipping element until an end element is found. */
if(!elem->constructed)
- return (const char *) NULL;
+ return NULL;
elem->beg = beg;
while(beg < end && *beg) {
beg = getASN1Element(&lelem, beg, end);
if(!beg)
- return (const char *) NULL;
+ return NULL;
}
if(beg >= end)
- return (const char *) NULL;
+ return NULL;
elem->end = beg;
return beg + 1;
}
else if((unsigned)b > (size_t)(end - beg))
- return (const char *) NULL; /* Does not fit in source. */
+ return NULL; /* Does not fit in source. */
else {
/* Get long length. */
len = 0;
do {
if(len & 0xFF000000L)
- return (const char *) NULL; /* Lengths > 32 bits are not supported. */
+ return NULL; /* Lengths > 32 bits are not supported. */
len = (len << 8) | (unsigned char) *beg++;
} while(--b);
}
if(len > (size_t)(end - beg))
- return (const char *) NULL; /* Element data does not fit in source. */
+ return NULL; /* Element data does not fit in source. */
elem->beg = beg;
elem->end = beg + len;
return elem->end;
}
+/*
+ * Search the null terminated OID or OID identifier in local table.
+ * Return the table entry pointer or NULL if not found.
+ */
static const curl_OID * searchOID(const char *oid)
{
const curl_OID *op;
-
- /* Search the null terminated OID or OID identifier in local table.
- Return the table entry pointer or NULL if not found. */
-
for(op = OIDtable; op->numoid; op++)
if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
return op;
- return (const curl_OID *) NULL;
+ return NULL;
}
+/*
+ * Convert an ASN.1 Boolean value into its string representation. Return the
+ * dynamically allocated string, or NULL if source is not an ASN.1 Boolean
+ * value.
+ */
+
static const char *bool2str(const char *beg, const char *end)
{
- /* Convert an ASN.1 Boolean value into its string representation.
- Return the dynamically allocated string, or NULL if source is not an
- ASN.1 Boolean value. */
-
if(end - beg != 1)
- return (const char *) NULL;
+ return NULL;
return strdup(*beg? "TRUE": "FALSE");
}
+/*
+ * Convert an ASN.1 octet string to a printable string.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
static const char *octet2str(const char *beg, const char *end)
{
size_t n = end - beg;
char *buf = NULL;
- /* Convert an ASN.1 octet string to a printable string.
- Return the dynamically allocated string, or NULL if an error occurs. */
-
if(n <= (SIZE_T_MAX - 1) / 3) {
buf = malloc(3 * n + 1);
if(buf)
@@ -220,21 +223,22 @@ static const char *bit2str(const char *beg, const char *end)
Return the dynamically allocated string, or NULL if an error occurs. */
if(++beg > end)
- return (const char *) NULL;
+ return NULL;
return octet2str(beg, end);
}
+/*
+ * Convert an ASN.1 integer value into its string representation.
+ * Return the dynamically allocated string, or NULL if source is not an
+ * ASN.1 integer value.
+ */
static const char *int2str(const char *beg, const char *end)
{
unsigned long val = 0;
size_t n = end - beg;
- /* Convert an ASN.1 integer value into its string representation.
- Return the dynamically allocated string, or NULL if source is not an
- ASN.1 integer value. */
-
if(!n)
- return (const char *) NULL;
+ return NULL;
if(n > 4)
return octet2str(beg, end);
@@ -249,6 +253,13 @@ static const char *int2str(const char *beg, const char *end)
return curl_maprintf("%s%lx", val >= 10? "0x": "", val);
}
+/*
+ * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
+ * destination buffer dynamically. The allocation size will normally be too
+ * large: this is to avoid buffer overflows.
+ * Terminate the string with a nul byte and return the converted
+ * string length.
+ */
static ssize_t
utf8asn1str(char **to, int type, const char *from, const char *end)
{
@@ -259,13 +270,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
unsigned int wc;
char *buf;
- /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
- destination buffer dynamically. The allocation size will normally be too
- large: this is to avoid buffer overflows.
- Terminate the string with a nul byte and return the converted
- string length. */
-
- *to = (char *) NULL;
+ *to = NULL;
switch(type) {
case CURL_ASN1_BMP_STRING:
size = 2;
@@ -341,96 +346,105 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
return outlength;
}
+/*
+ * Convert an ASN.1 String into its UTF-8 string representation.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
static const char *string2str(int type, const char *beg, const char *end)
{
char *buf;
-
- /* Convert an ASN.1 String into its UTF-8 string representation.
- Return the dynamically allocated string, or NULL if an error occurs. */
-
if(utf8asn1str(&buf, type, beg, end) < 0)
- return (const char *) NULL;
+ return NULL;
return buf;
}
-static int encodeUint(char *buf, int n, unsigned int x)
+/*
+ * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at
+ * buf. Return the total number of encoded digits, even if larger than
+ * `buflen'.
+ */
+static size_t encodeUint(char *buf, size_t buflen, unsigned int x)
{
- int i = 0;
+ size_t i = 0;
unsigned int y = x / 10;
- /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'.
- Return the total number of encoded digits, even if larger than `n'. */
-
if(y) {
- i += encodeUint(buf, n, y);
+ i = encodeUint(buf, buflen, y);
x -= y * 10;
}
- if(i < n)
+ if(i < buflen)
buf[i] = (char) ('0' + x);
i++;
- if(i < n)
+ if(i < buflen)
buf[i] = '\0'; /* Store a terminator if possible. */
return i;
}
-static int encodeOID(char *buf, int n, const char *beg, const char *end)
+/*
+ * Convert an ASN.1 OID into its dotted string representation.
+ * Store the result in th `n'-byte buffer at `buf'.
+ * Return the converted string length, or 0 on errors.
+ */
+static size_t encodeOID(char *buf, size_t buflen,
+ const char *beg, const char *end)
{
- int i = 0;
+ size_t i;
unsigned int x;
unsigned int y;
- /* Convert an ASN.1 OID into its dotted string representation.
- Store the result in th `n'-byte buffer at `buf'.
- Return the converted string length, or -1 if an error occurs. */
-
/* Process the first two numbers. */
y = *(const unsigned char *) beg++;
x = y / 40;
y -= x * 40;
- i += encodeUint(buf + i, n - i, x);
- if(i < n)
+ i = encodeUint(buf, buflen, x);
+ if(i < buflen)
buf[i] = '.';
i++;
- i += encodeUint(buf + i, n - i, y);
+ if(i >= buflen)
+ i += encodeUint(NULL, 0, y);
+ else
+ i += encodeUint(buf + i, buflen - i, y);
/* Process the trailing numbers. */
while(beg < end) {
- if(i < n)
+ if(i < buflen)
buf[i] = '.';
i++;
x = 0;
do {
if(x & 0xFF000000)
- return -1;
+ return 0;
y = *(const unsigned char *) beg++;
x = (x << 7) | (y & 0x7F);
} while(y & 0x80);
- i += encodeUint(buf + i, n - i, x);
+ if(i >= buflen)
+ i += encodeUint(NULL, 0, x);
+ else
+ i += encodeUint(buf + i, buflen - i, x);
}
- if(i < n)
+ if(i < buflen)
buf[i] = '\0';
return i;
}
+/*
+ * Convert an ASN.1 OID into its dotted or symbolic string representation.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
+
static const char *OID2str(const char *beg, const char *end, bool symbolic)
{
- char *buf = (char *) NULL;
- const curl_OID * op;
- int n;
-
- /* Convert an ASN.1 OID into its dotted or symbolic string representation.
- Return the dynamically allocated string, or NULL if an error occurs. */
-
+ char *buf = NULL;
if(beg < end) {
- n = encodeOID((char *) NULL, -1, beg, end);
- if(n >= 0) {
- buf = malloc(n + 1);
+ size_t buflen = encodeOID(NULL, 0, beg, end);
+ if(buflen) {
+ buf = malloc(buflen + 1); /* one extra for the zero byte */
if(buf) {
- encodeOID(buf, n, beg, end);
- buf[n] = '\0';
+ encodeOID(buf, buflen, beg, end);
+ buf[buflen] = '\0';
if(symbolic) {
- op = searchOID(buf);
+ const curl_OID *op = searchOID(buf);
if(op) {
free(buf);
buf = strdup(op->textoid);
@@ -470,7 +484,7 @@ static const char *GTime2str(const char *beg, const char *end)
sec2 = fracp[-1];
break;
default:
- return (const char *) NULL;
+ return NULL;
}
/* Scan for timezone, measure fractional seconds. */
@@ -506,15 +520,16 @@ static const char *GTime2str(const char *beg, const char *end)
sep, tzl, tzp);
}
+/*
+ * Convert an ASN.1 UTC time to a printable string.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
static const char *UTime2str(const char *beg, const char *end)
{
const char *tzp;
size_t tzl;
const char *sec;
- /* Convert an ASN.1 UTC time to a printable string.
- Return the dynamically allocated string, or NULL if an error occurs. */
-
for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
;
/* Get the seconds. */
@@ -525,12 +540,12 @@ static const char *UTime2str(const char *beg, const char *end)
case 2:
break;
default:
- return (const char *) NULL;
+ return NULL;
}
/* Process timezone. */
if(tzp >= end)
- return (const char *) NULL;
+ return NULL;
if(*tzp == 'Z') {
tzp = "GMT";
end = tzp + 3;
@@ -545,13 +560,14 @@ static const char *UTime2str(const char *beg, const char *end)
tzl, tzp);
}
+/*
+ * Convert an ASN.1 element to a printable string.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
static const char *ASN1tostr(curl_asn1Element *elem, int type)
{
- /* Convert an ASN.1 element to a printable string.
- Return the dynamically allocated string, or NULL if an error occurs. */
-
if(elem->constructed)
- return (const char *) NULL; /* No conversion of structured elements. */
+ return NULL; /* No conversion of structured elements. */
if(!type)
type = elem->tag; /* Type not forced: use element tag as type. */
@@ -585,10 +601,14 @@ static const char *ASN1tostr(curl_asn1Element *elem, int type)
return string2str(type, elem->beg, elem->end);
}
- return (const char *) NULL; /* Unsupported. */
+ return NULL; /* Unsupported. */
}
-static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
+/*
+ * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
+ * `buf'. Return the total string length, even if larger than `buflen'.
+ */
+static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
{
curl_asn1Element rdn;
curl_asn1Element atv;
@@ -600,9 +620,6 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
const char *p3;
const char *str;
- /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'.
- Return the total string length, even if larger than `n'. */
-
for(p1 = dn->beg; p1 < dn->end;) {
p1 = getASN1Element(&rdn, p1, dn->end);
if(!p1)
@@ -626,7 +643,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
for(p3 = str; isupper(*p3); p3++)
;
for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
- if(l < n)
+ if(l < buflen)
buf[l] = *p3;
l++;
}
@@ -634,14 +651,14 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
/* Encode attribute name. */
for(p3 = str; *p3; p3++) {
- if(l < n)
+ if(l < buflen)
buf[l] = *p3;
l++;
}
free((char *) str);
/* Generate equal sign. */
- if(l < n)
+ if(l < buflen)
buf[l] = '=';
l++;
@@ -650,7 +667,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
if(!str)
return -1;
for(p3 = str; *p3; p3++) {
- if(l < n)
+ if(l < buflen)
buf[l] = *p3;
l++;
}
@@ -661,28 +678,30 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
return l;
}
+/*
+ * Convert an ASN.1 distinguished name into a printable string.
+ * Return the dynamically allocated string, or NULL if an error occurs.
+ */
static const char *DNtostr(curl_asn1Element *dn)
{
- char *buf = (char *) NULL;
- ssize_t n = encodeDN(buf, 0, dn);
-
- /* Convert an ASN.1 distinguished name into a printable string.
- Return the dynamically allocated string, or NULL if an error occurs. */
+ char *buf = NULL;
+ ssize_t buflen = encodeDN(NULL, 0, dn);
- if(n >= 0) {
- buf = malloc(n + 1);
+ if(buflen >= 0) {
+ buf = malloc(buflen + 1);
if(buf) {
- encodeDN(buf, n + 1, dn);
- buf[n] = '\0';
+ encodeDN(buf, buflen + 1, dn);
+ buf[buflen] = '\0';
}
}
- return (const char *) buf;
+ return buf;
}
/*
- * X509 parser.
+ * ASN.1 parse an X509 certificate into structure subfields.
+ * Syntax is assumed to have already been checked by the SSL backend.
+ * See RFC 5280.
*/
-
int Curl_parseX509(curl_X509certificate *cert,
const char *beg, const char *end)
{
@@ -691,10 +710,6 @@ int Curl_parseX509(curl_X509certificate *cert,
const char *ccp;
static const char defaultVersion = 0; /* v1. */
- /* ASN.1 parse an X509 certificate into structure subfields.
- Syntax is assumed to have already been checked by the SSL backend.
- See RFC 5280. */
-
cert->certificate.header = NULL;
cert->certificate.beg = beg;
cert->certificate.end = end;
@@ -801,13 +816,14 @@ int Curl_parseX509(curl_X509certificate *cert,
return 0;
}
+
+/*
+ * Copy at most 64-characters, terminate with a newline and returns the
+ * effective number of stored characters.
+ */
static size_t copySubstring(char *to, const char *from)
{
size_t i;
-
- /* Copy at most 64-characters, terminate with a newline and returns the
- effective number of stored characters. */
-
for(i = 0; i < 64; i++) {
to[i] = *from;
if(!*from++)
@@ -1104,15 +1120,15 @@ static const char *checkOID(const char *beg, const char *end,
ccp = getASN1Element(&e, beg, end);
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
- return (const char *) NULL;
+ return NULL;
p = OID2str(e.beg, e.end, FALSE);
if(!p)
- return (const char *) NULL;
+ return NULL;
matched = !strcmp(p, oid);
free((char *) p);
- return matched? ccp: (const char *) NULL;
+ return matched? ccp: NULL;
}
CURLcode Curl_verifyhost(struct connectdata *conn,
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index 9f230b3f8..8249108bb 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -545,6 +545,25 @@ curl_includes_ws2tcpip="\
])
+dnl CURL_INCLUDES_BSDSOCKET
+dnl -------------------------------------------------
+dnl Set up variable with list of headers that must be
+dnl included when bsdsocket.h is to be included.
+
+AC_DEFUN([CURL_INCLUDES_BSDSOCKET], [
+curl_includes_bsdsocket="\
+/* includes start */
+#ifdef HAVE_PROTO_BSDSOCKET_H
+# include <proto/bsdsocket.h>
+ struct Library *SocketBase = NULL;
+#endif
+/* includes end */"
+ AC_CHECK_HEADERS(
+ proto/bsdsocket.h,
+ [], [], [ $curl_includes_bsdsocket])
+])
+
+
dnl CURL_PREPROCESS_CALLCONV
dnl -------------------------------------------------
dnl Set up variable with a preprocessor block which
@@ -759,6 +778,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOSESOCKET], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_socket
]],[[
if(0 != closesocket(0))
@@ -776,6 +796,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOSESOCKET], [
AC_MSG_CHECKING([if closesocket is prototyped])
AC_EGREP_CPP([closesocket],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_socket
],[
AC_MSG_RESULT([yes])
@@ -791,6 +812,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOSESOCKET], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_socket
]],[[
if(0 != closesocket(0))
@@ -944,6 +966,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CONNECT], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
]],[[
@@ -962,6 +985,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CONNECT], [
AC_MSG_CHECKING([if connect is prototyped])
AC_EGREP_CPP([connect],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
],[
@@ -978,6 +1002,7 @@ AC_DEFUN([CURL_CHECK_FUNC_CONNECT], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
]],[[
@@ -1168,92 +1193,6 @@ AC_DEFUN([CURL_CHECK_FUNC_FCNTL_O_NONBLOCK], [
fi
])
-
-dnl CURL_CHECK_FUNC_FDOPEN
-dnl -------------------------------------------------
-dnl Verify if fdopen is available, prototyped, and
-dnl can be compiled. If all of these are true, and
-dnl usage has not been previously disallowed with
-dnl shell variable curl_disallow_fdopen, then
-dnl HAVE_FDOPEN will be defined.
-
-AC_DEFUN([CURL_CHECK_FUNC_FDOPEN], [
- AC_REQUIRE([CURL_INCLUDES_STDIO])dnl
- #
- tst_links_fdopen="unknown"
- tst_proto_fdopen="unknown"
- tst_compi_fdopen="unknown"
- tst_allow_fdopen="unknown"
- #
- AC_MSG_CHECKING([if fdopen can be linked])
- AC_LINK_IFELSE([
- AC_LANG_FUNC_LINK_TRY([fdopen])
- ],[
- AC_MSG_RESULT([yes])
- tst_links_fdopen="yes"
- ],[
- AC_MSG_RESULT([no])
- tst_links_fdopen="no"
- ])
- #
- if test "$tst_links_fdopen" = "yes"; then
- AC_MSG_CHECKING([if fdopen is prototyped])
- AC_EGREP_CPP([fdopen],[
- $curl_includes_stdio
- ],[
- AC_MSG_RESULT([yes])
- tst_proto_fdopen="yes"
- ],[
- AC_MSG_RESULT([no])
- tst_proto_fdopen="no"
- ])
- fi
- #
- if test "$tst_proto_fdopen" = "yes"; then
- AC_MSG_CHECKING([if fdopen is compilable])
- AC_COMPILE_IFELSE([
- AC_LANG_PROGRAM([[
- $curl_includes_stdio
- ]],[[
- if(0 != fdopen(0, 0))
- return 1;
- ]])
- ],[
- AC_MSG_RESULT([yes])
- tst_compi_fdopen="yes"
- ],[
- AC_MSG_RESULT([no])
- tst_compi_fdopen="no"
- ])
- fi
- #
- if test "$tst_compi_fdopen" = "yes"; then
- AC_MSG_CHECKING([if fdopen usage allowed])
- if test "x$curl_disallow_fdopen" != "xyes"; then
- AC_MSG_RESULT([yes])
- tst_allow_fdopen="yes"
- else
- AC_MSG_RESULT([no])
- tst_allow_fdopen="no"
- fi
- fi
- #
- AC_MSG_CHECKING([if fdopen might be used])
- if test "$tst_links_fdopen" = "yes" &&
- test "$tst_proto_fdopen" = "yes" &&
- test "$tst_compi_fdopen" = "yes" &&
- test "$tst_allow_fdopen" = "yes"; then
- AC_MSG_RESULT([yes])
- AC_DEFINE_UNQUOTED(HAVE_FDOPEN, 1,
- [Define to 1 if you have the fdopen function.])
- curl_cv_func_fdopen="yes"
- else
- AC_MSG_RESULT([no])
- curl_cv_func_fdopen="no"
- fi
-])
-
-
dnl CURL_CHECK_FUNC_FGETXATTR
dnl -------------------------------------------------
dnl Verify if fgetxattr is available, prototyped, and
@@ -2292,6 +2231,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYADDR], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gethostbyaddr(0, 0, 0))
@@ -2309,6 +2249,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYADDR], [
AC_MSG_CHECKING([if gethostbyaddr is prototyped])
AC_EGREP_CPP([gethostbyaddr],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
],[
AC_MSG_RESULT([yes])
@@ -2324,6 +2265,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYADDR], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gethostbyaddr(0, 0, 0))
@@ -2385,6 +2327,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GAI_STRERROR], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gai_strerror(0))
@@ -2402,6 +2345,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GAI_STRERROR], [
AC_MSG_CHECKING([if gai_strerror is prototyped])
AC_EGREP_CPP([gai_strerror],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
],[
AC_MSG_RESULT([yes])
@@ -2417,6 +2361,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GAI_STRERROR], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gai_strerror(0))
@@ -2621,6 +2566,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYNAME], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gethostbyname(0))
@@ -2638,6 +2584,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYNAME], [
AC_MSG_CHECKING([if gethostbyname is prototyped])
AC_EGREP_CPP([gethostbyname],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
],[
AC_MSG_RESULT([yes])
@@ -2653,6 +2600,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTBYNAME], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_netdb
]],[[
if(0 != gethostbyname(0))
@@ -2848,6 +2796,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTNAME], [
AC_REQUIRE([CURL_INCLUDES_WINSOCK2])dnl
AC_REQUIRE([CURL_INCLUDES_UNISTD])dnl
AC_REQUIRE([CURL_PREPROCESS_CALLCONV])dnl
+ AC_REQUIRE([CURL_INCLUDES_BSDSOCKET])dnl
#
tst_links_gethostname="unknown"
tst_proto_gethostname="unknown"
@@ -2858,6 +2807,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTNAME], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_unistd
]],[[
if(0 != gethostname(0, 0))
@@ -2875,6 +2825,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTNAME], [
AC_MSG_CHECKING([if gethostname is prototyped])
AC_EGREP_CPP([gethostname],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_unistd
],[
AC_MSG_RESULT([yes])
@@ -2890,6 +2841,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTNAME], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_unistd
]],[[
if(0 != gethostname(0, 0))
@@ -2913,6 +2865,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETHOSTNAME], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_unistd
$curl_preprocess_callconv
extern int FUNCALLCONV gethostname($tst_arg1, $tst_arg2);
@@ -4109,6 +4062,7 @@ AC_DEFUN([CURL_CHECK_FUNC_IOCTLSOCKET], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
]],[[
if(0 != ioctlsocket(0, 0, 0))
return 1;
@@ -4125,6 +4079,7 @@ AC_DEFUN([CURL_CHECK_FUNC_IOCTLSOCKET], [
AC_MSG_CHECKING([if ioctlsocket is prototyped])
AC_EGREP_CPP([ioctlsocket],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
],[
AC_MSG_RESULT([yes])
tst_proto_ioctlsocket="yes"
@@ -4139,6 +4094,7 @@ AC_DEFUN([CURL_CHECK_FUNC_IOCTLSOCKET], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
]],[[
if(0 != ioctlsocket(0, 0, 0))
return 1;
@@ -4197,6 +4153,7 @@ AC_DEFUN([CURL_CHECK_FUNC_IOCTLSOCKET_FIONBIO], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
]],[[
int flags = 0;
if(0 != ioctlsocket(0, FIONBIO, &flags))
@@ -5011,6 +4968,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SETSOCKOPT], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
]],[[
if(0 != setsockopt(0, 0, 0, 0, 0))
@@ -5028,6 +4986,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SETSOCKOPT], [
AC_MSG_CHECKING([if setsockopt is prototyped])
AC_EGREP_CPP([setsockopt],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
],[
AC_MSG_RESULT([yes])
@@ -5043,6 +5002,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SETSOCKOPT], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
]],[[
if(0 != setsockopt(0, 0, 0, 0, 0))
@@ -5102,6 +5062,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SETSOCKOPT_SO_NONBLOCK], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
]],[[
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
@@ -5647,6 +5608,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SOCKET], [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
]],[[
@@ -5665,6 +5627,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SOCKET], [
AC_MSG_CHECKING([if socket is prototyped])
AC_EGREP_CPP([socket],[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
],[
@@ -5681,6 +5644,7 @@ AC_DEFUN([CURL_CHECK_FUNC_SOCKET], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_winsock2
+ $curl_includes_bsdsocket
$curl_includes_sys_socket
$curl_includes_socket
]],[[
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index 796086af2..132d1b92f 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -64,6 +64,7 @@ _ curl_easy_setopt_ccsid()
Variable arguments are a string pointer and a CCSID (unsigned int) for
options:
CURLOPT_ABSTRACT_UNIX_SOCKET
+ CURLOPT_ALTSVC
CURLOPT_CAINFO
CURLOPT_CAPATH
CURLOPT_COOKIE
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index 7ce61aa9f..a4cae27ee 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -1132,7 +1132,12 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
if(testwarn) {
testwarn = 0;
- if((int) STRING_LASTZEROTERMINATED != (int) STRING_DOH + 1 ||
+ if(
+#ifdef USE_ALTSVC
+ (int) STRING_LASTZEROTERMINATED != (int) STRING_ALTSVC + 1 ||
+#else
+ (int) STRING_LASTZEROTERMINATED != (int) STRING_DOH + 1 ||
+#endif
(int) STRING_LAST != (int) STRING_COPYPOSTFIELDS + 1)
curl_mfprintf(stderr,
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
@@ -1144,6 +1149,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
switch (tag) {
case CURLOPT_ABSTRACT_UNIX_SOCKET:
+ case CURLOPT_ALTSVC:
case CURLOPT_CAINFO:
case CURLOPT_CAPATH:
case CURLOPT_COOKIE:
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index 643f480c5..72a769f1d 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -134,6 +134,10 @@
d c X'00200000'
d CURL_VERSION_MULTI_SSL...
d c X'00400000'
+ d CURL_VERSION_BROTLI...
+ d c X'00800000'
+ d CURL_VERSION_ALTSVC...
+ d c X'01000000'
*
d CURL_HTTPPOST_FILENAME...
d c X'00000001'
@@ -814,6 +818,19 @@
d CURLHEADER_SEPARATE...
d c X'00000001'
*
+ d CURLALTSVC_IMMEDIATELY...
+ d c X'00000001'
+ d CURLALTSVC_ALTUSED...
+ d c X'00000002'
+ d CURLALTSVC_READONLYFILE...
+ d c X'00000004'
+ d CURLALTSVC_H1...
+ d c X'00000008'
+ d CURLALTSVC_H2...
+ d c X'00000010'
+ d CURLALTSVC_H3...
+ d c X'00000020'
+ *
d CURLPROTO_HTTP...
d c X'00000001'
d CURLPROTO_HTTPS...
@@ -1395,6 +1412,10 @@
d c 10284
d CURLOPT_HTTP09_ALLOWED...
d c 00285
+ d CURLOPT_ALTSVC_CTRL...
+ d c 00286
+ d CURLOPT_ALTSVC...
+ d c 10287
*
/if not defined(CURL_NO_OLDIES)
d CURLOPT_FILE c 10001
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 38824ed00..ec4747705 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -20,20 +20,30 @@
#
###########################################################################
ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@
+FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@
PERL = @PERL@
ZSH_COMPLETION_FUNCTION_FILENAME = _gnurl
+FISH_COMPLETION_FUNCTION_FILENAME = gnurl.fish
-CLEANFILES = $(ZSH_COMPLETION_FUNCTION_FILENAME)
+CLEANFILES = $(ZSH_COMPLETION_FUNCTION_FILENAME) $(FISH_COMPLETION_FUNCTION_FILENAME)
-all-local: $(ZSH_COMPLETION_FUNCTION_FILENAME)
+all-local: $(ZSH_COMPLETION_FUNCTION_FILENAME) $(FISH_COMPLETION_FUNCTION_FILENAME)
-$(ZSH_COMPLETION_FUNCTION_FILENAME): zsh.pl
+$(ZSH_COMPLETION_FUNCTION_FILENAME): completion.pl
if CROSSCOMPILING
@echo "NOTICE: we can't generate zsh completion when cross-compiling!"
else # if not cross-compiling:
- @if ! test -x "$(PERL)"; then echo "No perl: can't install zsh.pl"; exit 0; fi
- $(PERL) $(srcdir)/zsh.pl $(top_builddir)/src/gnurl$(EXEEXT) > $@
+ @if ! test -x "$(PERL)"; then echo "No perl: can't install completion.pl"; exit 0; fi
+ $(PERL) $(srcdir)/completion.pl --curl $(top_builddir)/src/gnurl$(EXEEXT) --shell zsh > $@
+endif
+
+$(FISH_COMPLETION_FUNCTION_FILENAME): completion.pl
+if CROSSCOMPILING
+ @echo "NOTICE: we can't generate fish completion when cross-compiling!"
+else # if not cross-compiling:
+ @if ! test -x "$(PERL)"; then echo "No perl: can't install completion.pl"; exit 0; fi
+ $(PERL) $(srcdir)/completion.pl --curl $(top_builddir)/src/gnurl$(EXEEXT) --shell fish > $@
endif
install-data-local:
@@ -41,5 +51,7 @@ if CROSSCOMPILING
@echo "NOTICE: we can't install zsh completion when cross-compiling!"
else # if not cross-compiling:
$(MKDIR_P) $(DESTDIR)$(ZSH_FUNCTIONS_DIR)
+ $(MKDIR_P) $(DESTDIR)$(FISH_FUNCTIONS_DIR)
$(INSTALL_DATA) $(ZSH_COMPLETION_FUNCTION_FILENAME) $(DESTDIR)$(ZSH_FUNCTIONS_DIR)/$(ZSH_COMPLETION_FUNCTION_FILENAME)
+ $(INSTALL_DATA) $(FISH_COMPLETION_FUNCTION_FILENAME) $(DESTDIR)$(FISH_FUNCTIONS_DIR)/$(FISH_COMPLETION_FUNCTION_FILENAME)
endif
diff --git a/scripts/completion.pl b/scripts/completion.pl
new file mode 100755
index 000000000..1c41755b4
--- /dev/null
+++ b/scripts/completion.pl
@@ -0,0 +1,134 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Getopt::Long();
+use Pod::Usage();
+
+my $curl = 'curl';
+my $shell = 'zsh';
+my $help = 0;
+Getopt::Long::GetOptions(
+ 'curl=s' => \$curl,
+ 'shell=s' => \$shell,
+ 'help' => \$help,
+) or Pod::Usage::pod2usage();
+Pod::Usage::pod2usage() if $help;
+
+my $regex = '\s+(?:(-[^\s]+),\s)?(--[^\s]+)\s*(\<.+?\>)?\s+(.*)';
+my @opts = parse_main_opts('--help', $regex);
+
+if ($shell eq 'fish') {
+ print "# curl fish completion\n\n";
+ print qq{$_ \n} foreach (@opts);
+} elsif ($shell eq 'zsh') {
+ my $opts_str;
+
+ $opts_str .= qq{ $_ \\\n} foreach (@opts);
+ chomp $opts_str;
+
+my $tmpl = <<"EOS";
+#compdef curl
+
+# curl zsh completion
+
+local curcontext="\$curcontext" state state_descr line
+typeset -A opt_args
+
+local rc=1
+
+_arguments -C -S \\
+$opts_str
+ '*:URL:_urls' && rc=0
+
+return rc
+EOS
+
+ print $tmpl;
+} else {
+ die("Unsupported shell: $shell");
+}
+
+sub parse_main_opts {
+ my ($cmd, $regex) = @_;
+
+ my @list;
+ my @lines = call_curl($cmd);
+
+ foreach my $line (@lines) {
+ my ($short, $long, $arg, $desc) = ($line =~ /^$regex/) or next;
+
+ my $option = '';
+
+ $arg =~ s/\:/\\\:/g if defined $arg;
+
+ $desc =~ s/'/'\\''/g if defined $desc;
+ $desc =~ s/\[/\\\[/g if defined $desc;
+ $desc =~ s/\]/\\\]/g if defined $desc;
+ $desc =~ s/\:/\\\:/g if defined $desc;
+
+ if ($shell eq 'fish') {
+ $option .= "complete --command curl";
+ $option .= " --short-option '" . strip_dash(trim($short)) . "'"
+ if defined $short;
+ $option .= " --long-option '" . strip_dash(trim($long)) . "'"
+ if defined $long;
+ $option .= " --description '" . strip_dash(trim($desc)) . "'"
+ if defined $desc;
+ } elsif ($shell eq 'zsh') {
+ $option .= '{' . trim($short) . ',' if defined $short;
+ $option .= trim($long) if defined $long;
+ $option .= '}' if defined $short;
+ $option .= '\'[' . trim($desc) . ']\'' if defined $desc;
+
+ $option .= ":'$arg'" if defined $arg;
+
+ $option .= ':_files'
+ if defined $arg and ($arg eq '<file>' || $arg eq '<filename>'
+ || $arg eq '<dir>');
+ }
+
+ push @list, $option;
+ }
+
+ # Sort longest first, because zsh won't complete an option listed
+ # after one that's a prefix of it.
+ @list = sort {
+ $a =~ /([^=]*)/; my $ma = $1;
+ $b =~ /([^=]*)/; my $mb = $1;
+
+ length($mb) <=> length($ma)
+ } @list if $shell eq 'zsh';
+
+ return @list;
+}
+
+sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
+sub strip_dash { my $s = shift; $s =~ s/^-+//g; return $s };
+
+sub call_curl {
+ my ($cmd) = @_;
+ my $output = `"$curl" $cmd`;
+ if ($? == -1) {
+ die "Could not run curl: $!";
+ } elsif ((my $exit_code = $? >> 8) != 0) {
+ die "curl returned $exit_code with output:\n$output";
+ }
+ return split /\n/, $output;
+}
+
+__END__
+
+=head1 NAME
+
+completion.pl - Generates tab-completion files for various shells
+
+=head1 SYNOPSIS
+
+completion.pl [options...]
+
+ --curl path to curl executable
+ --shell zsh/fish
+ --help prints this help
+
+=cut
diff --git a/scripts/singleuse.pl b/scripts/singleuse.pl
new file mode 100755
index 000000000..148aebe9d
--- /dev/null
+++ b/scripts/singleuse.pl
@@ -0,0 +1,210 @@
+#!/usr/bin/perl
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2019, 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 https://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.
+#
+###########################################################################
+#
+# This script is aimed to help scan for and detect globally declared functions
+# that are not used from other source files.
+#
+# Use it like this:
+#
+# $ ./scripts/singleuse.pl lib/.libs/libcurl.a
+#
+# Be aware that it might cause false positives due to various build options.
+#
+
+my $file = $ARGV[0];
+
+my %wl = (
+ 'Curl_none_cert_status_request' => 'multiple TLS backends',
+ 'Curl_none_check_cxn' => 'multiple TLS backends',
+ 'Curl_none_cleanup' => 'multiple TLS backends',
+ 'Curl_none_close_all' => 'multiple TLS backends',
+ 'Curl_none_data_pending' => 'multiple TLS backends',
+ 'Curl_none_engines_list' => 'multiple TLS backends',
+ 'Curl_none_init' => 'multiple TLS backends',
+ 'Curl_none_md5sum' => 'multiple TLS backends',
+ 'Curl_none_random' => 'multiple TLS backends',
+ 'Curl_none_session_free' => 'multiple TLS backends',
+ 'Curl_none_set_engine' => 'multiple TLS backends',
+ 'Curl_none_set_engine_default' => 'multiple TLS backends',
+ 'Curl_none_shutdown' => 'multiple TLS backends',
+ 'Curl_multi_dump' => 'debug build only',
+ 'Curl_parse_port' => 'UNITTEST',
+ 'Curl_shuffle_addr' => 'UNITTEST',
+ 'de_cleanup' => 'UNITTEST',
+ 'doh_decode' => 'UNITTEST',
+ 'doh_encode' => 'UNITTEST',
+ 'Curl_auth_digest_get_pair' => 'by digest_sspi',
+ 'curlx_uztoso' => 'cmdline tool use',
+ 'curlx_uztoul' => 'by krb5_sspi',
+ 'curlx_uitous' => 'by schannel',
+ 'Curl_islower' => 'by curl_fnmatch',
+ 'getaddressinfo' => 'UNITTEST',
+ );
+
+my %api = (
+ 'curl_easy_cleanup' => 'API',
+ 'curl_easy_duphandle' => 'API',
+ 'curl_easy_escape' => 'API',
+ 'curl_easy_getinfo' => 'API',
+ 'curl_easy_init' => 'API',
+ 'curl_easy_pause' => 'API',
+ 'curl_easy_perform' => 'API',
+ 'curl_easy_recv' => 'API',
+ 'curl_easy_reset' => 'API',
+ 'curl_easy_send' => 'API',
+ 'curl_easy_setopt' => 'API',
+ 'curl_easy_strerror' => 'API',
+ 'curl_easy_unescape' => 'API',
+ 'curl_easy_upkeep' => 'API',
+ 'curl_escape' => 'API',
+ 'curl_formadd' => 'API',
+ 'curl_formfree' => 'API',
+ 'curl_formget' => 'API',
+ 'curl_free' => 'API',
+ 'curl_getdate' => 'API',
+ 'curl_getenv' => 'API',
+ 'curl_global_cleanup' => 'API',
+ 'curl_global_init' => 'API',
+ 'curl_global_init_mem' => 'API',
+ 'curl_global_sslset' => 'API',
+ 'curl_maprintf' => 'API',
+ 'curl_mfprintf' => 'API',
+ 'curl_mime_addpart' => 'API',
+ 'curl_mime_data' => 'API',
+ 'curl_mime_data_cb' => 'API',
+ 'curl_mime_encoder' => 'API',
+ 'curl_mime_filedata' => 'API',
+ 'curl_mime_filename' => 'API',
+ 'curl_mime_free' => 'API',
+ 'curl_mime_headers' => 'API',
+ 'curl_mime_init' => 'API',
+ 'curl_mime_name' => 'API',
+ 'curl_mime_subparts' => 'API',
+ 'curl_mime_type' => 'API',
+ 'curl_mprintf' => 'API',
+ 'curl_msnprintf' => 'API',
+ 'curl_msprintf' => 'API',
+ 'curl_multi_add_handle' => 'API',
+ 'curl_multi_assign' => 'API',
+ 'curl_multi_cleanup' => 'API',
+ 'curl_multi_fdset' => 'API',
+ 'curl_multi_info_read' => 'API',
+ 'curl_multi_init' => 'API',
+ 'curl_multi_perform' => 'API',
+ 'curl_multi_remove_handle' => 'API',
+ 'curl_multi_setopt' => 'API',
+ 'curl_multi_socket' => 'API',
+ 'curl_multi_socket_action' => 'API',
+ 'curl_multi_socket_all' => 'API',
+ 'curl_multi_strerror' => 'API',
+ 'curl_multi_timeout' => 'API',
+ 'curl_multi_wait' => 'API',
+ 'curl_mvaprintf' => 'API',
+ 'curl_mvfprintf' => 'API',
+ 'curl_mvprintf' => 'API',
+ 'curl_mvsnprintf' => 'API',
+ 'curl_mvsprintf' => 'API',
+ 'curl_pushheader_byname' => 'API',
+ 'curl_pushheader_bynum' => 'API',
+ 'curl_share_cleanup' => 'API',
+ 'curl_share_init' => 'API',
+ 'curl_share_setopt' => 'API',
+ 'curl_share_strerror' => 'API',
+ 'curl_slist_append' => 'API',
+ 'curl_slist_free_all' => 'API',
+ 'curl_strequal' => 'API',
+ 'curl_strnequal' => 'API',
+ 'curl_unescape' => 'API',
+ 'curl_url' => 'API',
+ 'curl_url_cleanup' => 'API',
+ 'curl_url_dup' => 'API',
+ 'curl_url_get' => 'API',
+ 'curl_url_set' => 'API',
+ 'curl_version' => 'API',
+ 'curl_version_info' => 'API',
+
+ # the following funcions are provided globally in debug builds
+ 'curl_easy_perform_ev' => 'debug-build',
+ );
+
+open(N, "nm $file|") ||
+ die;
+
+my %exist;
+my %uses;
+my $file;
+while (<N>) {
+ my $l = $_;
+ chomp $l;
+
+ if($l =~ /^([0-9a-z_-]+)\.o:/) {
+ $file = $1;
+ }
+ if($l =~ /^([0-9a-f]+) T (.*)/) {
+ my ($name)=($2);
+ #print "Define $name in $file\n";
+ $file =~ s/^libcurl_la-//;
+ $exist{$name} = $file;
+ }
+ elsif($l =~ /^ U (.*)/) {
+ my ($name)=($1);
+ #print "Uses $name in $file\n";
+ $uses{$name} .= "$file, ";
+ }
+}
+close(N);
+
+my $err;
+for(sort keys %exist) {
+ #printf "%s is defined in %s, used by: %s\n", $_, $exist{$_}, $uses{$_};
+ if(!$uses{$_}) {
+ # this is a symbol with no "global" user
+ if($_ =~ /^curl_/) {
+ if(!$api{$_}) {
+ # not present in the API, or for debug-builds
+ print STDERR "Bad curl-prefix: $_\n";
+ $err++;
+ }
+ }
+ elsif($_ =~ /^curl_dbg_/) {
+ # we ignore the memdebug symbols
+ }
+ elsif($wl{$_}) {
+ #print "$_ is WL\n";
+ }
+ else {
+ printf "%s is defined in %s, but not used outside\n", $_, $exist{$_};
+ $err++;
+ }
+ }
+ elsif($_ =~ /^curl_/) {
+ # global prefix, make sure it is "blessed"
+ if(!$api{$_}) {
+ # not present in the API, or for debug-builds
+ print STDERR "Bad curl-prefix $_\n";
+ $err++;
+ }
+ }
+}
+
+exit $err;
diff --git a/scripts/zsh.pl b/scripts/zsh.pl
deleted file mode 100755
index bbb9ecb6c..000000000
--- a/scripts/zsh.pl
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env perl
-
-# Generate ZSH completion
-
-use strict;
-use warnings;
-
-my $gnurl = $ARGV[0] || 'gnurl';
-
-my $regex = '\s+(?:(-[^\s]+),\s)?(--[^\s]+)\s([^\s.]+)?\s+(.*)';
-my @opts = parse_main_opts('--help', $regex);
-
-my $opts_str;
-
-$opts_str .= qq{ $_ \\\n} foreach (@opts);
-chomp $opts_str;
-
-my $tmpl = <<"EOS";
-#compdef gnurl
-
-# gnurl zsh completion
-
-local curcontext="\$curcontext" state state_descr line
-typeset -A opt_args
-
-local rc=1
-
-_arguments -C -S \\
-$opts_str
- '*:URL:_urls' && rc=0
-
-return rc
-EOS
-
-print $tmpl;
-
-sub parse_main_opts {
- my ($cmd, $regex) = @_;
-
- my @list;
- my @lines = call_curl($cmd);
-
- foreach my $line (@lines) {
- my ($short, $long, $arg, $desc) = ($line =~ /^$regex/) or next;
-
- my $option = '';
-
- $desc =~ s/'/'\\''/g if defined $desc;
- $desc =~ s/\[/\\\[/g if defined $desc;
- $desc =~ s/\]/\\\]/g if defined $desc;
-
- $option .= '{' . trim($short) . ',' if defined $short;
- $option .= trim($long) if defined $long;
- $option .= '}' if defined $short;
- $option .= '\'[' . trim($desc) . ']\'' if defined $desc;
-
- $option .= ":'$arg'" if defined $arg;
-
- $option .= ':_files'
- if defined $arg and ($arg eq '<file>' || $arg eq '<filename>'
- || $arg eq '<dir>');
-
- push @list, $option;
- }
-
- # Sort longest first, because zsh won't complete an option listed
- # after one that's a prefix of it.
- @list = sort {
- $a =~ /([^=]*)/; my $ma = $1;
- $b =~ /([^=]*)/; my $mb = $1;
-
- length($mb) <=> length($ma)
- } @list;
-
- return @list;
-}
-
-sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
-
-sub call_curl {
- my ($cmd) = @_;
- my $output = `"$gnurl" $cmd`;
- if ($? == -1) {
- die "Could not run gnurl: $!";
- } elsif ((my $exit_code = $? >> 8) != 0) {
- die "gnurl returned $exit_code with output:\n$output";
- }
- return split /\n/, $output;
-}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c259473e4..c8119eaa4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,16 +9,13 @@ if(USE_MANUAL)
COMMAND ${CMAKE_COMMAND} -E echo "#ifndef HAVE_LIBZ" >> tool_hugehelp.c
COMMAND env LC_ALL=C "${NROFF}" ${NROFF_MANOPT}
"${CURL_BINARY_DIR}/docs/curl.1" |
- "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl"
- "${CURL_SOURCE_DIR}/docs/MANUAL" >> tool_hugehelp.c
+ "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" >> tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#else" >> tool_hugehelp.c
COMMAND env LC_ALL=C "${NROFF}" ${NROFF_MANOPT}
"${CURL_BINARY_DIR}/docs/curl.1" |
- "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c
- "${CURL_SOURCE_DIR}/docs/MANUAL" >> tool_hugehelp.c
+ "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c >> tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#endif /* HAVE_LIBZ */" >> tool_hugehelp.c
DEPENDS
- "${CURL_SOURCE_DIR}/docs/MANUAL"
generate-curl.1
"${CURL_BINARY_DIR}/docs/curl.1"
"${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl"
diff --git a/src/Makefile.am b/src/Makefile.am
index 46a075249..d5020093f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -91,10 +91,19 @@ EXTRA_DIST = mkhelp.pl makefile.dj \
# Use absolute directory to disable VPATH
MANPAGE=$(abs_top_builddir)/docs/gnurl.1
-README=$(top_srcdir)/docs/MANUAL
MKHELP=$(top_srcdir)/src/mkhelp.pl
HUGE=tool_hugehelp.c
+HUGECMD = $(HUGEIT_$(V))
+HUGEIT_0 = @echo " HUGE " $@;
+HUGEIT_1 =
+HUGEIT_ = $(HUGEIT_0)
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
if USE_MANUAL
# Here are the stuff to create a built-in manual
@@ -104,33 +113,33 @@ $(MANPAGE):
if HAVE_LIBZ
# This generates the tool_hugehelp.c file in both uncompressed and
# compressed formats.
-$(HUGE): $(MANPAGE) $(README) $(MKHELP)
- echo '#include "tool_setup.h"' > $(HUGE)
- echo '#ifndef HAVE_LIBZ' >> $(HUGE)
- $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) $(README) >> $(HUGE)
- echo '#else' >> $(HUGE)
- $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) -c $(README) >> $(HUGE)
- echo '#endif /* HAVE_LIBZ */' >> $(HUGE)
+$(HUGE): $(MANPAGE) $(MKHELP)
+ $(HUGECMD) (echo '#include "tool_setup.h"' > $(HUGE); \
+ echo '#ifndef HAVE_LIBZ' >> $(HUGE); \
+ $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) >> $(HUGE); \
+ echo '#else' >> $(HUGE); \
+ $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) -c >> $(HUGE); \
+ echo '#endif /* HAVE_LIBZ */' >> $(HUGE) )
else # HAVE_LIBZ
# This generates the tool_hugehelp.c file uncompressed only
-$(HUGE): $(MANPAGE) $(README) $(MKHELP)
- echo '#include "tool_setup.h"' > $(HUGE)
- $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) $(README) >> $(HUGE)
+$(HUGE): $(MANPAGE) $(MKHELP)
+ $(HUGECMD)(echo '#include "tool_setup.h"' > $(HUGE): \
+ $(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) >> $(HUGE) )
endif
else # USE_MANUAL
# built-in manual has been disabled, make a blank file
$(HUGE):
- echo "/* built-in manual is disabled, blank function */" > $(HUGE)
- echo '#include "tool_hugehelp.h"' >> $(HUGE)
- echo "void hugehelp(void) {}" >>$(HUGE)
+ $(HUGECMD)(echo "/* built-in manual is disabled, blank function */" > $(HUGE); \
+ echo '#include "tool_hugehelp.h"' >> $(HUGE); \
+ echo "void hugehelp(void) {}" >>$(HUGE) )
endif
# ignore tool_hugehelp.c since it is generated source code and it plays
# by slightly different rules!
checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl -D$(srcdir) \
- -W$(srcdir)/tool_hugehelp.c $(srcdir)/*.[ch]
+ $(CHECKSRC)(@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(srcdir) \
+ -W$(srcdir)/tool_hugehelp.c $(srcdir)/*.[ch])
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
diff --git a/src/mkhelp.pl b/src/mkhelp.pl
index 757f024ce..5e62b4ebb 100755
--- a/src/mkhelp.pl
+++ b/src/mkhelp.pl
@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -33,14 +33,6 @@ if($ARGV[0] eq "-c") {
shift @ARGV;
}
-my $README = $ARGV[0];
-
-if($README eq "") {
- print "usage: mkhelp.pl [-c] <README> < manpage\n";
- exit;
-}
-
-
push @out, " _ _ ____ _\n";
push @out, " Project ___| | | | _ \\| |\n";
push @out, " / __| | | | |_) | |\n";
@@ -89,19 +81,6 @@ while (<STDIN>) {
}
push @out, "\n"; # just an extra newline
-open(READ, "<$README") ||
- die "couldn't read the README infile $README";
-
-while(<READ>) {
- my $line = $_;
-
- # remove trailing CR from line. msysgit checks out files as line+CRLF
- $line =~ s/\r$//;
-
- push @out, $line;
-}
-close(READ);
-
print <<HEAD
/*
* NEVER EVER edit this manually, fix the mkhelp.pl script instead!
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index 195d6e79c..1944f16c2 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -79,6 +79,9 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
struct OperationConfig *config = outs->config;
size_t bytes = sz * nmemb;
bool is_tty = config->global->isatty;
+#ifdef WIN32
+ CONSOLE_SCREEN_BUFFER_INFO console_info;
+#endif
/*
* Once that libcurl has called back tool_write_cb() the returned value
@@ -156,7 +159,9 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
}
#ifdef _WIN32
- if(isatty(fileno(outs->stream))) {
+ if(isatty(fileno(outs->stream)) &&
+ GetConsoleScreenBufferInfo(
+ (HANDLE)_get_osfhandle(fileno(outs->stream)), &console_info)) {
DWORD in_len = (DWORD)(sz * nmemb);
wchar_t* wc_buf;
DWORD wc_len;
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
index 0eb941ef6..fabd6d635 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -53,6 +53,7 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->random_file);
Curl_safefree(config->egd_file);
Curl_safefree(config->useragent);
+ Curl_safefree(config->altsvc);
Curl_safefree(config->cookie);
Curl_safefree(config->cookiejar);
Curl_safefree(config->cookiefile);
@@ -144,10 +145,10 @@ static void free_config_fields(struct OperationConfig *config)
curl_slist_free_all(config->headers);
curl_slist_free_all(config->proxyheaders);
- if(config->mimepost) {
- curl_mime_free(config->mimepost);
- config->mimepost = NULL;
- }
+ curl_mime_free(config->mimepost);
+ config->mimepost = NULL;
+ tool_mime_free(config->mimeroot);
+ config->mimeroot = NULL;
config->mimecurrent = NULL;
curl_slist_free_all(config->telnet_options);
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 81680dbbb..e374a7f0e 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -27,6 +27,8 @@
#include "tool_metalink.h"
+#include "tool_formparse.h"
+
typedef enum {
ERR_NONE,
ERR_BINARY_TERMINAL = 1, /* binary to terminal detected */
@@ -44,6 +46,7 @@ struct OperationConfig {
char *cookie; /* single line with specified cookies */
char *cookiejar; /* write to this file */
char *cookiefile; /* read from this file */
+ char *altsvc; /* alt-svc cache file name */
bool cookiesession; /* new session? */
bool encoding; /* Accept-Encoding please */
bool tr_encoding; /* Transfer-Encoding please */
@@ -176,8 +179,9 @@ struct OperationConfig {
curl_off_t condtime;
struct curl_slist *headers;
struct curl_slist *proxyheaders;
+ tool_mime *mimeroot;
+ tool_mime *mimecurrent;
curl_mime *mimepost;
- curl_mime *mimecurrent;
struct curl_slist *telnet_options;
struct curl_slist *resolve;
struct curl_slist *connect_to;
diff --git a/src/tool_convert.c b/src/tool_convert.c
index ec9d7ac7c..3969130c1 100644
--- a/src/tool_convert.c
+++ b/src/tool_convert.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -122,15 +122,13 @@ char convert_char(curl_infotype infotype, char this_char)
case CURLINFO_SSL_DATA_IN:
case CURLINFO_SSL_DATA_OUT:
/* data, treat as ASCII */
- if((this_char >= 0x20) && (this_char < 0x7f)) {
- /* printable ASCII hex value: convert to host encoding */
- (void)convert_from_network(&this_char, 1);
- }
- else {
+ if(this_char < 0x20 || this_char >= 0x7f) {
/* non-printable ASCII, use a replacement character */
return UNPRINTABLE_CHAR;
}
- /* fall through to default */
+ /* printable ASCII hex value: convert to host encoding */
+ (void)convert_from_network(&this_char, 1);
+ /* FALLTHROUGH */
default:
/* treat as host encoding */
if(ISPRINT(this_char)
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
index 5d1ea9c53..49993470b 100644
--- a/src/tool_formparse.c
+++ b/src/tool_formparse.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -21,7 +21,6 @@
***************************************************************************/
#include "tool_setup.h"
-#include "mime.h"
#include "strcase.h"
#define ENABLE_CURLX_PRINTF
@@ -38,14 +37,307 @@
#include "memdebug.h" /* keep this as LAST include */
-/* Stdin parameters. */
-typedef struct {
- char *data; /* Memory data. */
- curl_off_t origin; /* File read origin offset. */
- curl_off_t size; /* Data size. */
- curl_off_t curpos; /* Current read position. */
-} standard_input;
+/* Macros to free const pointers. */
+#define CONST_FREE(x) free((void *) (x))
+#define CONST_SAFEFREE(x) Curl_safefree(*((void **) &(x)))
+/* tool_mime functions. */
+static tool_mime *tool_mime_new(tool_mime *parent, toolmimekind kind)
+{
+ tool_mime *m = (tool_mime *) calloc(1, sizeof(*m));
+
+ if(m) {
+ m->kind = kind;
+ m->parent = parent;
+ if(parent) {
+ m->prev = parent->subparts;
+ parent->subparts = m;
+ }
+ }
+ return m;
+}
+
+static tool_mime *tool_mime_new_parts(tool_mime *parent)
+{
+ return tool_mime_new(parent, TOOLMIME_PARTS);
+}
+
+static tool_mime *tool_mime_new_data(tool_mime *parent, const char *data)
+{
+ tool_mime *m = NULL;
+
+ data = strdup(data);
+ if(data) {
+ m = tool_mime_new(parent, TOOLMIME_DATA);
+ if(!m)
+ CONST_FREE(data);
+ else
+ m->data = data;
+ }
+ return m;
+}
+
+static tool_mime *tool_mime_new_filedata(tool_mime *parent,
+ const char *filename,
+ bool isremotefile,
+ CURLcode *errcode)
+{
+ CURLcode result = CURLE_OK;
+ tool_mime *m = NULL;
+
+ *errcode = CURLE_OUT_OF_MEMORY;
+ if(strcmp(filename, "-")) {
+ /* This is a normal file. */
+ filename = strdup(filename);
+ if(filename) {
+ m = tool_mime_new(parent, TOOLMIME_FILE);
+ if(!m)
+ CONST_FREE(filename);
+ else {
+ m->data = filename;
+ if(!isremotefile)
+ m->kind = TOOLMIME_FILEDATA;
+ *errcode = CURLE_OK;
+ }
+ }
+ }
+ else { /* Standard input. */
+ int fd = fileno(stdin);
+ char *data = NULL;
+ curl_off_t size;
+ curl_off_t origin;
+ struct_stat sbuf;
+
+ set_binmode(stdin);
+ origin = ftell(stdin);
+ /* If stdin is a regular file, do not buffer data but read it
+ when needed. */
+ if(fd >= 0 && origin >= 0 && !fstat(fd, &sbuf) &&
+#ifdef __VMS
+ sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC &&
+#endif
+ S_ISREG(sbuf.st_mode)) {
+ size = sbuf.st_size - origin;
+ if(size < 0)
+ size = 0;
+ }
+ else { /* Not suitable for direct use, buffer stdin data. */
+ size_t stdinsize = 0;
+
+ if(file2memory(&data, &stdinsize, stdin) != PARAM_OK) {
+ /* Out of memory. */
+ return m;
+ }
+
+ if(ferror(stdin)) {
+ result = CURLE_READ_ERROR;
+ Curl_safefree(data);
+ data = NULL;
+ }
+ else if(!stdinsize) {
+ /* Zero-length data has been freed. Re-create it. */
+ data = strdup("");
+ if(!data)
+ return m;
+ }
+ size = curlx_uztoso(stdinsize);
+ origin = 0;
+ }
+ m = tool_mime_new(parent, TOOLMIME_STDIN);
+ if(!m)
+ Curl_safefree(data);
+ else {
+ m->data = data;
+ m->origin = origin;
+ m->size = size;
+ m->curpos = 0;
+ if(!isremotefile)
+ m->kind = TOOLMIME_STDINDATA;
+ *errcode = result;
+ }
+ }
+ return m;
+}
+
+void tool_mime_free(tool_mime *mime)
+{
+ if(mime) {
+ if(mime->subparts)
+ tool_mime_free(mime->subparts);
+ if(mime->prev)
+ tool_mime_free(mime->prev);
+ CONST_SAFEFREE(mime->name);
+ CONST_SAFEFREE(mime->filename);
+ CONST_SAFEFREE(mime->type);
+ CONST_SAFEFREE(mime->encoder);
+ CONST_SAFEFREE(mime->data);
+ curl_slist_free_all(mime->headers);
+ free(mime);
+ }
+}
+
+
+/* Mime part callbacks for stdin. */
+size_t tool_mime_stdin_read(char *buffer,
+ size_t size, size_t nitems, void *arg)
+{
+ tool_mime *sip = (tool_mime *) arg;
+ curl_off_t bytesleft;
+ (void) size; /* Always 1: ignored. */
+
+ if(sip->size >= 0) {
+ if(sip->curpos >= sip->size)
+ return 0; /* At eof. */
+ bytesleft = sip->size - sip->curpos;
+ if(curlx_uztoso(nitems) > bytesleft)
+ nitems = curlx_sotouz(bytesleft);
+ }
+ if(nitems) {
+ if(sip->data) {
+ /* Return data from memory. */
+ memcpy(buffer, sip->data + curlx_sotouz(sip->curpos), nitems);
+ }
+ else {
+ /* Read from stdin. */
+ nitems = fread(buffer, 1, nitems, stdin);
+ if(ferror(stdin)) {
+ /* Show error only once. */
+ if(sip->config) {
+ warnf(sip->config, "stdin: %s\n", strerror(errno));
+ sip->config = NULL;
+ }
+ return CURL_READFUNC_ABORT;
+ }
+ }
+ sip->curpos += curlx_uztoso(nitems);
+ }
+ return nitems;
+}
+
+int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence)
+{
+ tool_mime *sip = (tool_mime *) instream;
+
+ switch(whence) {
+ case SEEK_CUR:
+ offset += sip->curpos;
+ break;
+ case SEEK_END:
+ offset += sip->size;
+ break;
+ }
+ if(offset < 0)
+ return CURL_SEEKFUNC_CANTSEEK;
+ if(!sip->data) {
+ if(fseek(stdin, (long) (offset + sip->origin), SEEK_SET))
+ return CURL_SEEKFUNC_CANTSEEK;
+ }
+ sip->curpos = offset;
+ return CURL_SEEKFUNC_OK;
+}
+
+/* Translate an internal mime tree into a libcurl mime tree. */
+
+static CURLcode tool2curlparts(CURL *curl, tool_mime *m, curl_mime *mime)
+{
+ CURLcode ret = CURLE_OK;
+ curl_mimepart *part = NULL;
+ curl_mime *submime = NULL;
+ const char *filename = NULL;
+
+ if(m) {
+ ret = tool2curlparts(curl, m->prev, mime);
+ if(!ret) {
+ part = curl_mime_addpart(mime);
+ if(!part)
+ ret = CURLE_OUT_OF_MEMORY;
+ }
+ if(!ret) {
+ filename = m->filename;
+ switch(m->kind) {
+ case TOOLMIME_PARTS:
+ ret = tool2curlmime(curl, m, &submime);
+ if(!ret) {
+ ret = curl_mime_subparts(part, submime);
+ if(ret)
+ curl_mime_free(submime);
+ }
+ break;
+
+ case TOOLMIME_DATA:
+#ifdef CURL_DOES_CONVERSIONS
+ /* Our data is always textual: convert it to ASCII. */
+ {
+ size_t size = strlen(m->data);
+ char *cp = malloc(size + 1);
+
+ if(!cp)
+ ret = CURLE_OUT_OF_MEMORY;
+ else {
+ memcpy(cp, m->data, size + 1);
+ ret = convert_to_network(cp, size);
+ if(!ret)
+ ret = curl_mime_data(part, cp, CURL_ZERO_TERMINATED);
+ free(cp);
+ }
+ }
+#else
+ ret = curl_mime_data(part, m->data, CURL_ZERO_TERMINATED);
+#endif
+ break;
+
+ case TOOLMIME_FILE:
+ case TOOLMIME_FILEDATA:
+ ret = curl_mime_filedata(part, m->data);
+ if(!ret && m->kind == TOOLMIME_FILEDATA && !filename)
+ ret = curl_mime_filename(part, NULL);
+ break;
+
+ case TOOLMIME_STDIN:
+ if(!filename)
+ filename = "-";
+ /* FALLTHROUGH */
+ case TOOLMIME_STDINDATA:
+ ret = curl_mime_data_cb(part, m->size,
+ (curl_read_callback) tool_mime_stdin_read,
+ (curl_seek_callback) tool_mime_stdin_seek,
+ NULL, m);
+ break;
+
+ default:
+ /* Other cases not possible in this context. */
+ break;
+ }
+ }
+ if(!ret && filename)
+ ret = curl_mime_filename(part, filename);
+ if(!ret)
+ ret = curl_mime_type(part, m->type);
+ if(!ret)
+ ret = curl_mime_headers(part, m->headers, 0);
+ if(!ret)
+ ret = curl_mime_encoder(part, m->encoder);
+ if(!ret)
+ ret = curl_mime_name(part, m->name);
+ }
+ return ret;
+}
+
+CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime)
+{
+ CURLcode ret = CURLE_OK;
+
+ *mime = curl_mime_init(curl);
+ if(!*mime)
+ ret = CURLE_OUT_OF_MEMORY;
+ else
+ ret = tool2curlparts(curl, m->subparts, *mime);
+ if(ret) {
+ curl_mime_free(*mime);
+ *mime = NULL;
+ }
+ return ret;
+}
/*
* helper function to get a word from form param
@@ -379,130 +671,15 @@ static int get_param_part(struct OperationConfig *config, char endchar,
}
-/* Mime part callbacks for stdin. */
-static size_t stdin_read(char *buffer, size_t size, size_t nitems, void *arg)
-{
- standard_input *sip = (standard_input *) arg;
- curl_off_t bytesleft;
- (void) size; /* Always 1: ignored. */
-
- if(sip->curpos >= sip->size)
- return 0; /* At eof. */
- bytesleft = sip->size - sip->curpos;
- if((curl_off_t) nitems > bytesleft)
- nitems = (size_t) bytesleft;
- if(sip->data) {
- /* Return data from memory. */
- memcpy(buffer, sip->data + (size_t) sip->curpos, nitems);
- }
- else {
- /* Read from stdin. */
- nitems = fread(buffer, 1, nitems, stdin);
- }
- sip->curpos += nitems;
- return nitems;
-}
-
-static int stdin_seek(void *instream, curl_off_t offset, int whence)
-{
- standard_input *sip = (standard_input *) instream;
-
- switch(whence) {
- case SEEK_CUR:
- offset += sip->curpos;
- break;
- case SEEK_END:
- offset += sip->size;
- break;
- }
- if(offset < 0)
- return CURL_SEEKFUNC_CANTSEEK;
- if(!sip->data) {
- if(fseek(stdin, (long) (offset + sip->origin), SEEK_SET))
- return CURL_SEEKFUNC_CANTSEEK;
- }
- sip->curpos = offset;
- return CURL_SEEKFUNC_OK;
-}
-
-static void stdin_free(void *ptr)
-{
- standard_input *sip = (standard_input *) ptr;
-
- Curl_safefree(sip->data);
- free(sip);
-}
-
-/* Set a part's data from a file, taking care about the pseudo filename "-" as
- * a shortcut to read stdin: if so, use a callback to read OUR stdin (to
- * workaround Windows DLL file handle caveat).
- * If stdin is a regular file opened in binary mode, save current offset as
- * origin for rewind and do not buffer data. Else read to EOF and keep in
- * memory. In all cases, compute the stdin data size.
- */
-static CURLcode file_or_stdin(curl_mimepart *part, const char *file)
-{
- standard_input *sip = NULL;
- int fd = -1;
- CURLcode result = CURLE_OK;
- struct_stat sbuf;
-
- if(strcmp(file, "-"))
- return curl_mime_filedata(part, file);
-
- sip = (standard_input *) calloc(1, sizeof(*sip));
- if(!sip)
- return CURLE_OUT_OF_MEMORY;
-
- set_binmode(stdin);
-
- /* If stdin is a regular file, do not buffer data but read it when needed. */
- fd = fileno(stdin);
- sip->origin = ftell(stdin);
- if(fd >= 0 && sip->origin >= 0 && !fstat(fd, &sbuf) &&
-#ifdef __VMS
- sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC &&
-#endif
- S_ISREG(sbuf.st_mode)) {
- sip->size = sbuf.st_size - sip->origin;
- if(sip->size < 0)
- sip->size = 0;
- }
- else { /* Not suitable for direct use, buffer stdin data. */
- size_t stdinsize = 0;
-
- sip->origin = 0;
- if(file2memory(&sip->data, &stdinsize, stdin) != PARAM_OK)
- result = CURLE_OUT_OF_MEMORY;
- else {
- if(!stdinsize)
- sip->data = NULL; /* Has been freed if no data. */
- sip->size = stdinsize;
- if(ferror(stdin))
- result = CURLE_READ_ERROR;
- }
- }
-
- /* Set remote file name. */
- if(!result)
- result = curl_mime_filename(part, file);
-
- /* Set part's data from callback. */
- if(!result)
- result = curl_mime_data_cb(part, sip->size,
- stdin_read, stdin_seek, stdin_free, sip);
- if(result)
- stdin_free(sip);
- return result;
-}
-
-
/***************************************************************************
*
* formparse()
*
* Reads a 'name=value' parameter and builds the appropriate linked list.
*
+ * If the value is of the form '<filename', field data is read from the
+ * given file.
+
* Specify files to upload with 'name=@filename', or 'name=@"filename"'
* in case the filename contain ',' or ';'. Supports specified
* given Content-Type of the files. Such as ';type=<content-type>'.
@@ -539,15 +716,27 @@ static CURLcode file_or_stdin(curl_mimepart *part, const char *file)
* else curl will fail to figure out the correct filename. if the filename
* tobe quoted contains '"' or '\', '"' and '\' must be escaped by backslash.
*
- * This function uses curl_formadd to fulfill it's job. Is heavily based on
- * the old curl_formparse code.
- *
***************************************************************************/
+/* Convenience macros for null pointer check. */
+#define NULL_CHECK(ptr, init, retcode) { \
+ (ptr) = (init); \
+ if(!(ptr)) { \
+ warnf(config->global, "out of memory!\n"); \
+ curl_slist_free_all(headers); \
+ Curl_safefree(contents); \
+ return retcode; \
+ } \
+}
+#define SET_TOOL_MIME_PTR(m, field, retcode) { \
+ if(field) \
+ NULL_CHECK((m)->field, strdup(field), retcode); \
+}
+
int formparse(struct OperationConfig *config,
const char *input,
- curl_mime **mimepost,
- curl_mime **mimecurrent,
+ tool_mime **mimeroot,
+ tool_mime **mimecurrent,
bool literal_value)
{
/* input MUST be a string in the format 'name=contents' and we'll
@@ -560,25 +749,17 @@ int formparse(struct OperationConfig *config,
char *filename = NULL;
char *encoder = NULL;
struct curl_slist *headers = NULL;
- curl_mimepart *part = NULL;
+ tool_mime *part = NULL;
CURLcode res;
/* Allocate the main mime structure if needed. */
- if(!*mimepost) {
- *mimepost = curl_mime_init(config->easy);
- if(!*mimepost) {
- warnf(config->global, "curl_mime_init failed!\n");
- return 1;
- }
- *mimecurrent = *mimepost;
+ if(!*mimecurrent) {
+ NULL_CHECK(*mimeroot, tool_mime_new_parts(NULL), 1);
+ *mimecurrent = *mimeroot;
}
/* Make a copy we can overwrite. */
- contents = strdup(input);
- if(!contents) {
- fprintf(config->global->errors, "out of memory\n");
- return 2;
- }
+ NULL_CHECK(contents, strdup(input), 2);
/* Scan for the end of the name. */
contp = strchr(contents, '=');
@@ -589,8 +770,6 @@ int formparse(struct OperationConfig *config,
*contp++ = '\0';
if(*contp == '(' && !literal_value) {
- curl_mime *subparts;
-
/* Starting a multipart. */
sep = get_param_part(config, '\0',
&contp, &data, &type, NULL, NULL, &headers);
@@ -598,55 +777,26 @@ int formparse(struct OperationConfig *config,
Curl_safefree(contents);
return 3;
}
- subparts = curl_mime_init(config->easy);
- if(!subparts) {
- warnf(config->global, "curl_mime_init failed!\n");
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 4;
- }
- part = curl_mime_addpart(*mimecurrent);
- if(!part) {
- warnf(config->global, "curl_mime_addpart failed!\n");
- curl_mime_free(subparts);
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 5;
- }
- if(curl_mime_subparts(part, subparts)) {
- warnf(config->global, "curl_mime_subparts failed!\n");
- curl_mime_free(subparts);
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 6;
- }
- *mimecurrent = subparts;
- if(curl_mime_headers(part, headers, 1)) {
- warnf(config->global, "curl_mime_headers failed!\n");
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 7;
- }
- if(curl_mime_type(part, type)) {
- warnf(config->global, "curl_mime_type failed!\n");
- Curl_safefree(contents);
- return 8;
- }
+ NULL_CHECK(part, tool_mime_new_parts(*mimecurrent), 4);
+ *mimecurrent = part;
+ part->headers = headers;
+ headers = NULL;
+ SET_TOOL_MIME_PTR(part, type, 5);
}
else if(!name && !strcmp(contp, ")") && !literal_value) {
- /* Ending a mutipart. */
- if(*mimecurrent == *mimepost) {
+ /* Ending a multipart. */
+ if(*mimecurrent == *mimeroot) {
warnf(config->global, "no multipart to terminate!\n");
Curl_safefree(contents);
- return 9;
+ return 6;
}
- *mimecurrent = (*mimecurrent)->parent->parent;
+ *mimecurrent = (*mimecurrent)->parent;
}
else if('@' == contp[0] && !literal_value) {
/* we use the @-letter to indicate file name(s) */
- curl_mime *subparts = NULL;
+ tool_mime *subparts = NULL;
do {
/* since this was a file, it may have a content-type specifier
@@ -655,10 +805,8 @@ int formparse(struct OperationConfig *config,
sep = get_param_part(config, ',', &contp,
&data, &type, &filename, &encoder, &headers);
if(sep < 0) {
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
Curl_safefree(contents);
- return 10;
+ return 7;
}
/* now contp point to comma or string end.
@@ -666,125 +814,68 @@ int formparse(struct OperationConfig *config,
if(!subparts) {
if(sep != ',') /* If there is a single file. */
subparts = *mimecurrent;
- else {
- subparts = curl_mime_init(config->easy);
- if(!subparts) {
- warnf(config->global, "curl_mime_init failed!\n");
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 11;
- }
- }
+ else
+ NULL_CHECK(subparts, tool_mime_new_parts(*mimecurrent), 8);
}
- /* Allocate a part for that file. */
- part = curl_mime_addpart(subparts);
- if(!part) {
- warnf(config->global, "curl_mime_addpart failed!\n");
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 12;
- }
-
- /* Set part headers. */
- if(curl_mime_headers(part, headers, 1)) {
- warnf(config->global, "curl_mime_headers failed!\n");
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 13;
- }
-
- /* Setup file in part. */
- res = file_or_stdin(part, data);
- if(res) {
- warnf(config->global, "setting file %s failed!\n", data);
- if(res != CURLE_READ_ERROR) {
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
+ /* Store that file in a part. */
+ NULL_CHECK(part,
+ tool_mime_new_filedata(subparts, data, TRUE, &res), 9);
+ part->headers = headers;
+ headers = NULL;
+ part->config = config->global;
+ if(res == CURLE_READ_ERROR) {
+ /* An error occurred while reading stdin: if read has started,
+ issue the error now. Else, delay it until processed by
+ libcurl. */
+ if(part->size > 0) {
+ warnf(config->global,
+ "error while reading standard input\n");
Curl_safefree(contents);
- return 14;
+ return 10;
}
+ CONST_SAFEFREE(part->data);
+ part->data = NULL;
+ part->size = -1;
+ res = CURLE_OK;
}
- if(filename && curl_mime_filename(part, filename)) {
- warnf(config->global, "curl_mime_filename failed!\n");
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
- Curl_safefree(contents);
- return 15;
- }
- if(curl_mime_type(part, type)) {
- warnf(config->global, "curl_mime_type failed!\n");
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
- Curl_safefree(contents);
- return 16;
- }
- if(curl_mime_encoder(part, encoder)) {
- warnf(config->global, "curl_mime_encoder failed!\n");
- if(subparts != *mimecurrent)
- curl_mime_free(subparts);
- Curl_safefree(contents);
- return 17;
- }
+ SET_TOOL_MIME_PTR(part, filename, 11);
+ SET_TOOL_MIME_PTR(part, type, 12);
+ SET_TOOL_MIME_PTR(part, encoder, 13);
/* *contp could be '\0', so we just check with the delimiter */
} while(sep); /* loop if there's another file name */
-
- /* now we add the multiple files section */
- if(subparts != *mimecurrent) {
- part = curl_mime_addpart(*mimecurrent);
- if(!part) {
- warnf(config->global, "curl_mime_addpart failed!\n");
- curl_mime_free(subparts);
- Curl_safefree(contents);
- return 18;
- }
- if(curl_mime_subparts(part, subparts)) {
- warnf(config->global, "curl_mime_subparts failed!\n");
- curl_mime_free(subparts);
- Curl_safefree(contents);
- return 19;
- }
- }
+ part = (*mimecurrent)->subparts; /* Set name on group. */
}
else {
- /* Allocate a mime part. */
- part = curl_mime_addpart(*mimecurrent);
- if(!part) {
- warnf(config->global, "curl_mime_addpart failed!\n");
- Curl_safefree(contents);
- return 20;
- }
-
if(*contp == '<' && !literal_value) {
++contp;
sep = get_param_part(config, '\0', &contp,
&data, &type, NULL, &encoder, &headers);
if(sep < 0) {
Curl_safefree(contents);
- return 21;
- }
-
- /* Set part headers. */
- if(curl_mime_headers(part, headers, 1)) {
- warnf(config->global, "curl_mime_headers failed!\n");
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 22;
+ return 14;
}
- /* Setup file in part. */
- res = file_or_stdin(part, data);
- if(res) {
- warnf(config->global, "setting file %s failed!\n", data);
- if(res != CURLE_READ_ERROR) {
+ NULL_CHECK(part, tool_mime_new_filedata(*mimecurrent, data, FALSE,
+ &res), 15);
+ part->headers = headers;
+ headers = NULL;
+ part->config = config->global;
+ if(res == CURLE_READ_ERROR) {
+ /* An error occurred while reading stdin: if read has started,
+ issue the error now. Else, delay it until processed by
+ libcurl. */
+ if(part->size > 0) {
+ warnf(config->global,
+ "error while reading standard input\n");
Curl_safefree(contents);
- return 23;
+ return 16;
}
+ CONST_SAFEFREE(part->data);
+ part->data = NULL;
+ part->size = -1;
+ res = CURLE_OK;
}
}
else {
@@ -795,48 +886,18 @@ int formparse(struct OperationConfig *config,
&data, &type, &filename, &encoder, &headers);
if(sep < 0) {
Curl_safefree(contents);
- return 24;
+ return 17;
}
}
- /* Set part headers. */
- if(curl_mime_headers(part, headers, 1)) {
- warnf(config->global, "curl_mime_headers failed!\n");
- curl_slist_free_all(headers);
- Curl_safefree(contents);
- return 25;
- }
-
-#ifdef CURL_DOES_CONVERSIONS
- if(convert_to_network(data, strlen(data))) {
- warnf(config->global, "curl_formadd failed!\n");
- Curl_safefree(contents);
- return 26;
- }
-#endif
-
- if(curl_mime_data(part, data, CURL_ZERO_TERMINATED)) {
- warnf(config->global, "curl_mime_data failed!\n");
- Curl_safefree(contents);
- return 27;
- }
+ NULL_CHECK(part, tool_mime_new_data(*mimecurrent, data), 18);
+ part->headers = headers;
+ headers = NULL;
}
- if(curl_mime_filename(part, filename)) {
- warnf(config->global, "curl_mime_filename failed!\n");
- Curl_safefree(contents);
- return 28;
- }
- if(curl_mime_type(part, type)) {
- warnf(config->global, "curl_mime_type failed!\n");
- Curl_safefree(contents);
- return 29;
- }
- if(curl_mime_encoder(part, encoder)) {
- warnf(config->global, "curl_mime_encoder failed!\n");
- Curl_safefree(contents);
- return 30;
- }
+ SET_TOOL_MIME_PTR(part, filename, 19);
+ SET_TOOL_MIME_PTR(part, type, 20);
+ SET_TOOL_MIME_PTR(part, encoder, 21);
if(sep) {
*contp = (char) sep;
@@ -846,16 +907,12 @@ int formparse(struct OperationConfig *config,
}
/* Set part name. */
- if(name && curl_mime_name(part, name)) {
- warnf(config->global, "curl_mime_name failed!\n");
- Curl_safefree(contents);
- return 31;
- }
+ SET_TOOL_MIME_PTR(part, name, 22);
}
else {
warnf(config->global, "Illegally formatted input field!\n");
Curl_safefree(contents);
- return 32;
+ return 23;
}
Curl_safefree(contents);
return 0;
diff --git a/src/tool_formparse.h b/src/tool_formparse.h
index cdf02d028..750fe451f 100644
--- a/src/tool_formparse.h
+++ b/src/tool_formparse.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -23,10 +23,50 @@
***************************************************************************/
#include "tool_setup.h"
+/* Private structure for mime/parts. */
+
+typedef enum {
+ TOOLMIME_NONE = 0,
+ TOOLMIME_PARTS,
+ TOOLMIME_DATA,
+ TOOLMIME_FILE,
+ TOOLMIME_FILEDATA,
+ TOOLMIME_STDIN,
+ TOOLMIME_STDINDATA
+} toolmimekind;
+
+typedef struct tool_mime tool_mime;
+struct tool_mime {
+ /* Structural fields. */
+ toolmimekind kind; /* Part kind. */
+ tool_mime *parent; /* Parent item. */
+ tool_mime *prev; /* Previous sibling (reverse order link). */
+ /* Common fields. */
+ const char *data; /* Actual data or data filename. */
+ const char *name; /* Part name. */
+ const char *filename; /* Part's filename. */
+ const char *type; /* Part's mime type. */
+ const char *encoder; /* Part's requested encoding. */
+ struct curl_slist *headers; /* User-defined headers. */
+ /* TOOLMIME_PARTS fields. */
+ tool_mime *subparts; /* Part's subparts. */
+ /* TOOLMIME_STDIN/TOOLMIME_STDINDATA fields. */
+ curl_off_t origin; /* Stdin read origin offset. */
+ curl_off_t size; /* Stdin data size. */
+ curl_off_t curpos; /* Stdin current read position. */
+ struct GlobalConfig *config; /* For access from callback. */
+};
+
+size_t tool_mime_stdin_read(char *buffer,
+ size_t size, size_t nitems, void *arg);
+int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence);
+
int formparse(struct OperationConfig *config,
const char *input,
- curl_mime **mimepost,
- curl_mime **mimecurrent,
+ tool_mime **mimeroot,
+ tool_mime **mimecurrent,
bool literal_value);
+CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime);
+void tool_mime_free(tool_mime *mime);
#endif /* HEADER_CURL_TOOL_FORMPARSE_H */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index c7ba5f243..b133cb87e 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -214,6 +214,7 @@ static const struct LongShort aliases[]= {
{"a", "append", ARG_BOOL},
{"A", "user-agent", ARG_STRING},
{"b", "cookie", ARG_STRING},
+ {"ba", "alt-svc", ARG_STRING},
{"B", "use-ascii", ARG_BOOL},
{"c", "cookie-jar", ARG_STRING},
{"C", "continue-at", ARG_STRING},
@@ -1244,17 +1245,23 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
/* This specifies the User-Agent name */
GetStr(&config->useragent, nextarg);
break;
- case 'b': /* cookie string coming up: */
- if(nextarg[0] == '@') {
- nextarg++;
- }
- else if(strchr(nextarg, '=')) {
- /* A cookie string must have a =-letter */
- GetStr(&config->cookie, nextarg);
+ case 'b':
+ switch(subletter) {
+ case 'a': /* --alt-svc */
+ GetStr(&config->altsvc, nextarg);
break;
+ default: /* --cookie string coming up: */
+ if(nextarg[0] == '@') {
+ nextarg++;
+ }
+ else if(strchr(nextarg, '=')) {
+ /* A cookie string must have a =-letter */
+ GetStr(&config->cookie, nextarg);
+ break;
+ }
+ /* We have a cookie file to read from! */
+ GetStr(&config->cookiefile, nextarg);
}
- /* We have a cookie file to read from! */
- GetStr(&config->cookiefile, nextarg);
break;
case 'B':
/* use ASCII/text when transferring */
@@ -1691,7 +1698,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
to sort this out slowly and carefully */
if(formparse(config,
nextarg,
- &config->mimepost,
+ &config->mimeroot,
&config->mimecurrent,
(subletter == 's')?TRUE:FALSE)) /* 's' is literal string */
return PARAM_BAD_USE;
diff --git a/src/tool_getpass.c b/src/tool_getpass.c
index e5e2d6dc1..bf531a537 100644
--- a/src/tool_getpass.c
+++ b/src/tool_getpass.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -21,6 +21,10 @@
***************************************************************************/
#include "tool_setup.h"
+#if defined(__AMIGA__) && !defined(__amigaos4__)
+# undef HAVE_TERMIOS_H
+#endif
+
#ifndef HAVE_GETPASS_R
/* this file is only for systems without getpass_r() */
diff --git a/src/tool_help.c b/src/tool_help.c
index aeffd3dea..8a3c25820 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -48,6 +48,8 @@ struct helptxt {
static const struct helptxt helptext[] = {
{" --abstract-unix-socket <path>",
"Connect via abstract Unix domain socket"},
+ {" --alt-svc <file name>",
+ "Enable alt-svc with this cache file"},
{" --anyauth",
"Pick any authentication method"},
{"-a, --append",
@@ -78,7 +80,7 @@ static const struct helptxt helptext[] = {
"Connect to host"},
{"-C, --continue-at <offset>",
"Resumed transfer offset"},
- {"-b, --cookie <data>",
+ {"-b, --cookie <data|filename>",
"Send cookies from string/file"},
{"-c, --cookie-jar <filename>",
"Write cookies to <filename> after operation"},
@@ -525,6 +527,7 @@ static const struct feat feats[] = {
{"HTTPS-proxy", CURL_VERSION_HTTPS_PROXY},
{"MultiSSL", CURL_VERSION_MULTI_SSL},
{"PSL", CURL_VERSION_PSL},
+ {"alt-svc", CURL_VERSION_ALTSVC},
};
void tool_help(void)
@@ -540,6 +543,21 @@ void tool_help(void)
}
}
+static int
+featcomp(const void *p1, const void *p2)
+{
+ /* The arguments to this function are "pointers to pointers to char", but
+ the comparison arguments are "pointers to char", hence the following cast
+ plus dereference */
+#ifdef HAVE_STRCASECMP
+ return strcasecmp(* (char * const *) p1, * (char * const *) p2);
+#elif defined(HAVE_STRCMPI)
+ return strcmpi(* (char * const *) p1, * (char * const *) p2);
+#else
+ return strcmp(* (char * const *) p1, * (char * const *) p2);
+#endif
+}
+
void tool_version_info(void)
{
const char *const *proto;
@@ -559,15 +577,20 @@ void tool_version_info(void)
puts(""); /* newline */
}
if(curlinfo->features) {
+ char *featp[ sizeof(feats) / sizeof(feats[0]) + 1];
+ size_t numfeat = 0;
unsigned int i;
- printf("Features: ");
+ printf("Features:");
for(i = 0; i < sizeof(feats)/sizeof(feats[0]); i++) {
if(curlinfo->features & feats[i].bitmask)
- printf("%s ", feats[i].name);
+ featp[numfeat++] = (char *)feats[i].name;
}
#ifdef USE_METALINK
- printf("Metalink ");
+ featp[numfeat++] = (char *)"Metalink";
#endif
+ qsort(&featp[0], numfeat, sizeof(char *), featcomp);
+ for(i = 0; i< numfeat; i++)
+ printf(" %s", featp[i]);
puts(""); /* newline */
}
}
diff --git a/src/tool_main.c b/src/tool_main.c
index c3a81e933..5679f361e 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -112,7 +112,7 @@ static void memory_tracking_init(void)
env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
strcpy(fname, env);
curl_free(env);
- curl_memdebug(fname);
+ curl_dbg_memdebug(fname);
/* this weird stuff here is to make curl_free() get called
before curl_memdebug() as otherwise memory tracking will
log a free() without an alloc! */
@@ -123,7 +123,7 @@ static void memory_tracking_init(void)
char *endptr;
long num = strtol(env, &endptr, 10);
if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
- curl_memlimit(num);
+ curl_dbg_memlimit(num);
curl_free(env);
}
}
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 4516c8e6a..e1ceabe7a 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -33,6 +33,10 @@
# include <fabdef.h>
#endif
+#ifdef __AMIGA__
+# include <proto/dos.h>
+#endif
+
#include "strcase.h"
#define ENABLE_CURLX_PRINTF
@@ -945,6 +949,9 @@ static CURLcode operate_do(struct GlobalConfig *global,
config->postfieldsize);
break;
case HTTPREQ_MIMEPOST:
+ result = tool2curlmime(curl, config->mimeroot, &config->mimepost);
+ if(result)
+ goto show_error;
my_setopt_mimepost(curl, CURLOPT_MIMEPOST, config->mimepost);
break;
default:
@@ -1006,7 +1013,8 @@ static CURLcode operate_do(struct GlobalConfig *global,
if(config->tr_encoding)
my_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L);
/* new in libcurl 7.64.0 */
- my_setopt(curl, CURLOPT_HTTP09_ALLOWED, config->http09_allowed);
+ my_setopt(curl, CURLOPT_HTTP09_ALLOWED,
+ config->http09_allowed ? 1L : 0L);
} /* (built_in_protos & CURLPROTO_HTTP) */
@@ -1534,6 +1542,12 @@ static CURLcode operate_do(struct GlobalConfig *global,
if(config->disallow_username_in_url)
my_setopt(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, 1L);
+#ifdef USE_ALTSVC
+ /* only if explicitly enabled in configure */
+ if(config->altsvc)
+ my_setopt_str(curl, CURLOPT_ALTSVC, config->altsvc);
+#endif
+
/* initialize retry vars for loop below */
retry_sleep_default = (config->retry_delay) ?
config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
@@ -1856,9 +1870,9 @@ static CURLcode operate_do(struct GlobalConfig *global,
#ifdef __AMIGA__
if(!result && outs.s_isreg && outs.filename) {
/* Set the url (up to 80 chars) as comment for the file */
- if(strlen(url) > 78)
- url[79] = '\0';
- SetComment(outs.filename, url);
+ if(strlen(urlnode->url) > 78)
+ urlnode->url[79] = '\0';
+ SetComment(outs.filename, urlnode->url);
}
#endif
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index cd28ad829..745b4546e 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -32,7 +32,6 @@
#include "tool_setopt.h"
#include "tool_convert.h"
-#include "mime.h"
#include "memdebug.h" /* keep this as LAST include */
/* Lookup tables for converting setopt values back to symbols */
@@ -187,6 +186,12 @@ static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
if(ret) \
goto nomem; \
} WHILE_FALSE
+#define NULL_CHECK(p) do { \
+ if(!p) { \
+ ret = CURLE_OUT_OF_MEMORY; \
+ goto nomem; \
+ } \
+} WHILE_FALSE
#define DECL0(s) ADD((&easysrc_decl, s))
#define DECL1(f,a) ADDF((&easysrc_decl, f,a))
@@ -406,174 +411,184 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno)
return ret;
}
-/* Generate source code for a mime structure. */
-static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
+static CURLcode libcurl_generate_mime(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *toolmime,
+ int *mimeno); /* Forward. */
+
+/* Wrapper to generate source code for a mime part. */
+static CURLcode libcurl_generate_mime_part(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *part,
+ int mimeno)
{
CURLcode ret = CURLE_OK;
- int i;
- curl_off_t size;
- curl_mimepart *part;
- char *filename;
+ int submimeno = 0;
char *escaped = NULL;
- char *cp;
- char *data;
+ const char *data = NULL;
+ const char *filename = part->filename;
+
+ /* Parts are linked in reverse order. */
+ if(part->prev) {
+ ret = libcurl_generate_mime_part(curl, config, part->prev, mimeno);
+ if(ret)
+ return ret;
+ }
- /* May need several mime variables, so invent name */
- *mimeno = ++easysrc_mime_count;
+ /* Create the part. */
+ CODE2("part%d = curl_mime_addpart(mime%d);", mimeno, mimeno);
- DECL1("curl_mime *mime%d;", *mimeno);
- DATA1("mime%d = NULL;", *mimeno);
- CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
- CLEAN1("curl_mime_free(mime%d);", *mimeno);
- CLEAN1("mime%d = NULL;", *mimeno);
- if(mime->firstpart) {
- DECL1("curl_mimepart *part%d;", *mimeno);
- for(part = mime->firstpart; part; part = part->nextpart) {
- CODE2("part%d = curl_mime_addpart(mime%d);", *mimeno, *mimeno);
- filename = part->filename;
- switch(part->kind) {
- case MIMEKIND_FILE:
- Curl_safefree(escaped);
- escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_filedata(part%d, \"%s\");", *mimeno, escaped);
- if(!filename)
- CODE1("curl_mime_filename(part%d, NULL);", *mimeno);
- else {
- /* Fast check to see if remote file name is base name. */
- filename = part->data;
- for(cp = filename; *cp; cp++)
- if(*cp == '/' || *cp == '\\')
- filename = cp + 1;
- if(!part->filename || !strcmp(filename, part->filename))
- filename = NULL;
- else
- filename = part->filename;
- }
- break;
- case MIMEKIND_CALLBACK:
- /* Can only be reading stdin in the current context. */
- CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
- *mimeno);
- CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
- break;
- case MIMEKIND_DATA:
-#ifdef CURL_DOES_CONVERSIONS
- /* Data is stored in ASCII and we want in in the host character
- code. Convert it back for output. */
- data = malloc(part->datasize + 1);
- if(!data) {
- ret = CURLE_OUT_OF_MEMORY;
- goto nomem;
- }
- memcpy(data, part->data, part->datasize + 1);
- ret = convert_from_network(data, strlen(data));
- if(ret) {
- Curl_safefree(data);
- goto nomem;
- }
-#else
- data = part->data;
-#endif
+ switch(part->kind) {
+ case TOOLMIME_PARTS:
+ ret = libcurl_generate_mime(curl, config, part, &submimeno);
+ if(!ret) {
+ CODE2("curl_mime_subparts(part%d, mime%d);", mimeno, submimeno);
+ CODE1("mime%d = NULL;", submimeno); /* Avoid freeing in CLEAN. */
+ }
+ break;
- /* Are there any nul byte in data? */
- for(cp = data; *cp; cp++)
- ;
- size = (cp == data + part->datasize)? (curl_off_t) -1: part->datasize;
- Curl_safefree(escaped);
- escaped = c_escape(data, (size_t) part->datasize);
+ case TOOLMIME_DATA:
#ifdef CURL_DOES_CONVERSIONS
- Curl_safefree(data);
+ /* Data will be set in ASCII, thus issue a comment with clear text. */
+ escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE1("/* \"%s\" */", escaped);
+
+ /* Our data is always textual: convert it to ASCII. */
+ {
+ size_t size = strlen(part->data);
+ char *cp = malloc(size + 1);
+
+ NULL_CHECK(cp);
+ memcpy(cp, part->data, size + 1);
+ ret = convert_to_network(cp, size);
+ data = cp;
+ }
+#else
+ data = part->data;
#endif
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- if(size >= 0)
- CODE3("curl_mime_data(part%d, \"%s\", %" CURL_FORMAT_CURL_OFF_T ");",
- *mimeno, escaped, size);
- else
- CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
- *mimeno, escaped);
- break;
- case MIMEKIND_MULTIPART:
- ret = libcurl_generate_mime(part->arg, &i);
- if(ret)
- goto nomem;
- CODE2("curl_mime_subparts(part%d, mime%d);", *mimeno, i);
- CODE1("mime%d = NULL;", i); /* Avoid freeing in CLEAN sequence. */
- break;
- default:
- /* Other cases not possible in this context. */
- break;
- }
+ if(!ret) {
+ Curl_safefree(escaped);
+ escaped = c_escape(data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
+ mimeno, escaped);
+ }
+ break;
+
+ case TOOLMIME_FILE:
+ case TOOLMIME_FILEDATA:
+ escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped);
+ if(part->kind == TOOLMIME_FILEDATA && !filename) {
+ CODE1("curl_mime_filename(part%d, NULL);", mimeno);
+ }
+ break;
+
+ case TOOLMIME_STDIN:
+ if(!filename)
+ filename = "-";
+ /* FALLTHROUGH */
+ case TOOLMIME_STDINDATA:
+ /* Can only be reading stdin in the current context. */
+ CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
+ mimeno);
+ CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
+ break;
+ default:
+ /* Other cases not possible in this context. */
+ break;
+ }
- if(part->encoder) {
- Curl_safefree(escaped);
- escaped = c_escape(part->encoder->name, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_encoder(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->encoder) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
+ }
- if(filename) {
- Curl_safefree(escaped);
- escaped = c_escape(filename, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_filename(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && filename) {
+ Curl_safefree(escaped);
+ escaped = c_escape(filename, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->name) {
- Curl_safefree(escaped);
- escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_name(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->name) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->mimetype) {
- Curl_safefree(escaped);
- escaped = c_escape(part->mimetype, CURL_ZERO_TERMINATED);
- if(!escaped)
- return CURLE_OUT_OF_MEMORY;
- CODE2("curl_mime_type(part%d, \"%s\");", *mimeno, escaped);
- }
+ if(!ret && part->type) {
+ Curl_safefree(escaped);
+ escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
+ NULL_CHECK(escaped);
+ CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
+ }
- if(part->userheaders) {
- int ownership = part->flags & MIME_USERHEADERS_OWNER? 1: 0;
+ if(!ret && part->headers) {
+ int slistno;
- ret = libcurl_generate_slist(part->userheaders, &i);
- if(ret)
- goto nomem;
- CODE3("curl_mime_headers(part%d, slist%d, %d);",
- *mimeno, i, ownership);
- if(ownership)
- CODE1("slist%d = NULL;", i); /* Prevent freeing in CLEAN sequence. */
- }
+ ret = libcurl_generate_slist(part->headers, &slistno);
+ if(!ret) {
+ CODE2("curl_mime_headers(part%d, slist%d, 1);", mimeno, slistno);
+ CODE1("slist%d = NULL;", slistno); /* Prevent CLEANing. */
}
}
nomem:
+#ifdef CURL_DOES_CONVERSIONS
+ if(data)
+ free((char *) data);
+#endif
+
Curl_safefree(escaped);
return ret;
}
+/* Wrapper to generate source code for a mime structure. */
+static CURLcode libcurl_generate_mime(CURL *curl,
+ struct GlobalConfig *config,
+ tool_mime *toolmime,
+ int *mimeno)
+{
+ CURLcode ret = CURLE_OK;
+
+ /* May need several mime variables, so invent name. */
+ *mimeno = ++easysrc_mime_count;
+ DECL1("curl_mime *mime%d;", *mimeno);
+ DATA1("mime%d = NULL;", *mimeno);
+ CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
+ CLEAN1("curl_mime_free(mime%d);", *mimeno);
+ CLEAN1("mime%d = NULL;", *mimeno);
+
+ if(toolmime->subparts) {
+ DECL1("curl_mimepart *part%d;", *mimeno);
+ ret = libcurl_generate_mime_part(curl, config,
+ toolmime->subparts, *mimeno);
+ }
+
+nomem:
+ return ret;
+}
+
/* setopt wrapper for CURLOPT_MIMEPOST */
CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
curl_mime *mimepost)
{
- CURLcode ret = CURLE_OK;
-
- ret = curl_easy_setopt(curl, tag, mimepost);
-
- if(config->libcurl && mimepost && !ret) {
- int i;
+ CURLcode ret = curl_easy_setopt(curl, tag, mimepost);
+ int mimeno = 0;
- ret = libcurl_generate_mime(mimepost, &i);
+ if(!ret && config->libcurl) {
+ ret = libcurl_generate_mime(curl, config,
+ config->current->mimeroot, &mimeno);
if(!ret)
- CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, i);
+ CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, mimeno);
}
nomem:
@@ -685,10 +700,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
else {
if(escape) {
escaped = c_escape(value, CURL_ZERO_TERMINATED);
- if(!escaped) {
- ret = CURLE_OUT_OF_MEMORY;
- goto nomem;
- }
+ NULL_CHECK(escaped);
CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
}
else
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index f8a52cd75..663041f65 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -23,6 +23,8 @@
***************************************************************************/
#include "tool_setup.h"
+#include "tool_formparse.h"
+
/*
* Macros used in operate()
*/
diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c
index babae0416..e9007b2b4 100644
--- a/src/tool_urlglob.c
+++ b/src/tool_urlglob.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -603,7 +603,7 @@ CURLcode glob_match_url(char **result, char *filename, URLGlob *glob)
char *target;
size_t allocsize;
char numbuf[18];
- char *appendthis = NULL;
+ char *appendthis = (char *)"";
size_t appendlen = 0;
size_t stringlen = 0;
diff --git a/src/tool_xattr.c b/src/tool_xattr.c
index 730381ba9..592d4a120 100644
--- a/src/tool_xattr.c
+++ b/src/tool_xattr.c
@@ -111,11 +111,13 @@ int fwrite_xattr(CURL *curl, int fd)
#elif defined(HAVE_FSETXATTR_5)
err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0);
#elif defined(__FreeBSD_version)
- err = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, mappings[i].attr,
- value, strlen(value));
- /* FreeBSD's extattr_set_fd returns the length of the extended
- attribute */
- err = err < 0 ? err : 0;
+ {
+ ssize_t rc = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER,
+ mappings[i].attr, value, strlen(value));
+ /* FreeBSD's extattr_set_fd returns the length of the extended
+ attribute */
+ err = (rc < 0 ? -1 : 0);
+ }
#endif
if(freeptr)
curl_free(value);
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
index 505c573cb..85e731966 100644
--- a/tests/FILEFORMAT
+++ b/tests/FILEFORMAT
@@ -249,6 +249,7 @@ unittest
unix-sockets
WinSSL
ld_preload
+alt-svc
as well as each protocol that curl supports. A protocol only needs to be
specified if it is different from the server (useful when the server
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 5ac02450a..77a8171df 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -56,11 +56,11 @@ test289 test290 test291 test292 test293 test294 test295 test296 test297 \
test298 test299 test300 test301 test302 test303 test304 test305 test306 \
test307 test308 test309 test310 test311 test312 test313 test314 test315 \
test316 test317 test318 test319 test320 test321 test322 test323 test324 \
-test325 test326 test327 test328 test329 test330 \
+test325 test326 test327 test328 test329 test330 test331 \
\
test340 \
\
-test350 test351 test352 test353 test354 \
+test350 test351 test352 test353 test354 test355 test356 \
test393 test394 test395 \
\
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
@@ -83,7 +83,7 @@ test617 test618 test619 test620 test621 test622 test623 test624 test625 \
test626 test627 test628 test629 test630 test631 test632 test633 test634 \
test635 test636 test637 test638 test639 test640 test641 test642 \
test643 test644 test645 test646 test647 test648 test649 test650 test651 \
-test652 test653 test654 test655 test656 test658 \
+test652 test653 test654 test655 test656 test658 test659 \
\
test700 test701 test702 test703 test704 test705 test706 test707 test708 \
test709 test710 test711 test712 test713 test714 test715 \
@@ -174,7 +174,7 @@ test1516 test1517 test1518 test1519 test1520 test1521 test1522 \
\
test1525 test1526 test1527 test1528 test1529 test1530 test1531 test1532 \
test1533 test1534 test1535 test1536 test1537 test1538 \
-test1540 \
+test1540 test1541 \
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
test1558 test1560 test1561 test1562 \
\
@@ -183,13 +183,13 @@ test1590 test1591 test1592 \
test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \
test1608 test1609 test1620 test1621 \
\
-test1650 test1651 test1652 test1653 \
+test1650 test1651 test1652 test1653 test1654 \
\
test1700 test1701 test1702 \
\
test1800 test1801 \
\
-test1900 test1901 test1902 test1903 test1904 \
+test1900 test1901 test1902 test1903 test1904 test1905 \
\
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
diff --git a/tests/data/test1026 b/tests/data/test1026
index bd5dc9c85..6bda7a43f 100644
--- a/tests/data/test1026
+++ b/tests/data/test1026
@@ -28,7 +28,7 @@ curl --manual
# Search for these two sentinel lines in the manual output; if they are found,
# then chances are good the entire manual is there.
<postcheck>
-perl -e 'open(IN,$ARGV[0]); my $lines=grep(/(a\s*tool\s*to\s*transfer\s*data)|(mailing\s*lists\s*to\s*discuss\s*curl)/, <IN>); exit ($lines != 2); # Let this file pass an XML syntax check: </IN>' log/stdout1026
+perl -e 'open(IN,$ARGV[0]); my $lines=grep(/(curl\s*-\s*transfer\sa\s*URL)|(CONTRIBUTORS)/, <IN>); exit ($lines != 2); # Let this file pass an XML syntax check: </IN>' log/stdout1026
</postcheck>
</client>
diff --git a/tests/data/test1034 b/tests/data/test1034
index beab0d3c0..b4ffc8a98 100644
--- a/tests/data/test1034
+++ b/tests/data/test1034
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
<testcase>
<info>
<keywords>
diff --git a/tests/data/test1046 b/tests/data/test1046
index bc4e5c293..e86e1329c 100644
--- a/tests/data/test1046
+++ b/tests/data/test1046
@@ -40,7 +40,7 @@ HTTP-IPv6 GET with numeric localhost --interface
</command>
# --interface doesn't accept an address surrounded by [] so %CLIENT6IP is out
<precheck>
-perl -e "print 'Test requires default test server host address' if ( '%CLIENT6IP' ne '[::1]' );"
+perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP' ne '[::1]' );"
</precheck>
</client>
diff --git a/tests/data/test1048 b/tests/data/test1048
index f94ae58d1..5ed267b55 100644
--- a/tests/data/test1048
+++ b/tests/data/test1048
@@ -48,7 +48,7 @@ FTP-IPv6 dir list PASV with localhost --interface
</command>
# --interface doesn't accept an address surrounded by [] so %CLIENT6IP is out
<precheck>
-perl -e "print 'Test requires default test server host address' if ( '%CLIENT6IP' ne '[::1]' );"
+perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP' ne '[::1]' );"
</precheck>
</client>
diff --git a/tests/data/test1050 b/tests/data/test1050
index a0e5beab1..281936bfe 100644
--- a/tests/data/test1050
+++ b/tests/data/test1050
@@ -43,7 +43,7 @@ FTP-IPv6 dir list, EPRT with specified IP
</command>
# --interface doesn't accept an address surrounded by [] so %CLIENT6IP is out
<precheck>
-perl -e "print 'Test requires default test server host address' if ( '%CLIENT6IP' ne '[::1]' );"
+perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP' ne '[::1]' );"
</precheck>
</client>
diff --git a/tests/data/test1082 b/tests/data/test1082
index d58dd25cd..8e4078b2d 100644
--- a/tests/data/test1082
+++ b/tests/data/test1082
@@ -35,7 +35,7 @@ HTTP GET with localhost --interface
http://%HOSTIP:%HTTPPORT/1082 --interface localhost
</command>
<precheck>
-perl -e "print 'Test requires default test server host address' if ( '%CLIENTIP' ne '127.0.0.1' );"
+perl -e "print 'Test requires default test client host address' if ( '%CLIENTIP' ne '127.0.0.1' );"
</precheck>
</client>
diff --git a/tests/data/test1083 b/tests/data/test1083
index e441278da..1b1db0539 100644
--- a/tests/data/test1083
+++ b/tests/data/test1083
@@ -39,7 +39,7 @@ HTTP-IPv6 GET with ip6-localhost --interface
-g "http://%HOST6IP:%HTTP6PORT/1083" --interface ip6-localhost
</command>
<precheck>
-perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test server host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
+perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
</precheck>
</client>
diff --git a/tests/data/test1097 b/tests/data/test1097
index 7512a2e7d..7eb7b5f3d 100644
--- a/tests/data/test1097
+++ b/tests/data/test1097
@@ -60,7 +60,7 @@ http://test.a.galaxy.far.far.away.1097:%HTTPPORT/1097 --proxy http://%HOSTIP:%HT
<strip>
^User-Agent: curl/.*
</strip>
-<protocol>
+<protocol nonewline="yes">
CONNECT test.a.galaxy.far.far.away.1097:%HTTPPORT HTTP/1.1
Host: test.a.galaxy.far.far.away.1097:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
@@ -71,9 +71,10 @@ POST /1097 HTTP/1.1
User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.12 libssh2/1.0.1_CVS
Host: test.a.galaxy.far.far.away.1097:%HTTPPORT
Accept: */*
-Content-Length: 0
+Content-Length: 11
Content-Type: application/x-www-form-urlencoded
+dummy=value
</protocol>
</verify>
diff --git a/tests/data/test1133 b/tests/data/test1133
index d71155eda..737f9d9e2 100644
--- a/tests/data/test1133
+++ b/tests/data/test1133
@@ -29,7 +29,7 @@ HTTP RFC1867-type formposting with filename/data contains ',', ';', '"'
http://%HOSTIP:%HTTPPORT/we/want/1133 -F "file=@\"log/test1133,and;.txt\";type=mo/foo;filename=\"faker,and;.txt\"" -F 'file2=@"log/test1133,and;.txt"' -F 'file3=@"log/test1133,and;.txt";type=m/f,"log/test1133,and;.txt"' -F a="{\"field1\":\"value1\",\"field2\":\"value2\"}" -F 'b=" \\value1;type=\"whatever\" "; type=text/foo; charset=utf-8 ; filename=param_b'
</command>
# We create this file before the command is invoked!
-<file name=log/test1133,and;.txt>
+<file name="log/test1133,and;.txt">
foo bar
This is a bar foo
bar
diff --git a/tests/data/test1149 b/tests/data/test1149
index ae081a8a9..f826391e9 100644
--- a/tests/data/test1149
+++ b/tests/data/test1149
@@ -1,5 +1,5 @@
-# based on test1010
<testcase>
+# based on test1010
<info>
<keywords>
FTP
diff --git a/tests/data/test1156 b/tests/data/test1156
index fb4836242..f78dc998f 100644
--- a/tests/data/test1156
+++ b/tests/data/test1156
@@ -67,4 +67,5 @@ http://%HOSTIP:%HTTPPORT/want/1156
<errorcode>
0
</errorcode>
+</verify>
</testcase>
diff --git a/tests/data/test1160 b/tests/data/test1160
index 3fe689e96..63dd0a7a0 100644
--- a/tests/data/test1160
+++ b/tests/data/test1160
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
<testcase>
<info>
<keywords>
diff --git a/tests/data/test1262 b/tests/data/test1262
index 4b08a2cf2..ed526c099 100644
--- a/tests/data/test1262
+++ b/tests/data/test1262
@@ -1,5 +1,5 @@
-# similar to test 139 but with a reversed time condition
<testcase>
+# similar to test 139 but with a reversed time condition
<info>
<keywords>
FTP
diff --git a/tests/data/test1263 b/tests/data/test1263
index 7946916e2..7462db4d4 100644
--- a/tests/data/test1263
+++ b/tests/data/test1263
@@ -1,5 +1,5 @@
-# similar to test 1260
<testcase>
+# similar to test 1260
<info>
<keywords>
HTTP
diff --git a/tests/data/test1291 b/tests/data/test1291
index 12d65f3d8..3f1575184 100644
--- a/tests/data/test1291
+++ b/tests/data/test1291
@@ -1,7 +1,6 @@
+<testcase>
# This test case is primarily meant to verify that parsing and adding the 100K
# files is a swift operation.
-#
-<testcase>
<info>
<keywords>
HTTP
diff --git a/tests/data/test1307 b/tests/data/test1307
index 82ed3c07f..c4f7ac729 100644
--- a/tests/data/test1307
+++ b/tests/data/test1307
@@ -15,6 +15,7 @@ none
</server>
<features>
unittest
+ftp
</features>
<name>
internal Curl_fnmatch() testing
diff --git a/tests/data/test1404 b/tests/data/test1404
index 961cc6630..e98087a24 100644
--- a/tests/data/test1404
+++ b/tests/data/test1404
@@ -94,6 +94,8 @@ s/(USERAGENT, \")[^\"]+/${1}stripped/
$_ = '' if /CURLOPT_SSL_VERIFYPEER/
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
$_ = '' if /CURLOPT_HTTP_VERSION/
+# CURL_DOES_CONVERSION generates an extra comment.
+$_ = '' if /\/\* "value" \*\//
</stripfile>
<file name="log/test1404.c" mode="text">
/********* Sample code generated by the curl command line tool **********
diff --git a/tests/data/test1425 b/tests/data/test1425
index 0044c69d5..ce9ba97fb 100644
--- a/tests/data/test1425
+++ b/tests/data/test1425
Binary files differ
diff --git a/tests/data/test1426 b/tests/data/test1426
index dd6a8d117..851d8c3fb 100644
--- a/tests/data/test1426
+++ b/tests/data/test1426
Binary files differ
diff --git a/tests/data/test1449 b/tests/data/test1449
index d30c13c68..1911b0272 100644
--- a/tests/data/test1449
+++ b/tests/data/test1449
@@ -1,5 +1,5 @@
-# initially based on test110
<testcase>
+# initially based on test110
<info>
<keywords>
FTP
diff --git a/tests/data/test1455 b/tests/data/test1455
index 0b77dc4f5..7276ea4ec 100644
--- a/tests/data/test1455
+++ b/tests/data/test1455
@@ -9,7 +9,7 @@ HTTP GET
#
# Server-side
<reply name="1455">
-<data nocheck=yes>
+<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
diff --git a/tests/data/test1456 b/tests/data/test1456
index 07a6e7c03..007473618 100644
--- a/tests/data/test1456
+++ b/tests/data/test1456
@@ -9,7 +9,7 @@ IPv6
#
# Server-side
<reply>
-<data nocheck=yes>
+<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
@@ -21,7 +21,7 @@ Connection: close
Content-Type: text/html
Funny-head: yesyes
--foo-
+These data aren't actually sent to the client
</data>
</reply>
diff --git a/tests/data/test1457 b/tests/data/test1457
index aad6d43d4..575748f46 100644
--- a/tests/data/test1457
+++ b/tests/data/test1457
@@ -29,7 +29,7 @@ http
Check if %{stderr} and %{stdout} switch between stdout and stderr.
</name>
<command>
-http://%HOSTIP:%HTTPPORT/1457 --write-out 'line1%{stderr}line2%{stdout}line3'
+http://%HOSTIP:%HTTPPORT/1457 --silent --write-out 'line1%{stderr}line2%{stdout}line3'
</command>
</client>
@@ -45,7 +45,6 @@ Content-Type: text/plain
testdata
line1line3
</stdout>
-#note: as of now <stderr> doesn't actually exist in runtests.pl
<stderr nonewline="yes">
line2
</stderr>
diff --git a/tests/data/test1506 b/tests/data/test1506
index 815fef923..7377dd6e0 100644
--- a/tests/data/test1506
+++ b/tests/data/test1506
@@ -88,9 +88,13 @@ Accept: */*
* Connection #2 to host server3.example.com left intact
* Closing connection 0
* Connection #3 to host server4.example.com left intact
+* Closing connection
+* Closing connection
+* Closing connection
</file>
<stripfile>
$_ = '' if (($_ !~ /left intact/) && ($_ !~ /Closing connection/))
+s/^(\* Closing connection) [123](?=\r?\n)/$1/
</stripfile>
</verify>
</testcase>
diff --git a/tests/data/test1541 b/tests/data/test1541
new file mode 100644
index 000000000..e18bb47df
--- /dev/null
+++ b/tests/data/test1541
@@ -0,0 +1,34 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+multi-threaded
+connection-sharing
+</keywords>
+</info>
+
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<tool>
+lib1541
+</tool>
+ <name>
+connection sharing using 67 parallel threads for 7 seconds
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/1
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+</verify>
+</testcase>
diff --git a/tests/data/test1561 b/tests/data/test1561
index ff448c95f..69352fda2 100644
--- a/tests/data/test1561
+++ b/tests/data/test1561
@@ -18,6 +18,15 @@ Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Set-Cookie: super=secret; domain=example.com; path=/1561; secure;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login/; secure;
+Set-Cookie: __Secure-SID=12345; Domain=example.com
+Set-Cookie: __Secure-SID=12346; Secure; Domain=example.com
+Set-Cookie: supersupersuper=secret; __Secure-SID=12346; Secure; Domain=example.com
+Set-Cookie: __Host-SID=22345
+Set-Cookie: __Host-SID=22346; Secure
+Set-Cookie: __Host-SID=22347; Domain=example.com
+Set-Cookie: __Host-SID=22348; Domain=example.com; Path=/
+Set-Cookie: __Host-SID=22349; Secure; Domain=example.com; Path=/
+Set-Cookie: __Host-SID=12346; Secure; Path=/
Content-Length: 7
nomnom
@@ -33,6 +42,14 @@ Set-Cookie: public=yes; domain=example.com; path=/foo;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login/en;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login;
Set-Cookie: secureoverhttp=yes; domain=example.com; path=/1561; secure;
+Set-Cookie: __Secure-SID=22345; Domain=example.com
+Set-Cookie: __Secure-SID=22346; Secure; Domain=example.com
+Set-Cookie: __Host-SID=32345
+Set-Cookie: __Host-SID=32346; Secure
+Set-Cookie: __Host-SID=32347; Domain=example.com
+Set-Cookie: __Host-SID=32348; Domain=example.com; Path=/
+Set-Cookie: __Host-SID=32349; Secure; Domain=example.com; Path=/
+Set-Cookie: __Host-SID=32350; Secure; Path=/
Content-Length: 7
nomnom
@@ -77,6 +94,9 @@ Accept: */*
# This file was generated by libcurl! Edit at your own risk.
.example.com TRUE /foo FALSE 0 public yes
+www.example.com FALSE / TRUE 0 __Host-SID 12346
+.example.com TRUE / TRUE 0 supersupersuper secret
+.example.com TRUE / TRUE 0 __Secure-SID 12346
.example.com TRUE /1561/login/ TRUE 0 supersuper secret
#HttpOnly_.example.com TRUE /15 FALSE 0 super secret
</file>
diff --git a/tests/data/test1654 b/tests/data/test1654
new file mode 100644
index 000000000..175076c8a
--- /dev/null
+++ b/tests/data/test1654
@@ -0,0 +1,58 @@
+<testcase>
+<info>
+<keywords>
+unittest
+alt-svc
+altsvc
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<features>
+unittest
+alt-svc
+</features>
+
+# This date is exactly "20190124 22:34:21" UTC
+<setenv>
+CURL_TIME=1548369261
+</setenv>
+<name>
+alt-svc
+</name>
+<command>
+log/1654
+</command>
+<tool>
+unit1654
+</tool>
+<file name="log/1654" mode="text">
+h2 example.com 443 h3 shiny.example.com 8443 "20191231 00:00:00" 0 1
+# a comment
+h2c example.com 443 h3 shiny.example.com 8443 "20291231 23:30:00" 0 1
+ h1 example.com 443 h3 shiny.example.com 8443 "20121231 00:00:01" 0 1
+ h3 example.com 443 h3 shiny.example.com 8443 "20131231 00:00:00" 0 1
+ # also a comment
+bad example.com 443 h3 shiny.example.com 8443 "20191231 00:00:00" 0 1
+rubbish
+</file>
+</client>
+<verify>
+<file name="log/1654-out" mode="text">
+# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# This file was generated by libcurl! Edit at your own risk.
+h2 example.com 443 h3 shiny.example.com 8443 "20191231 00:00:00" 0 1
+h2c example.com 443 h3 shiny.example.com 8443 "20291231 23:30:00" 0 1
+h1 example.com 443 h3 shiny.example.com 8443 "20121231 00:00:01" 0 1
+h3 example.com 443 h3 shiny.example.com 8443 "20131231 00:00:00" 0 1
+h1 example.org 8080 h2 example.com 8080 "20190125 22:34:21" 0 0
+h1 2.example.org 8080 h3 2.example.org 8080 "20190125 22:34:21" 0 0
+h1 3.example.org 8080 h2 example.com 8080 "20190125 22:34:21" 0 0
+h1 3.example.org 8080 h3 yesyes.com 8080 "20190125 22:34:21" 0 0
+h2c example.org 80 h2 example.com 443 "20190124 22:36:21" 0 0
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test1905 b/tests/data/test1905
new file mode 100644
index 000000000..0459b10b4
--- /dev/null
+++ b/tests/data/test1905
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+cookies
+FLUSH
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Type: text/html
+Funny-head: yesyes swsclose
+Set-Cookie: foobar=name;
+Set-Cookie: secondcookie=present;
+
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+CURLOPT_COOKIELIST set to "FLUSH" of a shared cookie object
+ </name>
+<tool>
+lib1905
+</tool>
+<command>
+http://%HOSTIP:%HTTPPORT/we/want/1905
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /we/want/1905 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<file name="log/cookies1905" mode="text">
+# Netscape HTTP Cookie File
+# https://curl.haxx.se/docs/http-cookies.html
+# This file was generated by libcurl! Edit at your own risk.
+
+%HOSTIP FALSE /we/want/ FALSE 0 secondcookie present
+%HOSTIP FALSE /we/want/ FALSE 0 foobar name
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test2056 b/tests/data/test2056
index f00e21204..5d2584eec 100644
--- a/tests/data/test2056
+++ b/tests/data/test2056
@@ -8,17 +8,7 @@ HTTP Negotiate auth (stub krb5)
</info>
# Server-side
<reply>
-<!-- First request, expect 401 Negotiate -->
-<data>
-HTTP/1.1 401 Authorization Required
-Server: Microsoft-IIS/7.0
-Content-Type: text/html; charset=iso-8859-1
-WWW-Authenticate: Negotiate
-Content-Length: 13
-
-Not yet sir!
-</data>
-<!-- Second request, expect success in one shot -->
+<!-- First request, expect success in one shot -->
<data1>
HTTP/1.1 200 Things are fine in server land
Server: Microsoft-IIS/7.0
@@ -29,12 +19,6 @@ Content-Length: 15
Nice auth sir!
</data1>
<datacheck>
-HTTP/1.1 401 Authorization Required
-Server: Microsoft-IIS/7.0
-Content-Type: text/html; charset=iso-8859-1
-WWW-Authenticate: Negotiate
-Content-Length: 13
-
HTTP/1.1 200 Things are fine in server land
Server: Microsoft-IIS/7.0
Content-Type: text/html; charset=iso-8859-1
@@ -75,10 +59,6 @@ CURL_STUB_GSS_CREDS="KRB5_Alice"
<protocol>
GET /2056 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /2056 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
Authorization: Negotiate IktSQjVfQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjE6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
Accept: */*
diff --git a/tests/data/test2057 b/tests/data/test2057
index 562505168..92d7824c1 100644
--- a/tests/data/test2057
+++ b/tests/data/test2057
@@ -8,17 +8,7 @@ HTTP Negotiate auth (stub ntlm)
</info>
# Server-side
<reply>
-<!-- First request, expect 401 Negotiate -->
-<data>
-HTTP/1.1 401 Authorization Required
-Server: Microsoft-IIS/7.0
-Content-Type: text/html; charset=iso-8859-1
-WWW-Authenticate: Negotiate
-Content-Length: 13
-
-Not yet sir!
-</data>
-<!-- Second request, expect 401 (ntlm challenge) -->
+<!-- First request, expect 401 (ntlm challenge) -->
<data1>
HTTP/1.1 401 Authorization Required
Server: Microsoft-IIS/7.0
@@ -28,7 +18,7 @@ Content-Length: 19
Still not yet sir!
</data1>
-<!-- Third request, expect success -->
+<!-- Second request, expect success -->
<data2>
HTTP/1.1 200 Things are fine in server land
Server: Microsoft-IIS/7.0
@@ -42,12 +32,6 @@ Nice auth sir!
HTTP/1.1 401 Authorization Required
Server: Microsoft-IIS/7.0
Content-Type: text/html; charset=iso-8859-1
-WWW-Authenticate: Negotiate
-Content-Length: 13
-
-HTTP/1.1 401 Authorization Required
-Server: Microsoft-IIS/7.0
-Content-Type: text/html; charset=iso-8859-1
WWW-Authenticate: Negotiate Qw==
Content-Length: 19
@@ -91,10 +75,6 @@ CURL_STUB_GSS_CREDS="NTLM_Alice"
<protocol>
GET /2057 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /2057 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
Authorization: Negotiate Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjI6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
Accept: */*
diff --git a/tests/data/test327 b/tests/data/test327
index 1aa672d0c..3a1c07162 100644
--- a/tests/data/test327
+++ b/tests/data/test327
@@ -31,7 +31,7 @@ Content-Type: text/html
Funny-head: yesyes swsclose
Set-Cookie: foobar=name; expires=Thu, 01 Jan 1970 00:00:00 GMT;
-</data>
+</data2>
</reply>
# Client-side
diff --git a/tests/data/test331 b/tests/data/test331
new file mode 100644
index 000000000..54b86d2a1
--- /dev/null
+++ b/tests/data/test331
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+cookies
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Type: text/html
+Content-Length: 4
+Set-Cookie: moo=yes;
+
+hej
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Type: text/html
+Content-Length: 0
+Funny-head: yesyes swsclose
+
+</data2>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with cookie using host name 'moo'
+ </name>
+ <command>
+-x http://%HOSTIP:%HTTPPORT http://moo/we/want/331 -b none http://moo/we/want/3310002
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://moo/we/want/331 HTTP/1.1
+Host: moo
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+GET http://moo/we/want/3310002 HTTP/1.1
+Host: moo
+Accept: */*
+Proxy-Connection: Keep-Alive
+Cookie: moo=yes
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test355 b/tests/data/test355
new file mode 100644
index 000000000..e9c4cb28f
--- /dev/null
+++ b/tests/data/test355
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+Alt-Svc
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+alt-svc
+</features>
+<server>
+http
+</server>
+ <name>
+load Alt-Svc from file and use
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/355 --alt-svc ""
+</command>
+<file name="log/altsvc-355">
+h1 example.com 80 h1 %HOSTIP %HTTPPORT "20290222 22:19:28" 0 0
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /355 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test356 b/tests/data/test356
new file mode 100644
index 000000000..e2ac4860d
--- /dev/null
+++ b/tests/data/test356
@@ -0,0 +1,70 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+Alt-Svc
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+Alt-Svc: h1="nowhere.foo:81"
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+debug
+alt-svc
+</features>
+<server>
+http
+</server>
+ <name>
+parse incoming Alt-Svc and save to file
+ </name>
+<setenv>
+# make debug-curl accept Alt-Svc over plain HTTP
+CURL_ALTSVC_HTTP="yeah"
+</setenv>
+ <command>
+http://%HOSTIP:%HTTPPORT/356 --alt-svc "log/altsvc-356"
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /356 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<stripfile>
+# strip out the (dynamic) expire date from the file so that the rest
+# matches
+s/\"([^\"]*)\"/TIMESTAMP/
+</stripfile>
+<file name="log/altsvc-356">
+# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# This file was generated by libcurl! Edit at your own risk.
+h1 %HOSTIP %HTTPPORT h1 nowhere.foo 81 TIMESTAMP 0 0
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test506 b/tests/data/test506
index 30f4aa9c0..8f06e0e4f 100644
--- a/tests/data/test506
+++ b/tests/data/test506
@@ -228,9 +228,6 @@ lock: share [Pigs in space]: 94
unlock: share [Pigs in space]: 95
GLOBAL_CLEANUP
</stdout>
-<stderr>
-http://%HOSTIP:%HTTPPORT/506
-</stderr>
<file name="log/jar506" mode="text">
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
diff --git a/tests/data/test578 b/tests/data/test578
index abbe49a3c..788ed72f0 100644
--- a/tests/data/test578
+++ b/tests/data/test578
@@ -38,7 +38,7 @@ lib578
HTTP POST lower than MAX_INITIAL_POST_SIZE with progress callback
</name>
<command>
-http://%HOSTIP:%HTTPPORT/500 log/ip578
+http://%HOSTIP:%HTTPPORT/578 log/ip578
</command>
</client>
diff --git a/tests/data/test597 b/tests/data/test597
index 458bb6453..3eb9ed8b8 100644
--- a/tests/data/test597
+++ b/tests/data/test597
@@ -31,7 +31,6 @@ ftp://%HOSTIP:%FTPPORT
USER anonymous
PASS ftp@example.com
PWD
-QUIT
</protocol>
</verify>
</testcase>
diff --git a/tests/data/test658 b/tests/data/test658
index c75293c6d..2ed6d6429 100644
--- a/tests/data/test658
+++ b/tests/data/test658
@@ -3,6 +3,7 @@
<keywords>
HTTP
HTTP GET
+CURLOPT_CURLU
</keywords>
</info>
<reply>
@@ -29,7 +30,7 @@ http
lib658
</tool>
<name>
-HTTP GET
+Pass URL to libcurl with CURLOPT_CURLU
</name>
<command>
http://%HOSTIP:%HTTPPORT/658
@@ -45,6 +46,7 @@ GET /658 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
+</protocol>
</verify>
</testcase>
diff --git a/tests/data/test659 b/tests/data/test659
new file mode 100644
index 000000000..43e1aaf92
--- /dev/null
+++ b/tests/data/test659
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+CURLOPT_CURLU
+proxy
+</keywords>
+</info>
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+<client>
+<server>
+http
+</server>
+<tool>
+lib659
+</tool>
+<name>
+CURLOPT_CURLU without the path set - over proxy
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT
+</command>
+</client>
+
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://www.example.com:80/ HTTP/1.1
+Host: www.example.com
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+
+</testcase>
diff --git a/tests/data/test8 b/tests/data/test8
index e6d0f500e..2fc190060 100644
--- a/tests/data/test8
+++ b/tests/data/test8
@@ -46,7 +46,6 @@ Set-Cookie: trailingspace = removed; path=/we/want;
Set-Cookie: nocookie=yes; path=/WE;
Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad;
Set-Cookie: partialip=nono; domain=.0.0.1;
-Set-Cookie: chocolate=chip; domain=curl; path=/we/want;
</file>
<precheck>
diff --git a/tests/fuzz/download_fuzzer.sh b/tests/fuzz/download_fuzzer.sh
index adc3ec53d..b19fbb7ba 100755
--- a/tests/fuzz/download_fuzzer.sh
+++ b/tests/fuzz/download_fuzzer.sh
@@ -4,4 +4,4 @@
set -ex
# Clone the curl-fuzzer repository to the specified directory.
-git clone https://github.com/curl/curl-fuzzer $1
+git clone --depth=1 https://github.com/curl/curl-fuzzer "$1"
diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
index f4c76c5b7..a2281c456 100644
--- a/tests/libtest/Makefile.am
+++ b/tests/libtest/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -131,8 +131,13 @@ endif
lib1521.c: $(top_srcdir)/tests/libtest/mk-lib1521.pl $(top_srcdir)/include/gnurl/curl.h
@PERL@ $(top_srcdir)/tests/libtest/mk-lib1521.pl < $(top_srcdir)/include/gnurl/curl.h > lib1521.c
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+ $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 2e5236fad..e38f48102 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -22,18 +22,19 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib571 lib572 lib573 lib574 lib575 lib576 lib578 lib579 lib582 \
lib583 lib585 lib586 lib587 lib589 lib590 lib591 lib597 lib598 lib599 \
lib643 lib644 lib645 lib650 lib651 lib652 lib653 lib654 lib655 lib658 \
+ lib659 \
lib1156 \
lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \
lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515 lib1517 \
lib1518 lib1520 lib1521 lib1522 \
lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 lib1533 \
lib1534 lib1535 lib1536 lib1537 lib1538 \
- lib1540 \
+ lib1540 lib1541 \
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
lib1558 \
lib1560 \
lib1591 lib1592 \
- lib1900 \
+ lib1900 lib1905 \
lib2033
chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \
@@ -345,6 +346,10 @@ lib658_SOURCES = lib658.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib658_LDADD = $(TESTUTIL_LIBS)
lib658_CPPFLAGS = $(AM_CPPFLAGS)
+lib659_SOURCES = lib659.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib659_LDADD = $(TESTUTIL_LIBS)
+lib659_CPPFLAGS = $(AM_CPPFLAGS)
+
lib1500_SOURCES = lib1500.c $(SUPPORTFILES) $(TESTUTIL)
lib1500_LDADD = $(TESTUTIL_LIBS)
lib1500_CPPFLAGS = $(AM_CPPFLAGS)
@@ -488,6 +493,10 @@ lib1540_SOURCES = lib1540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1540_LDADD = $(TESTUTIL_LIBS)
lib1540_CPPFLAGS = $(AM_CPPFLAGS)
+lib1541_SOURCES = lib1541.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1541_LDADD = $(TESTUTIL_LIBS)
+lib1541_CPPFLAGS = $(AM_CPPFLAGS)
+
lib1550_SOURCES = lib1550.c $(SUPPORTFILES)
lib1550_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1517
@@ -535,6 +544,10 @@ lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1900_LDADD = $(TESTUTIL_LIBS)
lib1900_CPPFLAGS = $(AM_CPPFLAGS)
+lib1905_SOURCES = lib1905.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1905_LDADD = $(TESTUTIL_LIBS)
+lib1905_CPPFLAGS = $(AM_CPPFLAGS)
+
lib2033_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib2033_LDADD = $(TESTUTIL_LIBS)
lib2033_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_PIPELINING
diff --git a/tests/libtest/first.c b/tests/libtest/first.c
index 405e6f84a..d687bf276 100644
--- a/tests/libtest/first.c
+++ b/tests/libtest/first.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -96,7 +96,7 @@ static void memory_tracking_init(void)
env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
strcpy(fname, env);
curl_free(env);
- curl_memdebug(fname);
+ curl_dbg_memdebug(fname);
/* this weird stuff here is to make curl_free() get called
before curl_memdebug() as otherwise memory tracking will
log a free() without an alloc! */
@@ -107,7 +107,7 @@ static void memory_tracking_init(void)
char *endptr;
long num = strtol(env, &endptr, 10);
if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
- curl_memlimit(num);
+ curl_dbg_memlimit(num);
curl_free(env);
}
}
diff --git a/tests/libtest/lib1537.c b/tests/libtest/lib1537.c
index 9832c3a30..7c5dde042 100644
--- a/tests/libtest/lib1537.c
+++ b/tests/libtest/lib1537.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -30,7 +30,7 @@ int test(char *URL)
CURLcode res = CURLE_OK;
char *ptr = NULL;
int asize;
- int outlen;
+ int outlen = 0;
char *raw;
(void)URL; /* we don't use this */
diff --git a/tests/libtest/lib1541.c b/tests/libtest/lib1541.c
new file mode 100644
index 000000000..983a47e01
--- /dev/null
+++ b/tests/libtest/lib1541.c
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, 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 https://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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#include <time.h>
+
+/* number of threads to fire up in parallel */
+#define NUM_THREADS 67
+
+/* for how many seconds each thread will loop */
+#define RUN_FOR_SECONDS 7
+
+static pthread_mutex_t connlock;
+
+static size_t write_db(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ /* not interested in the downloaded bytes, return the size */
+ (void)ptr; /* unused */
+ (void)data; /* unused */
+ return (size_t)(size * nmemb);
+}
+
+static void lock_cb(CURL *handle, curl_lock_data data,
+ curl_lock_access access, void *userptr)
+{
+ (void)access; /* unused */
+ (void)userptr; /* unused */
+ (void)handle; /* unused */
+ (void)data; /* unused */
+ pthread_mutex_lock(&connlock);
+}
+
+static void unlock_cb(CURL *handle, curl_lock_data data,
+ void *userptr)
+{
+ (void)userptr; /* unused */
+ (void)handle; /* unused */
+ (void)data; /* unused */
+ pthread_mutex_unlock(&connlock);
+}
+
+static void init_locks(void)
+{
+ pthread_mutex_init(&connlock, NULL);
+}
+
+static void kill_locks(void)
+{
+ pthread_mutex_destroy(&connlock);
+}
+
+struct initurl {
+ const char *url;
+ CURLSH *share;
+ int threadno;
+};
+
+static void *run_thread(void *ptr)
+{
+ struct initurl *u = (struct initurl *)ptr;
+ int i;
+ time_t end = time(NULL) + RUN_FOR_SECONDS;
+
+ for(i = 0; time(NULL) < end; i++) {
+ CURL *curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_URL, u->url);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(curl, CURLOPT_SHARE, u->share);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_db);
+ curl_easy_perform(curl); /* ignores error */
+ curl_easy_cleanup(curl);
+ fprintf(stderr, "Thread %d transfer %d\n", u->threadno, i);
+ }
+
+ return NULL;
+}
+
+int test(char *URL)
+{
+ pthread_t tid[NUM_THREADS];
+ int i;
+ int error;
+ CURLSH *share;
+ struct initurl url[NUM_THREADS];
+
+ /* Must initialize libcurl before any threads are started */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ share = curl_share_init();
+ curl_share_setopt(share, CURLSHOPT_LOCKFUNC, lock_cb);
+ curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, unlock_cb);
+ curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
+
+ init_locks();
+
+ for(i = 0; i< NUM_THREADS; i++) {
+ url[i].url = URL;
+ url[i].share = share;
+ url[i].threadno = i;
+ error = pthread_create(&tid[i], NULL, run_thread, &url[i]);
+ if(0 != error)
+ fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
+ else
+ fprintf(stderr, "Thread %d, gets %s\n", i, URL);
+ }
+
+ /* now wait for all threads to terminate */
+ for(i = 0; i< NUM_THREADS; i++) {
+ error = pthread_join(tid[i], NULL);
+ fprintf(stderr, "Thread %d terminated\n", i);
+ }
+
+ kill_locks();
+
+ curl_share_cleanup(share);
+ curl_global_cleanup();
+ return 0;
+}
+
+#else /* without pthread, this test doesn't work */
+int test(char *URL)
+{
+ (void)URL;
+ return 0;
+}
+#endif
diff --git a/tests/libtest/lib1555.c b/tests/libtest/lib1555.c
index e4f2255ac..f7193b5be 100644
--- a/tests/libtest/lib1555.c
+++ b/tests/libtest/lib1555.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -36,14 +36,16 @@ static int progressCallback(void *arg,
double ulnow)
{
CURLcode res = 0;
+ char buffer[256];
+ size_t n = 0;
(void)arg;
(void)dltotal;
(void)dlnow;
(void)ultotal;
(void)ulnow;
- res = curl_easy_recv(curl, NULL, 0, NULL);
+ res = curl_easy_recv(curl, buffer, 256, &n);
printf("curl_easy_recv returned %d\n", res);
- res = curl_easy_send(curl, NULL, 0, NULL);
+ res = curl_easy_send(curl, buffer, n, &n);
printf("curl_easy_send returned %d\n", res);
return 1;
diff --git a/tests/libtest/lib1900.c b/tests/libtest/lib1900.c
index 1e10bdf34..2a70f8eba 100644
--- a/tests/libtest/lib1900.c
+++ b/tests/libtest/lib1900.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2018, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2013 - 2019, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -138,7 +138,7 @@ int test(char *URL)
CURLM *m = NULL;
CURLMsg *msg; /* for picking up messages with the transfer status */
int msgs_left; /* how many messages are left */
- int running;
+ int running = 0;
int handlenum = 0;
struct timeval last_handle_add;
diff --git a/tests/libtest/lib1905.c b/tests/libtest/lib1905.c
new file mode 100644
index 000000000..b09c4f526
--- /dev/null
+++ b/tests/libtest/lib1905.c
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, 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 https://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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLM *cm = NULL;
+ CURLSH *sh = NULL;
+ CURL *ch = NULL;
+ int unfinished;
+
+ cm = curl_multi_init();
+ if(!cm)
+ return 1;
+ sh = curl_share_init();
+ if(!sh)
+ goto cleanup;
+
+ curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+
+ ch = curl_easy_init();
+ if(!ch)
+ goto cleanup;
+
+ curl_easy_setopt(ch, CURLOPT_SHARE, sh);
+ curl_easy_setopt(ch, CURLOPT_URL, URL);
+ curl_easy_setopt(ch, CURLOPT_COOKIEFILE, "log/cookies1905");
+ curl_easy_setopt(ch, CURLOPT_COOKIEJAR, "log/cookies1905");
+
+ curl_multi_add_handle(cm, ch);
+
+ unfinished = 1;
+ while(unfinished) {
+ int MAX = 0;
+ long max_tout;
+ fd_set R, W, E;
+ struct timeval timeout;
+
+ FD_ZERO(&R);
+ FD_ZERO(&W);
+ FD_ZERO(&E);
+ curl_multi_perform(cm, &unfinished);
+
+ curl_multi_fdset(cm, &R, &W, &E, &MAX);
+ curl_multi_timeout(cm, &max_tout);
+
+ if(max_tout > 0) {
+ timeout.tv_sec = max_tout / 1000;
+ timeout.tv_usec = (max_tout % 1000) * 1000;
+ }
+ else {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1000;
+ }
+
+ select(MAX + 1, &R, &W, &E, &timeout);
+ }
+
+ curl_easy_setopt(ch, CURLOPT_COOKIELIST, "FLUSH");
+ curl_easy_setopt(ch, CURLOPT_SHARE, NULL);
+
+ curl_multi_remove_handle(cm, ch);
+ cleanup:
+ curl_easy_cleanup(ch);
+ curl_share_cleanup(sh);
+ curl_multi_cleanup(cm);
+
+ return 0;
+}
diff --git a/tests/libtest/lib556.c b/tests/libtest/lib556.c
index 69b2c09dd..0595000ce 100644
--- a/tests/libtest/lib556.c
+++ b/tests/libtest/lib556.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -70,7 +70,7 @@ int test(char *URL)
"GET /556 HTTP/1.2\r\n"
"Host: ninja\r\n\r\n";
#endif
- size_t iolen;
+ size_t iolen = 0;
res = curl_easy_send(curl, request, strlen(request), &iolen);
diff --git a/tests/libtest/lib597.c b/tests/libtest/lib597.c
index d7f38c4c8..e34505cd2 100644
--- a/tests/libtest/lib597.c
+++ b/tests/libtest/lib597.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -32,20 +32,12 @@
/*
* Test case for below scenario:
* - Connect to an FTP server using CONNECT_ONLY option
- * - transfer some files with re-using the connection (omitted in test case)
- * - Disconnect from FTP server with sending QUIT command
*
* The test case originated for verifying CONNECT_ONLY option shall not
* block after protocol connect is done, but it returns the message
* with function curl_multi_info_read().
*/
-enum {
- CONNECT_ONLY_PHASE = 0,
- QUIT_PHASE,
- LAST_PHASE
-};
-
int test(char *URL)
{
CURL *easy = NULL;
@@ -53,7 +45,6 @@ int test(char *URL)
int res = 0;
int running;
int msgs_left;
- int phase;
CURLMsg *msg;
start_test_timing();
@@ -64,76 +55,65 @@ int test(char *URL)
multi_init(multi);
- for(phase = CONNECT_ONLY_PHASE; phase < LAST_PHASE; ++phase) {
- /* go verbose */
- easy_setopt(easy, CURLOPT_VERBOSE, 1L);
-
- /* specify target */
- easy_setopt(easy, CURLOPT_URL, URL);
-
- /* enable 'CONNECT_ONLY' option when in connect phase */
- if(phase == CONNECT_ONLY_PHASE)
- easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L);
-
- /* enable 'NOBODY' option to send 'QUIT' command in quit phase */
- if(phase == QUIT_PHASE) {
- easy_setopt(easy, CURLOPT_CONNECT_ONLY, 0L);
- easy_setopt(easy, CURLOPT_NOBODY, 1L);
- easy_setopt(easy, CURLOPT_FORBID_REUSE, 1L);
- }
+ /* go verbose */
+ easy_setopt(easy, CURLOPT_VERBOSE, 1L);
- multi_add_handle(multi, easy);
+ /* specify target */
+ easy_setopt(easy, CURLOPT_URL, URL);
- for(;;) {
- struct timeval interval;
- fd_set fdread;
- fd_set fdwrite;
- fd_set fdexcep;
- long timeout = -99;
- int maxfd = -99;
+ easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L);
- multi_perform(multi, &running);
+ multi_add_handle(multi, easy);
- abort_on_test_timeout();
+ for(;;) {
+ struct timeval interval;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ long timeout = -99;
+ int maxfd = -99;
- if(!running)
- break; /* done */
+ multi_perform(multi, &running);
- FD_ZERO(&fdread);
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcep);
+ abort_on_test_timeout();
- multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+ if(!running)
+ break; /* done */
- /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
- multi_timeout(multi, &timeout);
+ multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
- /* At this point, timeout is guaranteed to be greater or equal than
- -1. */
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
- if(timeout != -1L) {
- int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
- interval.tv_sec = itimeout/1000;
- interval.tv_usec = (itimeout%1000)*1000;
- }
- else {
- interval.tv_sec = TEST_HANG_TIMEOUT/1000 + 1;
- interval.tv_usec = 0;
- }
+ multi_timeout(multi, &timeout);
- select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &interval);
+ /* At this point, timeout is guaranteed to be greater or equal than
+ -1. */
- abort_on_test_timeout();
+ if(timeout != -1L) {
+ int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+ interval.tv_sec = itimeout/1000;
+ interval.tv_usec = (itimeout%1000)*1000;
+ }
+ else {
+ interval.tv_sec = TEST_HANG_TIMEOUT/1000 + 1;
+ interval.tv_usec = 0;
}
- msg = curl_multi_info_read(multi, &msgs_left);
- if(msg)
- res = msg->data.result;
+ select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &interval);
- multi_remove_handle(multi, easy);
+ abort_on_test_timeout();
}
+ msg = curl_multi_info_read(multi, &msgs_left);
+ if(msg)
+ res = msg->data.result;
+
+ multi_remove_handle(multi, easy);
+
test_cleanup:
/* undocumented cleanup sequence - type UA */
diff --git a/tests/libtest/lib659.c b/tests/libtest/lib659.c
new file mode 100644
index 000000000..b37e8e940
--- /dev/null
+++ b/tests/libtest/lib659.c
@@ -0,0 +1,75 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+/*
+ * Get a single URL without select().
+ */
+
+int test(char *URL)
+{
+ CURL *handle = NULL;
+ CURLcode res = 0;
+ CURLU *urlp = NULL;
+
+ global_init(CURL_GLOBAL_ALL);
+ easy_init(handle);
+
+ urlp = curl_url();
+
+ if(!urlp) {
+ fprintf(stderr, "problem init URL api.");
+ goto test_cleanup;
+ }
+
+ /* this doesn't set the PATH part */
+ if(curl_url_set(urlp, CURLUPART_HOST, "www.example.com", 0) ||
+ curl_url_set(urlp, CURLUPART_SCHEME, "http", 0) ||
+ curl_url_set(urlp, CURLUPART_PORT, "80", 0)) {
+ fprintf(stderr, "problem setting CURLUPART");
+ goto test_cleanup;
+ }
+
+ easy_setopt(handle, CURLOPT_CURLU, urlp);
+ easy_setopt(handle, CURLOPT_VERBOSE, 1L);
+ easy_setopt(handle, CURLOPT_PROXY, URL);
+
+ res = curl_easy_perform(handle);
+
+ if(res) {
+ fprintf(stderr, "%s:%d curl_easy_perform() failed with code %d (%s)\n",
+ __FILE__, __LINE__, res, curl_easy_strerror(res));
+ goto test_cleanup;
+ }
+
+test_cleanup:
+
+ curl_url_cleanup(urlp);
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/stub_gssapi.c b/tests/libtest/stub_gssapi.c
index 377b75452..873e263dc 100644
--- a/tests/libtest/stub_gssapi.c
+++ b/tests/libtest/stub_gssapi.c
@@ -44,15 +44,15 @@ enum min_err_code {
GSS_LAST
};
-const char *min_err_table[] = {
- "stub-gss: no error",
- "stub-gss: no memory",
- "stub-gss: invalid arguments",
- "stub-gss: invalid credentials",
- "stub-gss: invalid context",
- "stub-gss: server returned error",
- "stub-gss: cannot find a mechanism",
- NULL
+static const char *min_err_table[] = {
+ "stub-gss: no error",
+ "stub-gss: no memory",
+ "stub-gss: invalid arguments",
+ "stub-gss: invalid credentials",
+ "stub-gss: invalid context",
+ "stub-gss: server returned error",
+ "stub-gss: cannot find a mechanism",
+ NULL
};
struct gss_ctx_id_t_desc_struct {
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 5e9aa78e5..82e83e15b 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -233,6 +233,7 @@ my $has_crypto; # set if libcurl is built with cryptographic support
my $has_cares; # set if built with c-ares
my $has_threadedres;# set if built with threaded resolver
my $has_psl; # set if libcurl is built with PSL support
+my $has_altsvc; # set if libcurl is built with alt-svc support
my $has_ldpreload; # set if curl is built for systems supporting LD_PRELOAD
my $has_multissl; # set if curl is build with MultiSSL support
my $has_manual; # set if curl is built with built-in manual
@@ -257,7 +258,6 @@ my $has_sslpinning; # built with a TLS backend that supports pinning
my $has_shared = "unknown"; # built shared
my $resolver; # name of the resolver backend (for human presentation)
-my $ssllib; # name of the SSL library we use (for human presentation)
my $has_textaware; # set if running on a system that has a text mode concept
# on files. Windows for example
@@ -2688,55 +2688,45 @@ sub checksystem {
# Win32-style path.
$pwd = pathhelp::sys_native_current_path();
}
- if ($libcurl =~ /winssl/i) {
+ if ($libcurl =~ /(winssl|schannel)/i) {
$has_winssl=1;
$has_sslpinning=1;
- $ssllib="WinSSL";
}
elsif ($libcurl =~ /openssl/i) {
$has_openssl=1;
$has_sslpinning=1;
- $ssllib="OpenSSL";
}
elsif ($libcurl =~ /gnutls/i) {
$has_gnutls=1;
$has_sslpinning=1;
- $ssllib="GnuTLS";
}
elsif ($libcurl =~ /nss/i) {
$has_nss=1;
$has_sslpinning=1;
- $ssllib="NSS";
}
elsif ($libcurl =~ /(yassl|wolfssl)/i) {
$has_yassl=1;
$has_sslpinning=1;
- $ssllib="yassl";
}
elsif ($libcurl =~ /polarssl/i) {
$has_polarssl=1;
$has_sslpinning=1;
- $ssllib="polarssl";
}
elsif ($libcurl =~ /securetransport/i) {
$has_darwinssl=1;
$has_sslpinning=1;
- $ssllib="DarwinSSL";
}
elsif ($libcurl =~ /BoringSSL/i) {
$has_boringssl=1;
$has_sslpinning=1;
- $ssllib="BoringSSL";
}
elsif ($libcurl =~ /libressl/i) {
$has_libressl=1;
$has_sslpinning=1;
- $ssllib="libressl";
}
elsif ($libcurl =~ /mbedTLS/i) {
$has_mbedtls=1;
$has_sslpinning=1;
- $ssllib="mbedTLS";
}
if ($libcurl =~ /ares/i) {
$has_cares=1;
@@ -2744,7 +2734,6 @@ sub checksystem {
}
if ($libcurl =~ /mesalink/i) {
$has_mesalink=1;
- $ssllib="MesaLink";
}
}
elsif($_ =~ /^Protocols: (.*)/i) {
@@ -2850,6 +2839,10 @@ sub checksystem {
# PSL enabled
$has_psl=1;
}
+ if($feat =~ /alt-svc/i) {
+ # alt-svc enabled
+ $has_altsvc=1;
+ }
if($feat =~ /AsynchDNS/i) {
if(!$has_cares) {
# this means threaded resolver
@@ -3279,7 +3272,7 @@ sub singletest {
next;
}
}
- elsif($1 eq "WinSSL") {
+ elsif(($1 eq "WinSSL") || ($1 eq "Schannel")) {
if($has_winssl) {
next;
}
@@ -3399,6 +3392,11 @@ sub singletest {
next;
}
}
+ elsif($1 eq "alt-svc") {
+ if($has_altsvc) {
+ next;
+ }
+ }
elsif($1 eq "manual") {
if($has_manual) {
next;
@@ -3452,7 +3450,7 @@ sub singletest {
next;
}
}
- elsif($1 eq "WinSSL") {
+ elsif(($1 eq "WinSSL") || ($1 eq "Schannel")) {
if(!$has_winssl) {
next;
}
@@ -3746,6 +3744,7 @@ sub singletest {
# if this section exists, we verify that the stdout contained this:
my @validstdout = fixarray ( getpart("verify", "stdout") );
+ my @validstderr = fixarray ( getpart("verify", "stderr") );
# if this section exists, we verify upload
my @upload = getpart("verify", "upload");
@@ -4229,6 +4228,57 @@ sub singletest {
$ok .= "-"; # stdout not checked
}
+ if (@validstderr) {
+ # verify redirected stderr
+ my @actual = loadarray($STDERR);
+
+ # what parts to cut off from stderr
+ my @stripfile = getpart("verify", "stripfile");
+
+ foreach my $strip (@stripfile) {
+ chomp $strip;
+ my @newgen;
+ for(@actual) {
+ eval $strip;
+ if($_) {
+ push @newgen, $_;
+ }
+ }
+ # this is to get rid of array entries that vanished (zero
+ # length) because of replacements
+ @actual = @newgen;
+ }
+
+ # variable-replace in the stderr we have from the test case file
+ @validstderr = fixarray(@validstderr);
+
+ # get all attributes
+ my %hash = getpartattr("verify", "stderr");
+
+ # get the mode attribute
+ my $filemode=$hash{'mode'};
+ if($filemode && ($filemode eq "text") && $has_textaware) {
+ # text mode when running on windows: fix line endings
+ map s/\r\n/\n/g, @validstderr;
+ map s/\n/\r\n/g, @validstderr;
+ }
+
+ if($hash{'nonewline'}) {
+ # Yes, we must cut off the final newline from the final line
+ # of the protocol data
+ chomp($validstderr[$#validstderr]);
+ }
+
+ $res = compare($testnum, $testname, "stderr", \@actual, \@validstderr);
+ if($res) {
+ return 1;
+ }
+ $ok .= "r";
+ }
+ else {
+ $ok .= "-"; # stderr not checked
+ }
+
if(@protocol) {
# Verify the sent request
my @out = loadarray($SERVERIN);
diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am
index f2067f2e2..ef3303ec1 100644
--- a/tests/server/Makefile.am
+++ b/tests/server/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -56,8 +56,13 @@ include Makefile.inc
EXTRA_DIST = base64.pl Makefile.inc CMakeLists.txt
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+ $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
if CURLDEBUG
# for debug builds, we scan the sources on all regular make invokes
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index fab82d2b0..6996cad6a 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -64,8 +64,13 @@ AM_CPPFLAGS += -DCURL_STATICLIB -DUNITTESTS
# Makefile.inc provides neat definitions
include Makefile.inc
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+ $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
if BUILD_UNITTESTS
noinst_PROGRAMS = $(UNITPROGS)
diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc
index 06b5186e4..67de815c0 100644
--- a/tests/unit/Makefile.inc
+++ b/tests/unit/Makefile.inc
@@ -11,7 +11,7 @@ UNITPROGS = unit1300 unit1301 unit1302 unit1303 unit1304 unit1305 unit1307 \
unit1399 \
unit1600 unit1601 unit1602 unit1603 unit1604 unit1605 unit1606 unit1607 \
unit1608 unit1609 unit1620 unit1621 \
- unit1650 unit1651 unit1652 unit1653
+ unit1650 unit1651 unit1652 unit1653 unit1654
unit1300_SOURCES = unit1300.c $(UNITFILES)
unit1300_CPPFLAGS = $(AM_CPPFLAGS)
@@ -115,3 +115,6 @@ unit1652_CPPFLAGS = $(AM_CPPFLAGS)
unit1653_SOURCES = unit1653.c $(UNITFILES)
unit1653_CPPFLAGS = $(AM_CPPFLAGS)
+
+unit1654_SOURCES = unit1654.c $(UNITFILES)
+unit1654_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/tests/unit/unit1307.c b/tests/unit/unit1307.c
index d6664ff69..91e4606b7 100644
--- a/tests/unit/unit1307.c
+++ b/tests/unit/unit1307.c
@@ -23,6 +23,17 @@
#include "curl_fnmatch.h"
+static CURLcode unit_setup(void)
+{
+ return CURLE_OK;
+}
+
+static void unit_stop(void)
+{
+}
+
+#ifndef CURL_DISABLE_FTP
+
/*
CURL_FNMATCH_MATCH 0
CURL_FNMATCH_NOMATCH 1
@@ -239,15 +250,6 @@ static const struct testcase tests[] = {
"a", NOMATCH|LINUX_FAIL}
};
-static CURLcode unit_setup(void)
-{
- return CURLE_OK;
-}
-
-static void unit_stop(void)
-{
-}
-
static const char *ret2name(int i)
{
switch(i) {
@@ -308,3 +310,14 @@ UNITTEST_START
}
}
UNITTEST_STOP
+
+#else
+
+UNITTEST_START
+{
+ /* nothing to do, just fail */
+ return 1;
+}
+UNITTEST_STOP
+
+#endif
diff --git a/tests/unit/unit1607.c b/tests/unit/unit1607.c
index 64b6371ee..22c2e8482 100644
--- a/tests/unit/unit1607.c
+++ b/tests/unit/unit1607.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,6 +25,10 @@
#include "connect.h"
#include "share.h"
+/* retrieves ip address and port from a sockaddr structure.
+ note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
+bool getaddressinfo(struct sockaddr *sa, char *addr, long *port);
+
#include "memdebug.h" /* LAST include file */
static struct Curl_easy *easy;
@@ -159,8 +163,8 @@ UNITTEST_START
if(tests[i].address[j] == &skip)
continue;
- if(addr && !Curl_getaddressinfo(addr->ai_addr,
- ipaddress, &port)) {
+ if(addr && !getaddressinfo(addr->ai_addr,
+ ipaddress, &port)) {
fprintf(stderr, "%s:%d tests[%d] failed. getaddressinfo failed.\n",
__FILE__, __LINE__, i);
problem = true;
diff --git a/tests/unit/unit1608.c b/tests/unit/unit1608.c
index 9ae474ba9..4fc24704b 100644
--- a/tests/unit/unit1608.c
+++ b/tests/unit/unit1608.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -23,6 +23,9 @@
#include "hostip.h"
+CURLcode Curl_shuffle_addr(struct Curl_easy *data,
+ Curl_addrinfo **addr);
+
#define NUM_ADDRS 8
static struct Curl_addrinfo addrs[NUM_ADDRS];
diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c
index 2b99bee9b..865c9e459 100644
--- a/tests/unit/unit1609.c
+++ b/tests/unit/unit1609.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,6 +25,10 @@
#include "connect.h"
#include "share.h"
+/* retrieves ip address and port from a sockaddr structure.
+ note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
+bool getaddressinfo(struct sockaddr *sa, char *addr, long *port);
+
#include "memdebug.h" /* LAST include file */
static struct Curl_easy *easy;
@@ -158,8 +162,8 @@ UNITTEST_START
if(!addr && !tests[i].address[j])
break;
- if(addr && !Curl_getaddressinfo(addr->ai_addr,
- ipaddress, &port)) {
+ if(addr && !getaddressinfo(addr->ai_addr,
+ ipaddress, &port)) {
fprintf(stderr, "%s:%d tests[%d] failed. getaddressinfo failed.\n",
__FILE__, __LINE__, i);
problem = true;
diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c
index adc91236a..cd6f519f7 100644
--- a/tests/unit/unit1650.c
+++ b/tests/unit/unit1650.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2019, 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
@@ -152,7 +152,7 @@ static struct dohresp resp[] = {
UNITTEST_START
{
- size_t size;
+ size_t size = 0;
unsigned char buffer[256];
size_t i;
unsigned char *p;
diff --git a/tests/unit/unit1651.c b/tests/unit/unit1651.c
index fcd3b54db..db3a0f35b 100644
--- a/tests/unit/unit1651.c
+++ b/tests/unit/unit1651.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2019, 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
@@ -352,6 +352,8 @@ UNITTEST_START
struct Curl_easy *data = curl_easy_init();
int i;
int byte;
+ if(!data)
+ return 2;
memset(&conn, 0, sizeof(struct connectdata));
/* this is a lot of assuming, but we expect the parsing function to only
diff --git a/tests/unit/unit1654.c b/tests/unit/unit1654.c
new file mode 100644
index 000000000..7532c6d61
--- /dev/null
+++ b/tests/unit/unit1654.c
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, 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 https://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 "curlcheck.h"
+
+#include "urldata.h"
+#include "altsvc.h"
+
+static CURLcode
+unit_setup(void)
+{
+ return CURLE_OK;
+}
+
+static void
+unit_stop(void)
+{
+ curl_global_cleanup();
+}
+
+#if defined(CURL_DISABLE_HTTP) || !defined(USE_ALTSVC)
+UNITTEST_START
+{
+ return 0; /* nothing to do when HTTP is disabled or alt-svc support is
+ missing */
+}
+UNITTEST_STOP
+#else
+UNITTEST_START
+{
+ char outname[256];
+ CURL *curl;
+ CURLcode result;
+ struct altsvcinfo *asi = Curl_altsvc_init();
+ if(!asi)
+ return 1;
+ result = Curl_altsvc_load(asi, arg);
+ if(result)
+ return result;
+ curl = curl_easy_init();
+ if(!curl)
+ goto fail;
+ fail_unless(asi->num == 4, "wrong number of entries");
+ msnprintf(outname, sizeof(outname), "%s-out", arg);
+
+ result = Curl_altsvc_parse(curl, asi, "h2=\"example.com:8080\"",
+ ALPN_h1, "example.org", 8080);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse() failed!\n");
+ unitfail++;
+ }
+ fail_unless(asi->num == 5, "wrong number of entries");
+
+ result = Curl_altsvc_parse(curl, asi, "h3=\":8080\"",
+ ALPN_h1, "2.example.org", 8080);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse(2) failed!\n");
+ unitfail++;
+ }
+ fail_unless(asi->num == 6, "wrong number of entries");
+
+ result = Curl_altsvc_parse(curl, asi,
+ "h2=\"example.com:8080\", h3=\"yesyes.com\"",
+ ALPN_h1, "3.example.org", 8080);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse(3) failed!\n");
+ unitfail++;
+ }
+ /* that one should make two entries */
+ fail_unless(asi->num == 8, "wrong number of entries");
+
+ result = Curl_altsvc_parse(curl, asi, "h2=\"example.com:443\"; ma = 120;",
+ ALPN_h2c, "example.org", 80);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse(4) failed!\n");
+ unitfail++;
+ }
+ fail_unless(asi->num == 9, "wrong number of entries");
+
+ result = Curl_altsvc_parse(curl, asi,
+ "h2=\":443\", h3=\":443\"; ma = 120; persist = 1",
+ ALPN_h1, "curl.haxx.se", 80);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse(5) failed!\n");
+ unitfail++;
+ }
+ fail_unless(asi->num == 11, "wrong number of entries");
+
+ /* clear that one again and decrease the counter */
+ result = Curl_altsvc_parse(curl, asi, "clear;",
+ ALPN_h1, "curl.haxx.se", 80);
+ if(result) {
+ fprintf(stderr, "Curl_altsvc_parse(6) failed!\n");
+ unitfail++;
+ }
+ fail_unless(asi->num == 9, "wrong number of entries");
+
+ Curl_altsvc_save(asi, outname);
+
+ curl_easy_cleanup(curl);
+ fail:
+ Curl_altsvc_cleanup(asi);
+ return unitfail;
+}
+UNITTEST_STOP
+#endif