[automerger] Disable unused protocols. am: 4f2f94119e am: 2c491e4c14 am: 72786999f7 am: 7fc585798b am: 980448bb19 am: f2f7e1fade
am: 246a705556

Change-Id: I2a93e6d774f09c205c3ff1c0dd9ae830d9b83413
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index d4f580b..bce89b4 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -8,7 +8,7 @@
 
  2. Subscribe to the suitable [mailing lists](https://curl.haxx.se/mail/)
 
-Read [CONTRIBUTE](../docs/CONTRIBUTE)
+Read [CONTRIBUTE](../docs/CONTRIBUTE.md)
 ---------------------------------------
 
 Send your suggestions using one of these methods:
@@ -20,4 +20,4 @@
 
  3. as an [issue](https://github.com/curl/curl/issues)
 
-/ The cURL team!
+/ The curl team!
diff --git a/.travis.yml b/.travis.yml
index 49e3f15..bdd21b0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,7 @@
 
 install:
   - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update > /dev/null; fi
-  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew reinstall -s libtool > /dev/null; fi
+  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew reinstall libtool > /dev/null; fi
   - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install openssl libidn rtmpdump libssh2 c-ares libmetalink libressl nghttp2; fi
 
 before_script:
diff --git a/Android.bp b/Android.bp
index 7b79185..89c5bb7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -33,6 +33,9 @@
 cc_library {
     name: "libcurl",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     defaults: ["curl_common_defaults"],
     export_include_dirs: ["include"],
     host_supported: true,
@@ -40,6 +43,7 @@
         "-DBUILDING_LIBCURL",
     ],
     srcs:[
+        "lib/rand.c",
         "lib/file.c",
         "lib/timeval.c",
         "lib/base64.c",
@@ -63,7 +67,6 @@
         "lib/netrc.c",
         "lib/getinfo.c",
         "lib/transfer.c",
-        "lib/strequal.c",
         "lib/easy.c",
         "lib/security.c",
         "lib/curl_fnmatch.c",
@@ -97,10 +100,10 @@
         "lib/select.c",
         "lib/tftp.c",
         "lib/splay.c",
+        "lib/strcase.c",
         "lib/strdup.c",
         "lib/socks.c",
         "lib/ssh.c",
-        "lib/rawstr.c",
         "lib/curl_addrinfo.c",
         "lib/socks_gssapi.c",
         "lib/socks_sspi.c",
diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake
new file mode 100644
index 0000000..9f7d296
--- /dev/null
+++ b/CMake/CurlSymbolHiding.cmake
@@ -0,0 +1,61 @@
+include(CheckCSourceCompiles)
+
+option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
+mark_as_advanced(CURL_HIDDEN_SYMBOLS)
+
+if(CURL_HIDDEN_SYMBOLS)
+    set(SUPPORTS_SYMBOL_HIDING FALSE)
+
+    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+        set(SUPPORTS_SYMBOL_HIDING TRUE)
+        set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+        set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+    elseif(CMAKE_COMPILER_IS_GNUCC)
+        if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
+            set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
+        else()
+            execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+                            OUTPUT_VARIABLE GCC_VERSION)
+        endif()
+        if(NOT GCC_VERSION VERSION_LESS 3.4)
+            # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
+            set(SUPPORTS_SYMBOL_HIDING TRUE)
+            set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+            set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+        endif()
+    elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
+        set(SUPPORTS_SYMBOL_HIDING TRUE)
+        set(_SYMBOL_EXTERN "__global")
+        set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
+    elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
+        # note: this should probably just check for version 9.1.045 but I'm not 100% sure
+        #       so let's to it the same way autotools do.
+        set(SUPPORTS_SYMBOL_HIDING TRUE)
+        set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+        set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+        check_c_source_compiles("#include <stdio.h>
+            int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
+        if(NOT _no_bug)
+            set(SUPPORTS_SYMBOL_HIDING FALSE)
+            set(_SYMBOL_EXTERN "")
+            set(_CFLAG_SYMBOLS_HIDE "")
+        endif()
+    elseif(MSVC)
+        set(SUPPORTS_SYMBOL_HIDING TRUE)
+    endif()
+
+    set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
+elseif(MSVC)
+    if(NOT CMAKE_VERSION VERSION_LESS 3.7)
+        set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
+        set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
+    else()
+        message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
+        set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
+    endif()
+elseif()
+    set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
+endif()
+
+set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
+set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})
diff --git a/CMake/FindNGHTTP2.cmake b/CMake/FindNGHTTP2.cmake
new file mode 100644
index 0000000..4e566cf
--- /dev/null
+++ b/CMake/FindNGHTTP2.cmake
@@ -0,0 +1,18 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
+
+find_library(NGHTTP2_LIBRARY NAMES nghttp2)
+
+find_package_handle_standard_args(NGHTTP2
+    FOUND_VAR
+      NGHTTP2_FOUND
+    REQUIRED_VARS
+      NGHTTP2_LIBRARY
+      NGHTTP2_INCLUDE_DIR
+    FAIL_MESSAGE
+      "Could NOT find NGHTTP2"
+)
+
+set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} )
+set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake
index d599498..3b203c5 100644
--- a/CMake/OtherTests.cmake
+++ b/CMake/OtherTests.cmake
@@ -179,17 +179,20 @@
 
 
 include(CheckCSourceRuns)
-set(CMAKE_REQUIRED_FLAGS)
-if(HAVE_SYS_POLL_H)
-  set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
-endif(HAVE_SYS_POLL_H)
-check_c_source_runs("
-  #ifdef HAVE_SYS_POLL_H
-  #  include <sys/poll.h>
-  #endif
-  int main(void) {
-    return poll((void *)0, 0, 10 /*ms*/);
-  }" HAVE_POLL_FINE)
+# See HAVE_POLL in CMakeLists.txt for why poll is disabled on macOS
+if(NOT APPLE)
+  set(CMAKE_REQUIRED_FLAGS)
+  if(HAVE_SYS_POLL_H)
+    set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
+  endif(HAVE_SYS_POLL_H)
+  check_c_source_runs("
+    #ifdef HAVE_SYS_POLL_H
+    #  include <sys/poll.h>
+    #endif
+    int main(void) {
+      return poll((void *)0, 0, 10 /*ms*/);
+    }" HAVE_POLL_FINE)
+endif()
 
 set(HAVE_SIG_ATOMIC_T 1)
 set(CMAKE_REQUIRED_FLAGS)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f7c4d6..a6a7368 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2016, 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
@@ -19,7 +19,7 @@
 # KIND, either express or implied.
 #
 ###########################################################################
-# cURL/libcurl CMake script
+# curl/libcurl CMake script
 # by Tetetest and Sukender (Benoit Neil)
 
 # TODO:
@@ -42,6 +42,7 @@
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
 include(Utilities)
 include(Macros)
+include(CMakeDependentOption)
 
 project( CURL C )
 
@@ -71,11 +72,17 @@
 include_directories(${PROJECT_BINARY_DIR}/include/curl)
 include_directories( ${CURL_SOURCE_DIR}/include )
 
-option(BUILD_CURL_EXE "Set to ON to build cURL executable." ON)
+option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
 option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF)
 option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
-option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
-
+if(WIN32)
+  CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER
+                         "Set to ON to enable threaded DNS lookup"
+                         ON "NOT ENABLE_ARES"
+                         OFF)
+else()
+  option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
+endif()
 option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
 option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
 
@@ -112,8 +119,7 @@
   mark_as_advanced(BUILD_RELEASE_DEBUG_DIRS)
 endif()
 
-option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
-mark_as_advanced(CURL_HIDDEN_SYMBOLS)
+include(CurlSymbolHiding)
 
 option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
 mark_as_advanced(HTTP_ONLY)
@@ -250,13 +256,17 @@
 endif(WIN32)
 
 if(ENABLE_THREADED_RESOLVER)
-  check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
-  if(HAVE_PTHREAD_H)
-    set(CMAKE_THREAD_PREFER_PTHREAD 1)
-    find_package(Threads)
-    if(CMAKE_USE_PTHREADS_INIT)
-      set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
-      set(USE_THREADS_POSIX 1)
+  if(WIN32)
+    set(USE_THREADS_WIN32 ON)
+  else()
+    check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
+    if(HAVE_PTHREAD_H)
+      set(CMAKE_THREAD_PREFER_PTHREAD 1)
+      find_package(Threads)
+      if(CMAKE_USE_PTHREADS_INIT)
+        set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+        set(USE_THREADS_POSIX 1)
+      endif()
     endif()
   endif()
 endif()
@@ -322,6 +332,13 @@
   endif()
 endif()
 
+option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
+if(USE_NGHTTP2)
+  find_package(NGHTTP2 REQUIRED)
+  include_directories(${NGHTTP2_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
+endif()
+
 if(NOT CURL_DISABLE_LDAP)
   if(WIN32)
     option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
@@ -432,12 +449,12 @@
 endif()
 
 # Check for idn
-check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
+check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
 
 # Check for symbol dlopen (same as HAVE_LIBDL)
 check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
 
-option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
+option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON)
 set(HAVE_LIBZ OFF)
 set(HAVE_ZLIB_H OFF)
 set(HAVE_ZLIB OFF)
@@ -601,7 +618,7 @@
 check_include_file_concat("err.h"            HAVE_ERR_H)
 check_include_file_concat("errno.h"          HAVE_ERRNO_H)
 check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
-check_include_file_concat("idn-free.h"       HAVE_IDN_FREE_H)
+check_include_file_concat("idn2.h"           HAVE_IDN2_H)
 check_include_file_concat("ifaddrs.h"        HAVE_IFADDRS_H)
 check_include_file_concat("io.h"             HAVE_IO_H)
 check_include_file_concat("krb.h"            HAVE_KRB_H)
@@ -631,7 +648,6 @@
 check_include_file_concat("termio.h"         HAVE_TERMIO_H)
 check_include_file_concat("termios.h"        HAVE_TERMIOS_H)
 check_include_file_concat("time.h"           HAVE_TIME_H)
-check_include_file_concat("tld.h"            HAVE_TLD_H)
 check_include_file_concat("unistd.h"         HAVE_UNISTD_H)
 check_include_file_concat("utime.h"          HAVE_UTIME_H)
 check_include_file_concat("x509.h"           HAVE_X509_H)
@@ -645,9 +661,6 @@
 check_include_file_concat("stdint.h"        HAVE_STDINT_H)
 check_include_file_concat("sockio.h"        HAVE_SOCKIO_H)
 check_include_file_concat("sys/utsname.h"   HAVE_SYS_UTSNAME_H)
-check_include_file_concat("idna.h"          HAVE_IDNA_H)
-
-
 
 check_type_size(size_t  SIZEOF_SIZE_T)
 check_type_size(ssize_t  SIZEOF_SSIZE_T)
@@ -666,6 +679,7 @@
     set(ssize_t __int64)
   endif(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
 endif(NOT HAVE_SIZEOF_SSIZE_T)
+# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
 
 # Different sizeofs, etc.
 
@@ -728,7 +742,11 @@
 
 check_symbol_exists(basename      "${CURL_INCLUDES}" HAVE_BASENAME)
 check_symbol_exists(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
-check_symbol_exists(poll          "${CURL_INCLUDES}" HAVE_POLL)
+# poll on macOS is unreliable, it first did not exist, then was broken until
+# fixed in 10.9 only to break again in 10.12.
+if(NOT APPLE)
+  check_symbol_exists(poll        "${CURL_INCLUDES}" HAVE_POLL)
+endif()
 check_symbol_exists(select        "${CURL_INCLUDES}" HAVE_SELECT)
 check_symbol_exists(strdup        "${CURL_INCLUDES}" HAVE_STRDUP)
 check_symbol_exists(strstr        "${CURL_INCLUDES}" HAVE_STRSTR)
@@ -764,8 +782,6 @@
   check_symbol_exists(RAND_status   "${CURL_INCLUDES}" HAVE_RAND_STATUS)
   check_symbol_exists(RAND_screen   "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
   check_symbol_exists(RAND_egd      "${CURL_INCLUDES}" HAVE_RAND_EGD)
-  check_symbol_exists(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}"
-    HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
   if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
     set(USE_OPENSSL 1)
   endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
@@ -795,9 +811,6 @@
 check_symbol_exists(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
 check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
 check_symbol_exists(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
-check_symbol_exists(idn_free       "${CURL_INCLUDES}" HAVE_IDN_FREE)
-check_symbol_exists(idna_strerror  "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
-check_symbol_exists(tld_strerror   "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
 check_symbol_exists(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
 check_symbol_exists(setrlimit      "${CURL_INCLUDES}" HAVE_SETRLIMIT)
 check_symbol_exists(fcntl          "${CURL_INCLUDES}" HAVE_FCNTL)
@@ -864,9 +877,14 @@
     )
   curl_internal_test(${CURL_TEST})
 endforeach(CURL_TEST)
+
 if(HAVE_FILE_OFFSET_BITS)
   set(_FILE_OFFSET_BITS 64)
+  set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
 endif(HAVE_FILE_OFFSET_BITS)
+check_type_size("off_t"  SIZEOF_OFF_T)
+set(CMAKE_REQUIRED_FLAGS)
+
 foreach(CURL_TEST
     HAVE_GLIBC_STRERROR_R
     HAVE_POSIX_STRERROR_R
@@ -928,16 +946,6 @@
   endif(NOT HAVE_ZLIB_H)
 endif(NOT CURL_SPECIAL_LIBZ)
 
-if(_FILE_OFFSET_BITS)
-  set(_FILE_OFFSET_BITS 64)
-endif(_FILE_OFFSET_BITS)
-set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
-set(CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/curl/curl.h")
-check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
-set(CMAKE_EXTRA_INCLUDE_FILES)
-set(CMAKE_REQUIRED_FLAGS)
-
-
 # Check for nonblocking
 set(HAVE_DISABLED_NONBLOCKING 1)
 if(HAVE_FIONBIO OR
@@ -1010,6 +1018,11 @@
   add_definitions(-D_WIN32_WINNT=0x0501)
 endif(WIN32)
 
+# For windows, all compilers used by cmake should support large files
+if(WIN32)
+  set(USE_WIN32_LARGE_FILES ON)
+endif(WIN32)
+
 if(MSVC)
   add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
 endif(MSVC)
@@ -1061,8 +1074,10 @@
 _add_if("IPv6"          ENABLE_IPV6)
 _add_if("unix-sockets"  USE_UNIX_SOCKETS)
 _add_if("libz"          HAVE_LIBZ)
-_add_if("AsynchDNS"     USE_ARES OR USE_THREADS_POSIX)
-_add_if("IDN"           HAVE_LIBIDN)
+_add_if("AsynchDNS"     USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
+_add_if("IDN"           HAVE_LIBIDN2)
+_add_if("Largefile"     (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
+                        ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
 # TODO SSP1 (WinSSL) check is missing
 _add_if("SSPI"          USE_WINDOWS_SSPI)
 _add_if("GSS-API"       HAVE_GSSAPI)
@@ -1128,9 +1143,7 @@
 set(CURLVERSION             "${CURL_VERSION}")
 set(ENABLE_SHARED           "yes")
 if(CURL_STATICLIB)
-  # Broken: LIBCURL_LIBS below; .a lib is not built
-  message(WARNING "Static linking is broken!")
-  set(ENABLE_STATIC         "no")
+  set(ENABLE_STATIC         "yes")
 else()
   set(ENABLE_STATIC         "no")
 endif()
@@ -1139,9 +1152,12 @@
 set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
 set(LIBCURL_LIBS            "")
 set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
-# TODO CURL_LIBS also contains absolute paths which don't work with static -l...
 foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
-  set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
+  if(_lib MATCHES ".*/.*")
+    set(LIBCURL_LIBS          "${LIBCURL_LIBS} ${_lib}")
+  else()
+    set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
+  endif()
 endforeach()
 # "a" (Linux) or "lib" (Windows)
 string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
diff --git a/GIT-INFO b/GIT-INFO
index 16f4a22..6b703fe 100644
--- a/GIT-INFO
+++ b/GIT-INFO
@@ -51,17 +51,3 @@
    install them, you can rename the source file src/tool_hugehelp.c.cvs to
    src/tool_hugehelp.c and avoid having to generate this file. This will
    give you a stubbed version of the file that doesn't contain actual content.
-
-MAC OS X
-
- With Mac OS X 10.2 and the associated Developer Tools, the installed versions
- of the build tools are adequate.  For Mac OS X 10.1 users, Guido Neitzer
- wrote the following step-by-step guide:
-
- 1. Install fink (http://fink.sourceforge.net)
- 2. Update fink to the newest version (with the installed fink)
- 3. Install the latest version of autoconf, automake and m4 with fink
- 4. Install version 1.4.1 of libtool - you find it in the "unstable" section
-    (read the manual to see how to get unstable versions)
- 5. Get cURL from git
- 6. Build cURL with "./buildconf", "./configure", "make", "sudo make install"
diff --git a/Makefile.am b/Makefile.am
index 2986acf..f86ffbc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,10 +24,13 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
-CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in	\
- CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake	\
- CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake	\
- include/curl/curlbuild.h.cmake CMake/Macros.cmake
+CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in      \
+ CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake   \
+ CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake       \
+ include/curl/curlbuild.h.cmake CMake/Macros.cmake              \
+ CMake/CurlSymbolHiding.cmake CMake/FindCARES.cmake             \
+ CMake/FindLibSSH2.cmake CMake/FindNGHTTP2.cmake
+
 
 VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
 VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist
diff --git a/README.md b/README.md
index 64883dc..567d6d1 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
 ![curl logo](https://cdn.rawgit.com/curl/curl-www/master/logo/curl-logo.svg)
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/63/badge)](https://bestpractices.coreinfrastructure.org/projects/63)
 
 Curl is a command-line tool for transferring data specified with URL
 syntax. Find out how to use curl by reading [the curl.1 man
diff --git a/README.version b/README.version
index 41ae42b..9c2568f 100644
--- a/README.version
+++ b/README.version
@@ -1,6 +1,6 @@
-URL: https://curl.haxx.se/download/curl-7.50.1.tar.gz
-Version: 7.50.1
-Upstream commit: f2cb3a01192d36395d16acec6cdb93446ca6fd45
+URL: https://curl.haxx.se/download/curl-7.54.1.tar.gz
+Version: 7.54.1
+Upstream commit: 54b636f14546d3fde9f9c67c3b32701d78563161
 License: MIT
 License File: NOTICE
 BugComponent: 31714
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 163ceb1..f5d172f 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,26 +1,52 @@
-Curl and libcurl 7.50.1
+Curl and libcurl 7.52.0
 
- Public curl releases:         157
- Command line options:         185
- curl_easy_setopt() options:   224
+ Public curl releases:         161
+ Command line options:         205
+ curl_easy_setopt() options:   243
  Public functions in libcurl:  61
- Contributors:                 1418
+ Contributors:                 1467
+
+This release includes the following changes:
+
+ o nss: map CURL_SSLVERSION_DEFAULT to NSS default
+ o vtls: support TLS 1.3 via CURL_SSLVERSION_TLSv1_3
+ o curl: introduce the --tlsv1.3 option to force TLS 1.3
+ o curl: Add --retry-connrefused [11]
+ o proxy: Support HTTPS proxy and SOCKS+HTTP(s)
 
 This release includes the following bugfixes:
 
- o TLS: switch off SSL session id when client cert is used [7]
- o TLS: only reuse connections with the same client cert [8]
- o curl_multi_cleanup: clear connection pointer for easy handles [9]
- o include the CURLINFO_HTTP_VERSION(3) man page into the release tarball
- o include the http2-server.pl script in the release tarball
- o test558: fix test by stripping file paths from FD lines
- o spnego: Corrected miss-placed * in Curl_auth_spnego_cleanup() declaration
- o tests: Fix for http/2 feature [1]
- o cmake: Fix for schannel support [2]
- o curl.h: make public types void * again [3]
- o win32: fix a potential memory leak in Curl_load_library [4]
- o travis: fix OSX build by re-installing libtool [5]
- o mbedtls: Fix debug function name [6]
+ o msvc: removed a straggling reference to strequal.c
+ o winbuild: remove strcase.obj from curl build [1]
+ o examples: bugfixed multi-uv.c
+ o configure: verify that compiler groks -Werror=partial-availability [2]
+ o mbedtls: fix build with mbedtls versions < 2.4.0 [3]
+ o dist: add unit test CMakeLists.txt to the tarball
+ o curl -w: added more decimal digits to timing counters [4]
+ o easy: Initialize info variables on easy init and duphandle [5]
+ o cmake: disable poll for macOS [6]
+ o http2: Don't send header fields prohibited by HTTP/2 spec [7]
+ o ssh: check md5 fingerprints case insensitively (regression) [8]
+ o openssl: initial TLS 1.3 adaptions
+ o curl_formadd.3: *_FILECONTENT and *_FILE need the file to be kept
+ o printf: fix ".*f" handling [9]
+ o examples/fileupload.c: fclose the file as well
+ o SPNEGO: Fix memory leak when authentication fails [10]
+ o realloc: use Curl_saferealloc to avoid common mistakes [12]
+ o openssl: make sure to fail in the unlikely event that PRNG seeding fails
+ o URL-parser: for file://[host]/ URLs, the [host] must be localhost [13]
+ o timeval: prefer time_t to hold seconds instead of long
+ o Curl_rand: fixed and moved to rand.c [14]
+ o curl: add --fail-early [15]
+ o glob: fix [a-c] globbing regression [16]
+ o darwinssl: fix SSL client certificate not found on MacOS Sierra [17]
+ o curl.1: Clarify --dump-header only writes received headers
+ o http2: Fix address sanitizer memcpy warning
+ o http2: Use huge HTTP/2 windows [18]
+ o connects: Don't mix unix domain sockets with regular ones
+ o url: Fix conn reuse for local ports and interfaces [19]
+ o x509: Limit ASN.1 structure sizes to 256K
+ o checksrc: add more checks
 
 This release includes the following known bugs:
 
@@ -29,22 +55,35 @@
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
-  Alain Danteny, Bru Rom, Dan Fandrich, Daniel Stenberg, Eric Rescorla,
-  Fernando Muñoz, Kamil Dudka, Marcelo Echeverria, Martin Vejnár,
-  Patrick Monnerat, Paul Howarth, Peter Frühberger, Ray Satiro, Sergei Nikulov,
-  Steve Holme, Thomas Glanzmann, Viktor Szakáts, Yonggang Luo,
-  (18 contributors)
+  Adam Piggott, afrind on github, Alex Chan, Alex Rousskov, Andrei Sedoi,
+  Bruce Stephens, Dan Fandrich, Daniel Hwang, Daniel Stenberg, Dave Reisner,
+  David Schweikert, Dmitry Kurochkin, Frank Gevaerts, Isaac Boukris,
+  Jakub Zakrzewski, Kamil Dudka, Marcel Raad, Mauro Rappa, Mike Crowe,
+  Neal Poole, Nick Zitzmann, Okhin Vasilij, Patrick Monnerat, Peter Wu,
+  Ray Satiro, Ricki Hirner, Tatsuhiro Tsujikawa, Thomas Glanzmann, Tony Kelman,
+  Vasy Okhin,
+  (30 contributors)
 
         Thanks! (and sorry if I forgot to mention someone)
 
 References to bug reports and discussions on issues:
 
- [1] = https://curl.haxx.se/mail/lib-2016-07/0070.html
- [2] = https://curl.haxx.se/bug/?i=917
- [3] = https://curl.haxx.se/bug/?i=926
- [4] = https://curl.haxx.se/bug/?i=938
- [5] = https://curl.haxx.se/bug/?i=939
- [6] = https://curl.haxx.se/mail/lib-2016-08/0001.html
- [7] = https://curl.haxx.se/docs/adv_20160803A.html
- [8] = https://curl.haxx.se/docs/adv_20160803B.html
- [9] = https://curl.haxx.se/docs/adv_20160803C.html
+ [1] = https://curl.haxx.se/bug/?i=1098
+ [2] = https://curl.haxx.se/bug/?i=1104
+ [3] = https://curl.haxx.se/bug/?i=1087
+ [4] = https://curl.haxx.se/bug/?i=1106
+ [5] = https://curl.haxx.se/bug/?i=1103
+ [6] = https://curl.haxx.se/bug/?i=1089
+ [7] = https://curl.haxx.se/bug/?i=1092
+ [8] = https://github.com/curl/curl/commit/ce8d09483eea2fcb1b50e323e1a8ed1f3613b2e3#commitcomment-19666146
+ [9] = https://curl.haxx.se/bug/?i=1113
+ [10] = https://curl.haxx.se/bug/?i=1115
+ [11] = https://curl.haxx.se/bug/?i=1064
+ [12] = https://curl.haxx.se/mail/lib-2016-11/0087.html
+ [13] = https://curl.haxx.se/mail/lib-2016-11/0104.html
+ [14] = https://curl.haxx.se/mail/lib-2016-11/0119.html
+ [15] = https://curl.haxx.se/mail/archive-2016-11/0038.html
+ [16] = https://github.com/curl/curl/commit/ee4f76606cfa4ee068bf28edd37c8dae7e8db317#commitcomment-19823146
+ [17] = https://curl.haxx.se/bug/?i=1105
+ [18] = https://curl.haxx.se/bug/?i=1102
+ [19] = https://curl.haxx.se/mail/lib-2016-11/0137.html
diff --git a/acinclude.m4 b/acinclude.m4
index fa621b5..2abae8d 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2016, 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,8 +32,8 @@
 AC_DEFUN([CURL_CHECK_DEF], [
   AC_REQUIRE([CURL_CPP_P])dnl
   OLDCPPFLAGS=$CPPFLAGS
-  # CPPPFLAGS comes from CURL_CPP_P
-  CPPFLAGS="$CPPPFLAGS"
+  # CPPPFLAG comes from CURL_CPP_P
+  CPPFLAGS="$CPPFLAGS $CPPPFLAG"
   AS_VAR_PUSHDEF([ac_HaveDef], [curl_cv_have_def_$1])dnl
   AS_VAR_PUSHDEF([ac_Def], [curl_cv_def_$1])dnl
   if test -z "$SED"; then
@@ -1856,7 +1856,7 @@
   AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
   AC_MSG_CHECKING([for monotonic clock_gettime])
   #
-  if test "x$dontwant_rt" == "xno" ; then
+  if test "x$dontwant_rt" = "xno" ; then
     AC_COMPILE_IFELSE([
       AC_LANG_PROGRAM([[
 #ifdef HAVE_SYS_TYPES_H
@@ -3187,12 +3187,59 @@
     if test "x$cpp_p" = "xno"; then
       AC_MSG_WARN([failed to figure out cpp -P alternative])
       # without -P
-      CPPPFLAGS=$OLDCPPFLAGS
+      CPPPFLAG=""
     else
       # with -P
-      CPPPFLAGS=$CPPFLAGS
+      CPPPFLAG="-P"
     fi
     dnl restore CPPFLAGS
     CPPFLAGS=$OLDCPPFLAGS
+  else
+    # without -P
+    CPPPFLAG=""
   fi
 ])
+
+
+dnl CURL_MAC_CFLAGS
+dnl
+dnl Check if -mmacosx-version-min, -miphoneos-version-min or any
+dnl similar are set manually, otherwise do. And set
+dnl -Werror=partial-availability.
+dnl
+
+AC_DEFUN([CURL_MAC_CFLAGS], [
+
+  tst_cflags="no"
+  case $host_os in
+    darwin*)
+      tst_cflags="yes"
+      ;;
+  esac
+
+  AC_MSG_CHECKING([for good-to-use Mac CFLAGS])
+  AC_MSG_RESULT([$tst_cflags]);
+
+  if test "$tst_cflags" = "yes"; then
+    AC_MSG_CHECKING([for *version-min in CFLAGS])
+    min=""
+    if test -z "$(echo $CFLAGS | grep m.*os.*-version-min)"; then
+      min="-mmacosx-version-min=10.8"
+      CFLAGS="$CFLAGS $min"
+    fi
+    if test -z "$min"; then
+      AC_MSG_RESULT([set by user])
+    else
+      AC_MSG_RESULT([$min set])
+    fi
+
+    old_CFLAGS=$CFLAGS
+    CFLAGS="$CFLAGS -Werror=partial-availability"
+    AC_MSG_CHECKING([whether $CC accepts -Werror=partial-availability])
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+      [AC_MSG_RESULT([yes])],
+      [AC_MSG_RESULT([no])
+      CFLAGS=$old_CFLAGS])
+  fi
+
+])
diff --git a/configure.ac b/configure.ac
index ec3d22a..e2ef802 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,7 +141,7 @@
 
 dnl Solaris pkgadd support definitions
 PKGADD_PKG="HAXXcurl"
-PKGADD_NAME="cURL - a client that groks URLs"
+PKGADD_NAME="curl - a client that groks URLs"
 PKGADD_VENDOR="curl.haxx.se"
 AC_SUBST(PKGADD_PKG)
 AC_SUBST(PKGADD_NAME)
@@ -157,7 +157,7 @@
     curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
    curl_ipv6_msg="no      (--enable-ipv6)"
 curl_unix_sockets_msg="no      (--enable-unix-sockets)"
-    curl_idn_msg="no      (--with-{libidn,winidn})"
+    curl_idn_msg="no      (--with-{libidn2,winidn})"
  curl_manual_msg="no      (--enable-manual)"
 curl_libcurl_msg="enabled (--disable-libcurl-option)"
 curl_verbose_msg="enabled (--disable-verbose)"
@@ -349,6 +349,8 @@
 esac
 CURL_CHECK_WIN32_LARGEFILE
 
+CURL_MAC_CFLAGS
+
 dnl ************************************************************
 dnl switch off particular protocols
 dnl
@@ -883,17 +885,30 @@
     OPT_ZLIB=""
   fi
 
-  if test -z "$OPT_ZLIB" ; then
-    dnl check for the lib first without setting any new path, since many
-    dnl people have it in the default path
+  CURL_CHECK_PKGCONFIG(zlib)
 
-    AC_CHECK_LIB(z, inflateEnd,
+  if test "$PKGCONFIG" != "no" ; then
+    LIBS="`$PKGCONFIG --libs-only-l zlib` $LIBS"
+    LDFLAGS="`$PKGCONFIG --libs-only-L zlib` $LDFLAGS"
+    CPPFLAGS="`$PKGCONFIG --cflags-only-I zlib` $CPPFLAGS"
+    OPT_ZLIB=""
+    HAVE_LIBZ="1"
+  fi
+
+  if test -z "$OPT_ZLIB" ; then
+
+    if test -z "$HAVE_LIBZ"; then
+
+      dnl Check for the lib without setting any new path, since many
+      dnl people have it in the default path
+
+      AC_CHECK_LIB(z, inflateEnd,
                    dnl libz found, set the variable
                    [HAVE_LIBZ="1"
                     LIBS="-lz $LIBS"],
                    dnl if no lib found, try /usr/local
                    [OPT_ZLIB="/usr/local"])
-
+    fi
   fi
 
   dnl Add a nonempty path to the compiler flags
@@ -1350,18 +1365,18 @@
 
 OPT_DARWINSSL=no
 AC_ARG_WITH(darwinssl,dnl
-AC_HELP_STRING([--with-darwinssl],[enable iOS/Mac OS X native SSL/TLS])
-AC_HELP_STRING([--without-darwinssl], [disable iOS/Mac OS X native SSL/TLS]),
+AC_HELP_STRING([--with-darwinssl],[enable Apple OS native SSL/TLS])
+AC_HELP_STRING([--without-darwinssl], [disable Apple OS native SSL/TLS]),
   OPT_DARWINSSL=$withval)
 
-AC_MSG_CHECKING([whether to enable iOS/Mac OS X native SSL/TLS])
+AC_MSG_CHECKING([whether to enable Apple OS native SSL/TLS])
 if test "$curl_ssl_msg" = "$init_ssl_msg"; then
   if test "x$OPT_DARWINSSL" != "xno" &&
      test -d "/System/Library/Frameworks/Security.framework"; then
     AC_MSG_RESULT(yes)
-    AC_DEFINE(USE_DARWINSSL, 1, [to enable iOS/Mac OS X native SSL/TLS support])
+    AC_DEFINE(USE_DARWINSSL, 1, [to enable Apple OS native SSL/TLS support])
     AC_SUBST(USE_DARWINSSL, [1])
-    curl_ssl_msg="enabled (iOS/Mac OS X-native)"
+    curl_ssl_msg="enabled (Apple OS-native)"
     DARWINSSL_ENABLED=1
     LDFLAGS="$LDFLAGS -framework CoreFoundation -framework Security"
   else
@@ -1614,11 +1629,8 @@
     dnl SSL_get_shutdown (but this check won't actually detect it there
     dnl as it's a macro that needs the header files be included)
 
-    AC_CHECK_FUNCS( RAND_status \
-                    RAND_screen \
-                    RAND_egd \
+    AC_CHECK_FUNCS( RAND_egd \
                     ENGINE_cleanup \
-                    CRYPTO_cleanup_all_ex_data \
                     SSL_get_shutdown \
                     SSLv2_client_method )
 
@@ -2561,7 +2573,7 @@
     DIR_SSH2=${PREFIX_SSH2}/lib$libsuff
   fi
 
-  LDFLAGS="$LDFLAGS $LD_SSH2"
+  LDFLAGS="$LD_SSH2 $LDFLAGS"
   CPPFLAGS="$CPPFLAGS $CPP_SSH2"
   LIBS="$LIB_SSH2 $LIBS"
 
@@ -2808,15 +2820,15 @@
 dnl Check for the presence of IDN libraries and headers
 dnl **********************************************************************
 
-AC_MSG_CHECKING([whether to build with libidn])
+AC_MSG_CHECKING([whether to build with libidn2])
 OPT_IDN="default"
 AC_ARG_WITH(libidn,
-AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage])
-AC_HELP_STRING([--without-libidn],[Disable libidn usage]),
+AC_HELP_STRING([--with-libidn2=PATH],[Enable libidn2 usage])
+AC_HELP_STRING([--without-libidn2],[Disable libidn2 usage]),
   [OPT_IDN=$withval])
 case "$OPT_IDN" in
   no)
-    dnl --without-libidn option used
+    dnl --without-libidn2 option used
     want_idn="no"
     AC_MSG_RESULT([no])
     ;;
@@ -2827,13 +2839,13 @@
     AC_MSG_RESULT([(assumed) yes])
     ;;
   yes)
-    dnl --with-libidn option used without path
+    dnl --with-libidn2 option used without path
     want_idn="yes"
     want_idn_path="default"
     AC_MSG_RESULT([yes])
     ;;
   *)
-    dnl --with-libidn option used with path
+    dnl --with-libidn2 option used with path
     want_idn="yes"
     want_idn_path="$withval"
     AC_MSG_RESULT([yes ($withval)])
@@ -2850,33 +2862,33 @@
   if test "$want_idn_path" != "default"; then
     dnl path has been specified
     IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig"
-    CURL_CHECK_PKGCONFIG(libidn, [$IDN_PCDIR])
+    CURL_CHECK_PKGCONFIG(libidn2, [$IDN_PCDIR])
     if test "$PKGCONFIG" != "no"; then
       IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --libs-only-l libidn 2>/dev/null`
+        $PKGCONFIG --libs-only-l libidn2 2>/dev/null`
       IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --libs-only-L libidn 2>/dev/null`
+        $PKGCONFIG --libs-only-L libidn2 2>/dev/null`
       IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --cflags-only-I libidn 2>/dev/null`
+        $PKGCONFIG --cflags-only-I libidn2 2>/dev/null`
       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
     else
       dnl pkg-config not available or provides no info
-      IDN_LIBS="-lidn"
+      IDN_LIBS="-lidn2"
       IDN_LDFLAGS="-L$want_idn_path/lib$libsuff"
       IDN_CPPFLAGS="-I$want_idn_path/include"
       IDN_DIR="$want_idn_path/lib$libsuff"
     fi
   else
     dnl path not specified
-    CURL_CHECK_PKGCONFIG(libidn)
+    CURL_CHECK_PKGCONFIG(libidn2)
     if test "$PKGCONFIG" != "no"; then
-      IDN_LIBS=`$PKGCONFIG --libs-only-l libidn 2>/dev/null`
-      IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn 2>/dev/null`
-      IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn 2>/dev/null`
+      IDN_LIBS=`$PKGCONFIG --libs-only-l libidn2 2>/dev/null`
+      IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn2 2>/dev/null`
+      IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn2 2>/dev/null`
       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
     else
       dnl pkg-config not available or provides no info
-      IDN_LIBS="-lidn"
+      IDN_LIBS="-lidn2"
     fi
   fi
   #
@@ -2896,9 +2908,9 @@
   LDFLAGS="$IDN_LDFLAGS $LDFLAGS"
   LIBS="$IDN_LIBS $LIBS"
   #
-  AC_MSG_CHECKING([if idna_to_ascii_4i can be linked])
+  AC_MSG_CHECKING([if idn2_lookup_ul can be linked])
   AC_LINK_IFELSE([
-    AC_LANG_FUNC_LINK_TRY([idna_to_ascii_4i])
+    AC_LANG_FUNC_LINK_TRY([idn2_lookup_ul])
   ],[
     AC_MSG_RESULT([yes])
     tst_links_libidn="yes"
@@ -2906,37 +2918,19 @@
     AC_MSG_RESULT([no])
     tst_links_libidn="no"
   ])
-  if test "$tst_links_libidn" = "no"; then
-    AC_MSG_CHECKING([if idna_to_ascii_lz can be linked])
-    AC_LINK_IFELSE([
-      AC_LANG_FUNC_LINK_TRY([idna_to_ascii_lz])
-    ],[
-      AC_MSG_RESULT([yes])
-      tst_links_libidn="yes"
-    ],[
-      AC_MSG_RESULT([no])
-      tst_links_libidn="no"
-    ])
-  fi
   #
+  AC_CHECK_HEADERS( idn2.h )
+
   if test "$tst_links_libidn" = "yes"; then
-    AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you have the `idn' library (-lidn).])
+    AC_DEFINE(HAVE_LIBIDN2, 1, [Define to 1 if you have the `idn2' library (-lidn2).])
     dnl different versions of libidn have different setups of these:
-    AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror )
-    AC_CHECK_HEADERS( idn-free.h tld.h )
-    if test "x$ac_cv_header_tld_h" = "xyes"; then
-      AC_SUBST([IDN_ENABLED], [1])
-      curl_idn_msg="enabled"
-      if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then
-        LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
-        export LD_LIBRARY_PATH
-        AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH])
-      fi
-    else
-      AC_MSG_WARN([Libraries for IDN support too old: IDN disabled])
-      CPPFLAGS="$clean_CPPFLAGS"
-      LDFLAGS="$clean_LDFLAGS"
-      LIBS="$clean_LIBS"
+
+    AC_SUBST([IDN_ENABLED], [1])
+    curl_idn_msg="enabled (libidn2)"
+    if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then
+      LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
+      export LD_LIBRARY_PATH
+      AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH])
     fi
   else
     AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled])
@@ -3683,8 +3677,8 @@
 
 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$NSS_ENABLED" = "x1" \
-      -o "x$DARWINSSL_ENABLED" = "x1"; then
+      -o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
+      -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1"; then
     SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM"
 
     if test "x$CURL_DISABLE_HTTP" != "x1" -a \
@@ -3756,8 +3750,8 @@
 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$NSS_ENABLED" = "x1" \
-      -o "x$DARWINSSL_ENABLED" = "x1" \); then
+      -o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
+      -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1" \); then
   SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMB"
   if test "x$SSL_ENABLED" = "x1"; then
     SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMBS"
diff --git a/docs/BINDINGS b/docs/BINDINGS
deleted file mode 100644
index eb67c3d..0000000
--- a/docs/BINDINGS
+++ /dev/null
@@ -1,260 +0,0 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-                               libcurl bindings
-
- Creative people have written bindings or interfaces for various environments
- and programming languages. Using one of these allows you to take advantage of
- curl powers from within your favourite language or system.
-
- This is a list of all known interfaces as of this writing.
-
- The bindings listed below are not part of the curl/libcurl distribution
- archives, but must be downloaded and installed separately.
-
-Ada95
-
-  Writtten by Andreas Almroth
-  http://www.almroth.com/adacurl/index.html
-
-Basic
-
-  ScriptBasic bindings to libcurl. Writtten by Peter Verhas
-  http://scriptbasic.com/
-
-C
-  libcurl is a C library in itself!
-  https://curl.haxx.se/libcurl/
-
-C++
-
-  Written by Jean-Philippe Barrette-LaPierre
-  http://curlpp.org/
-
-Ch
-
-  Written by Stephen Nestinger and Jonathan Rogado
-  http://chcurl.sourceforge.net/
-
-Cocoa
-
-  BBHTTP: written by Bruno de Carvalho
-  https://github.com/brunodecarvalho/BBHTTP
-
-  curlhandle: Written by Dan Wood
-  http://curlhandle.sourceforge.net/
-
-D
-
-  Written by Kenneth Bogert
-  http://dlang.org/library/std/net/curl.html
-
-Dylan
-
-  Written by Chris Double
-  http://dylanlibs.sourceforge.net/
-
-Eiffel
-
-  Written by Eiffel Software
-  https://room.eiffel.com/library/curl
-
-Euphoria
-
-  Written by Ray Smith
-  http://rays-web.com/eulibcurl.htm
-
-Falcon
-
-  http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl
-
-Ferite
-
-  Written by Paul Querna
-  http://www.ferite.org/
-
-Gambas
-
-  http://gambas.sourceforge.net/
-
-glib/GTK+
-
-  Written by Richard Atterer
-  http://atterer.net/glibcurl/
-
-Guile:
-
-  Written by Michael L. Gran
-  http://www.lonelycactus.com/guile-curl.html
-
-Harbour
-
-  Written by Viktor Szakáts
-  https://github.com/vszakats/harbour-core/tree/master/contrib/hbcurl
-
-Haskell
-
-  Written by Galois, Inc
-  http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl
-
-Java
-
-  https://github.com/pjlegato/curl-java
-
-Julia
-
-  Written by Paul Howe
-  https://github.com/forio/Curl.jl
-
-Lisp
-
-  Written by Liam Healy
-  http://common-lisp.net/project/cl-curl/
-
-Lua
-
-  luacurl by Alexander Marinov
-  http://luacurl.luaforge.net/
-
-  Lua-cURL by Jürgen Hötzel
-  http://luaforge.net/projects/lua-curl/
-
-Mono
-
-  Written by Jeffrey Phillips
-  http://forge.novell.com/modules/xfmod/project/?libcurl-mono
-
-.NET
-
-  libcurl-net by Jeffrey Phillips
-  https://sourceforge.net/projects/libcurl-net/
-
-node.js
-
-  node-libcurl by Jonathan Cardoso Machado
-  https://github.com/JCMais/node-libcurl
-
-Object-Pascal
-
-  Free Pascal, Delphi and Kylix binding written by Christophe Espern.
-  http://www.tekool.com/opcurl
-
-O'Caml
-
-  Written by Lars Nilsson
-  https://sourceforge.net/projects/ocurl/
-
-Pascal
-
-  Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
-  http://houston.quik.com/jkp/curlpas/
-
-Perl
-
-  Maintained by Cris Bailiff and Bálint Szilakszi
-  https://github.com/szbalint/WWW--Curl
-
-PHP
-
-  Written by Sterling Hughes
-  https://php.net/curl
-
-PostgreSQL
-
-  Written by Gian Paolo Ciceri
-  http://gborg.postgresql.org/project/pgcurl/projdisplay.php
-
-Python
-
-  PycURL by Kjetil Jacobsen
-  http://pycurl.sourceforge.net/
-
-R
-
-  http://cran.r-project.org/package=curl
-
-Rexx
-
-  Written Mark Hessling
-  http://rexxcurl.sourceforge.net/
-
-RPG
-
-  Support for ILE/RPG on OS/400 is included in source distribution
-  https://curl.haxx.se/libcurl/
-  See packages/OS400/README.OS400 and packages/OS400/curl.inc.in
-
-Ruby
-
-  curb - written by Ross Bamford
-  http://curb.rubyforge.org/
-
-  ruby-curl-multi - written by Kristjan Petursson and Keith Rarick
-  http://curl-multi.rubyforge.org/
-
-Rust
-
-  curl-rust - by Carl Lerche
-  https://github.com/carllerche/curl-rust
-
-Scheme
-
-  Bigloo binding by Kirill Lisovsky
-  http://www.metapaper.net/lisovsky/web/curl/
-
-S-Lang
-
-  S-Lang binding by John E Davis
-  http://www.jedsoft.org/slang/modules/curl.html
-
-Smalltalk
-
-  Smalltalk binding by Danil Osipchuk
-  http://www.squeaksource.com/CurlPlugin/
-
-SP-Forth
-
-  SP-Forth binding by ygrek
-  http://www.forth.org.ru/~ac/lib/lin/curl/
-
-SPL
-
-  SPL binding by Clifford Wolf
-  http://www.clifford.at/spl/
-
-Tcl
-
-  Tclcurl by Andrés García
-  http://mirror.yellow5.com/tclcurl/
-
-Visual Basic
-
-  libcurl-vb by Jeffrey Phillips
-  https://sourceforge.net/projects/libcurl-vb/
-
-Visual Foxpro
-
-  by Carlos Alloatti
-  http://www.ctl32.com.ar/libcurl.asp
-
-Q
-  The libcurl module is part of the default install
-  http://q-lang.sourceforge.net/
-
-wxWidgets
-
-  Written by Casey O'Donnell
-  http://wxcode.sourceforge.net/components/wxcurl/
-
-XBLite
-
-  Written by David Szafranski
-  http://perso.wanadoo.fr/xblite/libraries.html
-
-Xojo
-
-  Written by Andrew Lambert
-  https://github.com/charonn0/RB-libcURL
diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md
new file mode 100644
index 0000000..a59a94f
--- /dev/null
+++ b/docs/BINDINGS.md
@@ -0,0 +1,106 @@
+libcurl bindings
+================
+
+ Creative people have written bindings or interfaces for various environments
+ and programming languages. Using one of these allows you to take advantage of
+ curl powers from within your favourite language or system.
+
+ This is a list of all known interfaces as of this writing.
+
+ The bindings listed below are not part of the curl/libcurl distribution
+ archives, but must be downloaded and installed separately.
+
+[Ada95](http://www.almroth.com/adacurl/index.html)  Written by Andreas Almroth
+
+[Basic](http://scriptbasic.com/) ScriptBasic bindings written by Peter Verhas
+
+[C++](http://curlpp.org/) Written by Jean-Philippe Barrette-LaPierre
+
+[Ch](http://chcurl.sourceforge.net/) Written by Stephen Nestinger and Jonathan Rogado
+
+Cocoa: [BBHTTP](https://github.com/brunodecarvalho/BBHTTP) written by Bruno de Carvalho
+[curlhandle](http://curlhandle.sourceforge.net/) Written by Dan Wood
+
+[D](http://dlang.org/library/std/net/curl.html) Written by Kenneth Bogert
+
+[Dylan](http://dylanlibs.sourceforge.net/) Written by Chris Double
+
+[Eiffel](https://room.eiffel.com/library/curl) Written by Eiffel Software
+
+[Euphoria](http://rays-web.com/eulibcurl.htm) Written by Ray Smith
+
+[Falcon](http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl)
+
+[Ferite](http://www.ferite.org/) Written by Paul Querna
+
+[Gambas](http://gambas.sourceforge.net/)
+
+[glib/GTK+](http://atterer.net/glibcurl/) Written by Richard Atterer
+
+[Guile](http://www.lonelycactus.com/guile-curl.html) Written by Michael L. Gran
+
+[Harbour](https://github.com/vszakats/harbour-core/tree/master/contrib/hbcurl) Written by Viktor Szakáts
+
+[Haskell](http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl) Written by Galois, Inc
+
+[Java](https://github.com/pjlegato/curl-java)
+
+[Julia](https://github.com/forio/Curl.jl) Written by Paul Howe
+
+[Lisp](http://common-lisp.net/project/cl-curl/) Written by Liam Healy
+
+Lua: [luacurl](http://luacurl.luaforge.net/) by Alexander Marinov, [Lua-cURL](http://luaforge.net/projects/lua-curl/) by Jürgen Hötzel
+
+[Mono](http://forge.novell.com/modules/xfmod/project/?libcurl-mono) Written by Jeffrey Phillips
+
+[.NET](https://sourceforge.net/projects/libcurl-net/) libcurl-net by Jeffrey Phillips
+
+[node.js](https://github.com/JCMais/node-libcurl) node-libcurl by Jonathan Cardoso Machado
+
+[Object-Pascal](http://www.tekool.com/opcurl) Free Pascal, Delphi and Kylix binding written by Christophe Espern.
+
+[O'Caml](https://sourceforge.net/projects/ocurl/) Written by Lars Nilsson
+
+[Pascal](http://houston.quik.com/jkp/curlpas/) Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
+
+[Perl](https://github.com/szbalint/WWW--Curl) Maintained by Cris Bailiff and Bálint Szilakszi
+
+[PHP](https://php.net/curl) Originally written by Sterling Hughes
+
+[PostgreSQL](http://gborg.postgresql.org/project/pgcurl/projdisplay.php) Written by Gian Paolo Ciceri
+
+[Python](http://pycurl.sourceforge.net/) PycURL by Kjetil Jacobsen
+
+[R](http://cran.r-project.org/package=curl)
+
+[Rexx](http://rexxcurl.sourceforge.net/) Written Mark Hessling
+
+RPG, support for ILE/RPG on OS/400 is included in source distribution
+
+Ruby: [curb](http://curb.rubyforge.org/) written by Ross Bamford, [ruby-curl-multi](http://curl-multi.rubyforge.org/) written by Kristjan Petursson and Keith Rarick
+
+[Rust](https://github.com/carllerche/curl-rust) curl-rust - by Carl Lerche
+
+[Scheme](http://www.metapaper.net/lisovsky/web/curl/) Bigloo binding by Kirill Lisovsky
+
+[S-Lang](http://www.jedsoft.org/slang/modules/curl.html) by John E Davis
+
+[Smalltalk](http://www.squeaksource.com/CurlPlugin/) Written by Danil Osipchuk
+
+[SP-Forth](http://www.forth.org.ru/~ac/lib/lin/curl/) Written by ygrek
+
+[SPL](http://www.clifford.at/spl/) Written by Clifford Wolf
+
+[Tcl](http://mirror.yellow5.com/tclcurl/) Tclcurl by Andrés García
+
+[Visual Basic](https://sourceforge.net/projects/libcurl-vb/) libcurl-vb by Jeffrey Phillips
+
+[Visual Foxpro](http://www.ctl32.com.ar/libcurl.asp) by Carlos Alloatti
+
+[Q](http://q-lang.sourceforge.net/) The libcurl module is part of the default install
+
+[wxWidgets](http://wxcode.sourceforge.net/components/wxcurl/) Written by Casey O'Donnell
+
+[XBLite](http://perso.wanadoo.fr/xblite/libraries.html) Written by David Szafranski
+
+[Xojo](https://github.com/charonn0/RB-libcURL) Written by Andrew Lambert
diff --git a/docs/CHECKSRC.md b/docs/CHECKSRC.md
index 591e066..b42de84 100644
--- a/docs/CHECKSRC.md
+++ b/docs/CHECKSRC.md
@@ -20,7 +20,7 @@
 
 checksrc does not check and verify the code against the entire style guide,
 but the script is instead an effort to detect the most common mistakes and
-syntax mistakes that contributers make before they get accustomed to our code
+syntax mistakes that contributors make before they get accustomed to our code
 style. Heck, many of us regulars do the mistakes too and this script helps us
 keep the code in shape.
 
@@ -33,7 +33,7 @@
 - `BADCOMMAND`: There's a bad !checksrc! instruction in the code. See the
    **Ignore certain warnings** section below for details.
 
-- `BANNEDFUNC`: A banned function was used. The funtions sprintf, vsprintf,
+- `BANNEDFUNC`: A banned function was used. The functions sprintf, vsprintf,
    strcat, strncat, gets are **never** allowed in curl source code.
 
 - `BRACEELSE`: '} else' on the same line. The else is supposed to be on the
diff --git a/docs/CODE_STYLE.md b/docs/CODE_STYLE.md
index 73a4d94..ba5f710 100644
--- a/docs/CODE_STYLE.md
+++ b/docs/CODE_STYLE.md
@@ -1,4 +1,4 @@
-# cURL C code style
+# curl C code style
 
 Source code that has a common style is easier to read than code that uses
 different styles in different places. It helps making the code feel like one
@@ -9,8 +9,8 @@
 tastes satisfied.
 
 Our C code has a few style rules. Most of them are verified and upheld by the
-lib/checksrc.pl script. Invoked with `make checksrc` or even by default by the
-build system when built after `./configure --enable-debug` has been used.
+`lib/checksrc.pl` script. Invoked with `make checksrc` or even by default by
+the build system when built after `./configure --enable-debug` has been used.
 
 It is normally not a problem for anyone to follow the guidelines, as you just
 need to copy the style already used in the source code and there are no
@@ -28,7 +28,8 @@
 understandable and be named according to what they're used for. File-local
 functions should be made static. We like lower case names.
 
-See the INTERNALS document on how we name non-exported library-global symbols.
+See the [INTERNALS](INTERNALS.md) document on how we name non-exported
+library-global symbols.
 
 ## Indenting
 
@@ -50,7 +51,7 @@
 
 ## Long lines
 
-Source code in curl may never be wider than 80 columns and there are two
+Source code in curl may never be wider than 79 columns and there are two
 reasons for maintaining this even in the modern era of very large and high
 resolution screens:
 
@@ -72,8 +73,12 @@
       /* clearly a youngster */
     }
 
-When we write functions however, the opening brace should be in the first
-column of the first line:
+You may omit the braces if they would contain only a one-line statement:
+
+    if(!x)
+      continue;
+
+For functions the opening brace should be on a separate line:
 
     int main(int argc, char **argv)
     {
@@ -162,6 +167,53 @@
     complement = ~bits;
     empty = (!*string) ? TRUE : FALSE;
 
+## Column alignment
+
+Some statements cannot be completed on a single line because the line would
+be too long, the statement too hard to read, or due to other style guidelines
+above. In such a case the statement will span multiple lines.
+
+If a continuation line is part of an expression or sub-expression then you
+should align on the appropriate column so that it's easy to tell what part of
+the statement it is. Operators should not start continuation lines. In other
+cases follow the 2-space indent guideline. Here are some examples from libcurl:
+
+~~~c
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+       (handle->set.httpreq == HTTPREQ_GET ||
+        handle->set.httpreq == HTTPREQ_HEAD))
+      /* didn't ask for HTTP/1.0 and a GET or HEAD */
+      return TRUE;
+~~~
+
+~~~c
+  case CURLOPT_KEEP_SENDING_ON_ERROR:
+    data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
+                                           TRUE : FALSE;
+    break;
+~~~
+
+~~~c
+    data->set.http_disable_hostname_check_before_authentication =
+      (0 != va_arg(param, long)) ? TRUE : FALSE;
+~~~
+
+~~~c
+  if(option) {
+    result = parse_login_details(option, strlen(option),
+                                 (userp ? &user : NULL),
+                                 (passwdp ? &passwd : NULL),
+                                 NULL);
+  }
+~~~
+
+~~~c
+        DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+                     "server response left\n",
+                     (int)clipamount));
+~~~
+
 ## Platform dependent code
 
 Use `#ifdef HAVE_FEATURE` to do conditional code. We avoid checking for
diff --git a/docs/CONTRIBUTE b/docs/CONTRIBUTE
deleted file mode 100644
index 9e84175..0000000
--- a/docs/CONTRIBUTE
+++ /dev/null
@@ -1,261 +0,0 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-                        When Contributing Source Code
-
- This document is intended to offer guidelines that can be useful to keep in
- mind when you decide to contribute to the project. This concerns new features
- as well as corrections to existing flaws or bugs.
-
- 1. Learning cURL
- 1.1 Join the Community
- 1.2 License
- 1.3 What To Read
-
- 2. Write a good patch
- 2.1 Follow code style
- 2.2 Non-clobbering All Over
- 2.3 Write Separate Patches
- 2.4 Patch Against Recent Sources
- 2.5 Document
- 2.6 Test Cases
-
- 3. Pushing Out Your Changes
- 3.1 Write Access to git Repository
- 3.2 How To Make a Patch with git
- 3.3 How To Make a Patch without git
- 3.4 How to get your changes into the main sources
- 3.5 Write good commit messages
- 3.6 About pull requests
-
-==============================================================================
-
-1. Learning cURL
-
-1.1 Join the Community
-
- Skip over to https://curl.haxx.se/mail/ and join the appropriate mailing
- list(s).  Read up on details before you post questions. Read this file before
- you start sending patches! We prefer patches and discussions being held on
- the mailing list(s), not sent to individuals.
-
- Before posting to one of the curl mailing lists, please read up on the mailing
- list etiquette: https://curl.haxx.se/mail/etiquette.html
-
- We also hang out on IRC in #curl on irc.freenode.net
-
- If you're at all interested in the code side of things, consider clicking
- 'watch' on the curl repo at github to get notified on pull requests and new
- issues posted there.
-
-1.2. License
-
- When contributing with code, you agree to put your changes and new code under
- the same license curl and libcurl is already using unless stated and agreed
- otherwise.
-
- If you add a larger piece of code, you can opt to make that file or set of
- files to use a different license as long as they don't enforce any changes to
- the rest of the package and they make sense. Such "separate parts" can not be
- GPL licensed (as we don't want copyleft to affect users of libcurl) but they
- must use "GPL compatible" licenses (as we want to allow users to use libcurl
- properly in GPL licensed environments).
-
- When changing existing source code, you do not alter the copyright of the
- original file(s). The copyright will still be owned by the original
- creator(s) or those who have been assigned copyright by the original
- author(s).
-
- By submitting a patch to the curl project, you are assumed to have the right
- to the code and to be allowed by your employer or whatever to hand over that
- patch/code to us. We will credit you for your changes as far as possible, to
- give credit but also to keep a trace back to who made what changes. Please
- always provide us with your full real name when contributing!
-
-1.3 What To Read
-
- Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS and the
- most recent changes in the git log. Just lurking on the curl-library mailing
- list is gonna give you a lot of insights on what's going on right now. Asking
- there is a good idea too.
-
-2. Write a good patch
-
-2.1 Follow code style
-
- When writing C code, follow the CODE_STYLE already established in the
- project. Consistent style makes code easier to read and mistakes less likely
- to happen.
-
-2.2 Non-clobbering All Over
-
- When you write new functionality or fix bugs, it is important that you don't
- fiddle all over the source files and functions. Remember that it is likely
- that other people have done changes in the same source files as you have and
- possibly even in the same functions. If you bring completely new
- functionality, try writing it in a new source file. If you fix bugs, try to
- fix one bug at a time and send them as separate patches.
-
-2.3 Write Separate Patches
-
- It is annoying when you get a huge patch from someone that is said to fix 511
- odd problems, but discussions and opinions don't agree with 510 of them - or
- 509 of them were already fixed in a different way. Then the patcher needs to
- extract the single interesting patch from somewhere within the huge pile of
- source, and that gives a lot of extra work. Preferably, all fixes that
- correct different problems should be in their own patch with an attached
- description exactly what they correct so that all patches can be selectively
- applied by the maintainer or other interested parties.
-
- Also, separate patches enable bisecting much better when we track problems in
- the future.
-
-2.4 Patch Against Recent Sources
-
- Please try to get the latest available sources to make your patches
- against. It makes the life of the developers so much easier. The very best is
- if you get the most up-to-date sources from the git repository, but the
- latest release archive is quite OK as well!
-
-2.5 Document
-
- Writing docs is dead boring and one of the big problems with many open source
- projects. Someone's gotta do it. It makes it a lot easier if you submit a
- small description of your fix or your new features with every contribution so
- that it can be swiftly added to the package documentation.
-
- The documentation is always made in man pages (nroff formatted) or plain
- ASCII files. All HTML files on the web site and in the release archives are
- generated from the nroff/ASCII versions.
-
-2.6 Test Cases
-
- Since the introduction of the test suite, we can quickly verify that the main
- features are working as they're supposed to. To maintain this situation and
- improve it, all new features and functions that are added need to be tested
- in the test suite. Every feature that is added should get at least one valid
- test case that verifies that it works as documented. If every submitter also
- posts a few test cases, it won't end up as a heavy burden on a single person!
-
- If you don't have test cases or perhaps you have done something that is very
- hard to write tests for, do explain exactly how you have otherwise tested and
- verified your changes.
-
-3. Pushing Out Your Changes
-
-3.1 Write Access to git Repository
-
- If you are a frequent contributor, or have another good reason, you can of
- course get write access to the git repository and then you'll be able to push
- your changes straight into the git repo instead of sending changes by mail as
- patches. Just ask if this is what you'd want. You will be required to have
- posted a few quality patches first, before you can be granted push access.
-
-3.2 How To Make a Patch with git
-
- You need to first checkout the repository:
-
-     git clone https://github.com/curl/curl.git
-
- You then proceed and edit all the files you like and you commit them to your
- local repository:
-
-     git commit [file]
-
- As usual, group your commits so that you commit all changes that at once that
- constitutes a logical change. See also section "3.5 Write good commit
- messages".
-
- Once you have done all your commits and you're happy with what you see, you
- can make patches out of your changes that are suitable for mailing:
-
-     git format-patch remotes/origin/master
-
- This creates files in your local directory named NNNN-[name].patch for each
- commit.
-
- Now send those patches off to the curl-library list. You can of course opt to
- do that with the 'git send-email' command.
-
-3.3 How To Make a Patch without git
-
- Keep a copy of the unmodified curl sources. Make your changes in a separate
- source tree. When you think you have something that you want to offer the
- curl community, use GNU diff to generate patches.
-
- If you have modified a single file, try something like:
-
-     diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
-
- If you have modified several files, possibly in different directories, you
- can use diff recursively:
-
-     diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
-
- The GNU diff and GNU patch tools exist for virtually all platforms, including
- all kinds of Unixes and Windows:
-
- For unix-like operating systems:
-
-     https://savannah.gnu.org/projects/patch/
-     https://www.gnu.org/software/diffutils/
-
- For Windows:
-
-     http://gnuwin32.sourceforge.net/packages/patch.htm
-     http://gnuwin32.sourceforge.net/packages/diffutils.htm
-
-3.4 How to get your changes into the main sources
-
- Submit your patch to the curl-library mailing list.
-
- Make the patch against as recent sources as possible.
-
- Make sure your patch adheres to the source indent and coding style of already
- existing source code. Failing to do so just adds more work for me.
-
- Respond to replies on the list about the patch and answer questions and/or
- fix nits/flaws. This is very important. I will take lack of replies as a sign
- that you're not very anxious to get your patch accepted and I tend to simply
- drop such patches from my TODO list.
-
- If you've followed the above paragraphs and your patch still hasn't been
- incorporated after some weeks, consider resubmitting it to the list.
-
-3.5 Write good commit messages
-
- A short guide to how to do fine commit messages in the curl project.
-
-      ---- start ----
-      [area]: [short line describing the main effect]
-
-      [separate the above single line from the rest with an empty line]
-
-      [full description, no wider than 72 columns that describe as much as
-      possible as to why this change is made, and possibly what things
-      it fixes and everything else that is related]
-
-      [Bug: link to source of the report or more related discussion]
-      [Reported-by: John Doe - credit the reporter]
-      [whatever-else-by: credit all helpers, finders, doers]
-      ---- stop ----
-
- Don't forget to use commit --author="" if you commit someone else's work,
- and make sure that you have your own user and email setup correctly in git
- before you commit
-
-3.6 About pull requests
-
- With git (and especially github) it is easy and tempting to send a pull
- request to the curl project to have changes merged this way instead of
- mailing patches to the curl-library mailing list.
-
- We used to dislike this but we're trying to change that and accept that this
- is a frictionless way for people to contribute to the project. We now welcome
- pull requests!
-
- We will continue to avoid using github's merge tools to make the history
- linear and to make sure commits follow our style guidelines.
diff --git a/docs/CONTRIBUTE.md b/docs/CONTRIBUTE.md
new file mode 100644
index 0000000..b0b0f6c
--- /dev/null
+++ b/docs/CONTRIBUTE.md
@@ -0,0 +1,247 @@
+# Contributing to the curl project
+
+This document is intended to offer guidelines on how to best contribute to the
+curl project. This concerns new features as well as corrections to existing
+flaws or bugs.
+
+## Learning curl
+
+### Join the Community
+
+Skip over to [https://curl.haxx.se/mail/](https://curl.haxx.se/mail/) and join
+the appropriate mailing list(s).  Read up on details before you post
+questions. Read this file before you start sending patches! We prefer
+questions sent to and discussions being held on the mailing list(s), not sent
+to individuals.
+
+Before posting to one of the curl mailing lists, please read up on the
+[mailing list etiquette](https://curl.haxx.se/mail/etiquette.html).
+
+We also hang out on IRC in #curl on irc.freenode.net
+
+If you're at all interested in the code side of things, consider clicking
+'watch' on the [curl repo on github](https://github.com/curl/curl) to get
+notified on pull requests and new issues posted there.
+
+### License and copyright
+
+When contributing with code, you agree to put your changes and new code under
+the same license curl and libcurl is already using unless stated and agreed
+otherwise.
+
+If you add a larger piece of code, you can opt to make that file or set of
+files to use a different license as long as they don't enforce any changes to
+the rest of the package and they make sense. Such "separate parts" can not be
+GPL licensed (as we don't want copyleft to affect users of libcurl) but they
+must use "GPL compatible" licenses (as we want to allow users to use libcurl
+properly in GPL licensed environments).
+
+When changing existing source code, you do not alter the copyright of the
+original file(s). The copyright will still be owned by the original creator(s)
+or those who have been assigned copyright by the original author(s).
+
+By submitting a patch to the curl project, you are assumed to have the right
+to the code and to be allowed by your employer or whatever to hand over that
+patch/code to us. We will credit you for your changes as far as possible, to
+give credit but also to keep a trace back to who made what changes. Please
+always provide us with your full real name when contributing!
+
+### What To Read
+
+Source code, the man pages, the [INTERNALS
+document](https://curl.haxx.se/dev/internals.html),
+[TODO](https://curl.haxx.se/docs/todo.html),
+[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) and the [most recent
+changes](https://curl.haxx.se/dev/sourceactivity.html) in git. Just lurking on
+the [curl-library mailing
+list](https://curl.haxx.se/mail/list.cgi?list=curl-library) will give you a
+lot of insights on what's going on right now. Asking there is a good idea too.
+
+## Write a good patch
+
+### Follow code style
+
+When writing C code, follow the
+[CODE_STYLE](https://curl.haxx.se/dev/code-style.html) already established in
+the project. Consistent style makes code easier to read and mistakes less
+likely to happen. Run `make checksrc` before you submit anything, to make sure
+you follow the basic style. That script doesn't verify everything, but if it
+complains you know you have work to do.
+
+### Non-clobbering All Over
+
+When you write new functionality or fix bugs, it is important that you don't
+fiddle all over the source files and functions. Remember that it is likely
+that other people have done changes in the same source files as you have and
+possibly even in the same functions. If you bring completely new
+functionality, try writing it in a new source file. If you fix bugs, try to
+fix one bug at a time and send them as separate patches.
+
+### Write Separate Changes
+
+It is annoying when you get a huge patch from someone that is said to fix 511
+odd problems, but discussions and opinions don't agree with 510 of them - or
+509 of them were already fixed in a different way. Then the person merging
+this change needs to extract the single interesting patch from somewhere
+within the huge pile of source, and that gives a lot of extra work.
+
+Preferably, each fix that correct a problem should be in its own patch/commit
+with its own description/commit message stating exactly what they correct so
+that all changes can be selectively applied by the maintainer or other
+interested parties.
+
+Also, separate changes enable bisecting much better when we track problems
+and regression in the future.
+
+### Patch Against Recent Sources
+
+Please try to get the latest available sources to make your patches against.
+It makes the lives of the developers so much easier. The very best is if you
+get the most up-to-date sources from the git repository, but the latest
+release archive is quite OK as well!
+
+### Documentation
+
+Writing docs is dead boring and one of the big problems with many open source
+projects. Someone's gotta do it. It makes it a lot easier if you submit a
+small description of your fix or your new features with every contribution so
+that it can be swiftly added to the package documentation.
+
+The documentation is always made in man pages (nroff formatted) or plain
+ASCII files. All HTML files on the web site and in the release archives are
+generated from the nroff/ASCII versions.
+
+### Test Cases
+
+Since the introduction of the test suite, we can quickly verify that the main
+features are working as they're supposed to. To maintain this situation and
+improve it, all new features and functions that are added need to be tested
+in the test suite. Every feature that is added should get at least one valid
+test case that verifies that it works as documented. If every submitter also
+posts a few test cases, it won't end up as a heavy burden on a single person!
+
+If you don't have test cases or perhaps you have done something that is very
+hard to write tests for, do explain exactly how you have otherwise tested and
+verified your changes.
+
+## Sharing Your Changes
+
+### How to get your changes into the main sources
+
+Ideally you file a [pull request on
+github](https://github.com/curl/curl/pulls), but you can also send your plain
+patch to [the curl-library mailing
+list](https://curl.haxx.se/mail/list.cgi?list=curl-library).
+
+Either way, your change will be reviewed and discussed there and you will be
+expected to correct flaws pointed out and update accordingly, or the change
+risk stalling and eventually just get deleted without action. As a submitter
+of a change, you are the owner of that change until it has been merged.
+
+Respond on the list or on github about the change and answer questions and/or
+fix nits/flaws. This is very important. We will take lack of replies as a
+sign that you're not very anxious to get your patch accepted and we tend to
+simply drop such changes.
+
+### About pull requests
+
+With github it is easy to send a [pull
+request](https://github.com/curl/curl/pulls) to the curl project to have
+changes merged.
+
+We prefer pull requests to mailed patches, as it makes it a proper git commit
+that is easy to merge and they are easy to track and not that easy to loose
+in a flood of many emails, like they sometimes do on the mailing lists.
+
+When you adjust your pull requests after review, consider squashing the
+commits so that we can review the full updated version more easily.
+
+### Making quality patches
+
+Make the patch against as recent sources as possible.
+
+If you've followed the tips in this document and your patch still hasn't been
+incorporated or responded to after some weeks, consider resubmitting it to
+the list or better yet: change it to a pull request.
+
+### Write good commit messages
+
+A short guide to how to write commit messages in the curl project.
+
+    ---- start ----
+    [area]: [short line describing the main effect]
+           -- empty line --
+    [full description, no wider than 72 columns that describe as much as
+    possible as to why this change is made, and possibly what things
+    it fixes and everything else that is related]
+           -- empty line --
+    [Bug: URL to source of the report or more related discussion]
+    [Reported-by: John Doe - credit the reporter]
+    [whatever-else-by: credit all helpers, finders, doers]
+    ---- stop ----
+
+Don't forget to use commit --author="" if you commit someone else's work,
+and make sure that you have your own user and email setup correctly in git
+before you commit
+
+### Write Access to git Repository
+
+If you are a very frequent contributor, you may be given push access to the
+git repository and then you'll be able to push your changes straight into the
+git repo instead of sending changes as pull requests or by mail as patches.
+
+Just ask if this is what you'd want. You will be required to have posted
+several high quality patches first, before you can be granted push access.
+
+### How To Make a Patch with git
+
+You need to first checkout the repository:
+
+    git clone https://github.com/curl/curl.git
+
+You then proceed and edit all the files you like and you commit them to your
+local repository:
+
+    git commit [file]
+
+As usual, group your commits so that you commit all changes that at once that
+constitutes a logical change.
+
+Once you have done all your commits and you're happy with what you see, you
+can make patches out of your changes that are suitable for mailing:
+
+    git format-patch remotes/origin/master
+
+This creates files in your local directory named NNNN-[name].patch for each
+commit.
+
+Now send those patches off to the curl-library list. You can of course opt to
+do that with the 'git send-email' command.
+
+### How To Make a Patch without git
+
+Keep a copy of the unmodified curl sources. Make your changes in a separate
+source tree. When you think you have something that you want to offer the
+curl community, use GNU diff to generate patches.
+
+If you have modified a single file, try something like:
+
+    diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
+
+If you have modified several files, possibly in different directories, you
+can use diff recursively:
+
+    diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
+
+The GNU diff and GNU patch tools exist for virtually all platforms, including
+all kinds of Unixes and Windows:
+
+For unix-like operating systems:
+
+ - [https://savannah.gnu.org/projects/patch/](https://savannah.gnu.org/projects/patch/)
+ - [https://www.gnu.org/software/diffutils/](https://www.gnu.org/software/diffutils/)
+
+For Windows:
+
+ - [http://gnuwin32.sourceforge.net/packages/patch.htm](http://gnuwin32.sourceforge.net/packages/patch.htm)
+ - [http://gnuwin32.sourceforge.net/packages/diffutils.htm](http://gnuwin32.sourceforge.net/packages/diffutils.htm)
diff --git a/docs/FAQ b/docs/FAQ
index 681ce29..d663811 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -81,7 +81,7 @@
   4.16 My HTTP POST or PUT requests are slow!
   4.17 Non-functional connect timeouts on Windows
   4.18 file:// URLs containing drive letters (Windows, NetWare)
-  4.19 Why doesn't cURL return an error when the network cable is unplugged?
+  4.19 Why doesn't curl return an error when the network cable is unplugged?
   4.20 curl doesn't return error for HTTP non-200 responses!
   4.21 Why is there a HTTP/1.1 in my HTTP/2 request?
 
@@ -968,8 +968,8 @@
 
   4.9 Curl can't authenticate to the server that requires NTLM?
 
-  NTLM support requires OpenSSL, GnuTLS, NSS, Secure Transport, or Microsoft
-  Windows libraries at build-time to provide this functionality.
+  NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or
+  Microsoft Windows libraries at build-time to provide this functionality.
 
   NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
   should not use such ones.
@@ -1083,18 +1083,18 @@
 
   4.18 file:// URLs containing drive letters (Windows, NetWare)
 
-  When using cURL to try to download a local file, one might use a URL
+  When using curl to try to download a local file, one might use a URL
   in this format:
 
   file://D:/blah.txt
 
-  You'll find that even if D:\blah.txt does exist, cURL returns a 'file
+  You'll find that even if D:\blah.txt does exist, curl returns a 'file
   not found' error.
 
   According to RFC 1738 (https://www.ietf.org/rfc/rfc1738.txt),
   file:// URLs must contain a host component, but it is ignored by
   most implementations. In the above example, 'D:' is treated as the
-  host component, and is taken away. Thus, cURL tries to open '/blah.txt'.
+  host component, and is taken away. Thus, curl tries to open '/blah.txt'.
   If your system is installed to drive C:, that will resolve to 'C:\blah.txt',
   and if that doesn't exist you will get the not found error.
 
@@ -1107,9 +1107,9 @@
 
   file://localhost/D:/blah.txt
 
-  In either case, cURL should now be looking for the correct file.
+  In either case, curl should now be looking for the correct file.
 
-  4.19 Why doesn't cURL return an error when the network cable is unplugged?
+  4.19 Why doesn't curl return an error when the network cable is unplugged?
 
   Unplugging a cable is not an error situation. The TCP/IP protocol stack
   was designed to be fault tolerant, so even though there may be a physical
@@ -1385,14 +1385,14 @@
   member function that is passed a pointer to the class:
 
      // f is the pointer to your object.
-     static YourClass::func(void *buffer, size_t sz, size_t n, void *f)
+     static size_t YourClass::func(void *buffer, size_t sz, size_t n, void *f)
      {
        // Call non-static member function.
        static_cast<YourClass*>(f)->nonStaticFunction();
      }
 
      // This is how you pass pointer to the static function:
-     curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass:func);
+     curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass::func);
      curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this);
 
   5.15 How do I get an FTP directory listing?
diff --git a/docs/FEATURES b/docs/FEATURES
index 10fbdd5..24fa56d 100644
--- a/docs/FEATURES
+++ b/docs/FEATURES
@@ -195,8 +195,8 @@
   *7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for
        example, only supports SSLv3 and TLSv1
   *8 = requires libssh2
-  *9 = requires OpenSSL, GnuTLS, NSS, yassl, Secure Transport or SSPI (native
-       Windows)
+  *9 = requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI
+       (native Windows)
   *10 = requires any of the SSL libraries in (*1) above other than axTLS, which
         does not support SSLv3
   *11 = requires libidn or Windows
diff --git a/docs/HISTORY b/docs/HISTORY.md
similarity index 96%
rename from docs/HISTORY
rename to docs/HISTORY.md
index f878ee1..ac93b67 100644
--- a/docs/HISTORY
+++ b/docs/HISTORY.md
@@ -1,10 +1,4 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-How cURL Became Like This
+How curl Became Like This
 =========================
 
 Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot
@@ -178,6 +172,8 @@
 April. GnuTLS can now optionally be used for the secure layer when curl is
 built.
 
+April: Added the multi_socket() API
+
 September: TFTP support was added.
 
 More than 100,000 unique visitors of the curl web site. 25 mirrors.
@@ -193,8 +189,6 @@
 
 March: security vulnerability: libcurl TFTP Packet Buffer Overflow
 
-April: Added the multi_socket() API
-
 September: The major SONAME number for libcurl was bumped to 4 due to the
 removal of ftp third party transfer support.
 
diff --git a/docs/HTTP2.md b/docs/HTTP2.md
index cc5a5b3..efbe699 100644
--- a/docs/HTTP2.md
+++ b/docs/HTTP2.md
@@ -96,18 +96,31 @@
 
 curl offers the `--http2` command line option to enable use of HTTP/2.
 
-curl offers the `--http2-prior-knowledge` command line option to enable use of 
+curl offers the `--http2-prior-knowledge` command line option to enable use of
 HTTP/2 without HTTP/1.1 Upgrade.
 
 Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections.
 
+curl tool limitations
+---------------------
+
+The command line tool won't do any HTTP/2 multiplexing even though libcurl
+supports it, simply because the curl tool is not written to take advantage of
+the libcurl API that's necessary for this (the multi interface). We have an
+outstanding TODO item for this and **you** can help us make it happen.
+
+The command line tool also doesn't support HTTP/2 server push for the same
+reason it doesn't do multiplexing: it needs to use the multi interface for
+that so that multiplexing is supported.
+
 HTTP Alternative Services
 -------------------------
 
-Alt-Svc is a suggested extension with a corresponding frame (ALTSVC) in HTTP/2
-that tells the client about an alternative "route" to the same content for the
-same origin server that you get the response from. A browser or long-living
-client can use that hint to create a new connection asynchronously.  For
-libcurl, we may introduce a way to bring such clues to the applicaton and/or
-let a subsequent request use the alternate route
-automatically. [Spec](https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14)
+Alt-Svc is an extension with a corresponding frame (ALTSVC) in HTTP/2 that
+tells the client about an alternative "route" to the same content for the same
+origin server that you get the response from. A browser or long-living client
+can use that hint to create a new connection asynchronously.  For libcurl, we
+may introduce a way to bring such clues to the application and/or let a
+subsequent request use the alternate route automatically.
+
+[Detailed in RFC 7838](https://tools.ietf.org/html/rfc7838)
diff --git a/docs/INSTALL b/docs/INSTALL
index 2e1075b..ff260b1 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -6,1110 +6,4 @@
 
                                 How To Compile
 
-Installing Binary Packages
-==========================
-
-   Lots of people download binary distributions of curl and libcurl. This
-   document does not describe how to install curl or libcurl using such a
-   binary package. This document describes how to compile, build and install
-   curl and libcurl from source code.
-
-Building from git
-=================
-
-   If you get your code off a git repository, see the GIT-INFO file in the
-   root directory for specific instructions on how to proceed.
-
-Unix
-====
-
-   A normal Unix installation is made in three or four steps (after you've
-   unpacked the source archive):
-
-        ./configure
-        make
-        make test (optional)
-        make install
-
-   You probably need to be root when doing the last command.
-
-   If you have checked out the sources from the git repository, read the
-   GIT-INFO on how to proceed.
-
-   Get a full listing of all available configure options by invoking it like:
-
-        ./configure --help
-
-   If you want to install curl in a different file hierarchy than /usr/local,
-   you need to specify that already when running configure:
-
-        ./configure --prefix=/path/to/curl/tree
-
-   If you happen to have write permission in that directory, you can do 'make
-   install' without being root. An example of this would be to make a local
-   install in your own home directory:
-
-        ./configure --prefix=$HOME
-        make
-        make install
-
-   The configure script always tries to find a working SSL library unless
-   explicitly told not to. If you have OpenSSL installed in the default search
-   path for your compiler/linker, you don't need to do anything special. If
-   you have OpenSSL installed in /usr/local/ssl, you can run configure like:
-
-        ./configure --with-ssl
-
-   If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL)
-   and you have pkg-config installed, set the pkg-config path first, like this:
-
-        env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl
-
-   Without pkg-config installed, use this:
-
-        ./configure --with-ssl=/opt/OpenSSL
-
-   If you insist on forcing a build without SSL support, even though you may
-   have OpenSSL installed in your system, you can run configure like this:
-
-        ./configure --without-ssl
-
-   If you have OpenSSL installed, but with the libraries in one place and the
-   header files somewhere else, you have to set the LDFLAGS and CPPFLAGS
-   environment variables prior to running configure.  Something like this
-   should work:
-
-     (with the Bourne shell and its clones):
-
-        CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
-           ./configure
-
-     (with csh, tcsh and their clones):
-
-        env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
-           ./configure
-
-   If you have shared SSL libs installed in a directory where your run-time
-   linker doesn't find them (which usually causes configure failures), you can
-   provide the -R option to ld on some operating systems to set a hard-coded
-   path to the run-time linker:
-
-        env LDFLAGS=-R/usr/local/ssl/lib ./configure --with-ssl
-
-   MORE OPTIONS
-   ------------
-
-     To force configure to use the standard cc compiler if both cc and gcc are
-     present, run configure like
-
-       CC=cc ./configure
-         or
-       env CC=cc ./configure
-
-     To force a static library compile, disable the shared library creation
-     by running configure like:
-
-       ./configure --disable-shared
-
-     To tell the configure script to skip searching for thread-safe functions,
-     add an option like:
-
-       ./configure --disable-thread
-
-     If you're a curl developer and use gcc, you might want to enable more
-     debug options with the --enable-debug option.
-
-     curl can be built to use a whole range of libraries to provide various
-     useful services, and configure will try to auto-detect a decent
-     default. But if you want to alter it, you can select how to deal with
-     each individual library.
-
-     To build with GnuTLS for SSL/TLS, use both --without-ssl and
-     --with-gnutls.
-
-     To build with Cyassl for SSL/TLS, use both --without-ssl and
-     --with-cyassl.
-
-     To build with NSS for SSL/TLS, use both --without-ssl and --with-nss.
-
-     To build with PolarSSL for SSL/TLS, use both --without-ssl and
-     --with-polarssl.
-
-     To build with axTLS for SSL/TLS, use both --without-ssl and --with-axtls.
-
-     To build with GSS-API support, use --with-gssapi and have the MIT Kerberos
-     or Heimdal packages installed.
-
-     To get support for SCP and SFTP, build with --with-libssh2 and have
-     libssh2 0.16 or later installed.
-
-     To get Metalink support, build with --with-libmetalink and have the
-     libmetalink packages installed.
-
-   SPECIAL CASES
-   -------------
-
-   Some versions of uClibc require configuring with CPPFLAGS=-D_GNU_SOURCE=1
-   to get correct large file support.
-
-   The Open Watcom C compiler on Linux requires configuring with the variables:
-
-       ./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \
-           RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra
-
-Win32
-=====
-
-   Building Windows DLLs and C run-time (CRT) linkage issues
-   ---------------------------------------------------------
-
-   As a general rule, building a DLL with static CRT linkage is highly
-   discouraged, and intermixing CRTs in the same app is something to
-   avoid at any cost.
-
-   Reading and comprehension of Microsoft Knowledge Base articles
-   KB94248 and KB140584 is a must for any Windows developer. Especially
-   important is full understanding if you are not going to follow the
-   advice given above.
-
-   KB94248  - How To Use the C Run-Time
-              https://support.microsoft.com/kb/94248/en-us
-
-   KB140584 - How to link with the correct C Run-Time (CRT) library
-              https://support.microsoft.com/kb/140584/en-us
-
-   KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries
-              https://msdn.microsoft.com/en-us/library/ms235460
-
-   If your app is misbehaving in some strange way, or it is suffering
-   from memory corruption, before asking for further help, please try
-   first to rebuild every single library your app uses as well as your
-   app using the debug multithreaded dynamic C runtime.
-
-   If you get linkage errors read section 5.7 of the FAQ document.
-
-   MingW32
-   -------
-
-   Make sure that MinGW32's bin dir is in the search path, for example:
-
-     set PATH=c:\mingw32\bin;%PATH%
-
-   then run 'mingw32-make mingw32' in the root dir. There are other
-   make targets available to build libcurl with more features, use:
-   'mingw32-make mingw32-zlib' to build with Zlib support;
-   'mingw32-make mingw32-ssl-zlib' to build with SSL and Zlib enabled;
-   'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2, SSL, Zlib;
-   'mingw32-make mingw32-ssh2-ssl-sspi-zlib' to build with SSH2, SSL, Zlib
-   and SSPI support.
-
-   If you have any problems linking libraries or finding header files, be sure
-   to verify that the provided "Makefile.m32" files use the proper paths, and
-   adjust as necessary. It is also possible to override these paths with
-   environment variables, for example:
-
-     set ZLIB_PATH=c:\zlib-1.2.8
-     set OPENSSL_PATH=c:\openssl-1.0.2c
-     set LIBSSH2_PATH=c:\libssh2-1.6.0
-
-   ATTENTION: if you want to build with libssh2 support you have to use latest
-   version 0.17 - previous versions will NOT work with 7.17.0 and later!
-   Use 'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2 and SSL enabled.
-
-   It is now also possible to build with other LDAP SDKs than MS LDAP;
-   currently it is possible to build with native Win32 OpenLDAP, or with the
-   Novell CLDAP SDK. If you want to use these you need to set these vars:
-
-     set LDAP_SDK=c:\openldap
-     set USE_LDAP_OPENLDAP=1
-
-   or for using the Novell SDK:
-
-     set USE_LDAP_NOVELL=1
-
-   If you want to enable LDAPS support then set LDAPS=1.
-
-   - optional MingW32-built OpenLDAP SDK available from:
-     http://www.gknw.net/mirror/openldap/
-   - optional recent Novell CLDAP SDK available from:
-     https://www.novell.com/developer/ndk/ldap_libraries_for_c.html
-
-   Cygwin
-   ------
-
-   Almost identical to the unix installation. Run the configure script in the
-   curl root with 'sh configure'. Make sure you have the sh executable in
-   /bin/ or you'll see the configure fail toward the end.
-
-   Run 'make'
-
-   Dev-Cpp
-   -------
-
-   See the separate INSTALL.devcpp file for details.
-
-   MSVC 6 caveats
-   --------------
-
-   If you use MSVC 6 it is required that you use the February 2003 edition of
-   the 'Platform SDK' which can be downloaded from:
-
-   https://www.microsoft.com/en-us/download/details.aspx?id=12261
-
-   Building any software with MSVC 6 without having PSDK installed is just
-   asking for trouble down the road once you have released it, you might notice
-   the problems in the first corner or ten miles ahead, depending mostly on your
-   choice of static vs dynamic runtime and third party libraries. Anyone using
-   software built in such way will at some point regret having done so.
-
-   If the compiler has been updated with the installation of a service pack as
-   those mentioned in https://support.microsoft.com/kb/194022 the compiler can be
-   safely used to read source code, translate and make it object code.
-
-   But, even with the service packs mentioned above installed, the resulting
-   software generated in such an environment will be using outdated system
-   header files and libraries with bugs and security issues which have already
-   been addressed and fixed long time ago.
-
-   So, building curl and libcurl with MSVC 6 without PSDK is absolutely
-   discouraged for the benefit of anyone using software built in such
-   environment. And it will not be supported in any way, as we could just
-   be hunting bugs which have already been fixed way back in 2003.
-
-   When building with MSVC 6 we attempt to detect if PSDK is not being used,
-   and if this is the case the build process will fail hard with an error
-   message stating that the February 2003 PSDK is required. This is done to
-   protect the unsuspecting and avoid PEBKAC issues.
-
-   Additionally it might happen that a die hard MSVC hacker still wants to
-   build curl and libcurl with MSVC 6 without PSDK installed, even knowing
-   that this is a highly discouraged and unsupported build environment. In
-   this case the brave of heart will be able to build in such an environment
-   with the requisite of defining preprocessor symbol ALLOW_MSVC6_WITHOUT_PSDK
-   in lib/config-win32.h and knowing that LDAP and IPv6 support will be missing.
-
-   MSVC from command line
-   ----------------------
-
-   Run the 'vcvars32.bat' file to get a proper environment. The
-   vcvars32.bat file is part of the Microsoft development environment and
-   you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin'
-   provided that you installed Visual C/C++ 6 in the default directory.
-
-   Then run 'nmake vc' in curl's root directory.
-
-   If you want to compile with zlib support, you will need to build
-   zlib (http://www.zlib.net/) as well. Please read the zlib
-   documentation on how to compile zlib. Define the ZLIB_PATH environment
-   variable to the location of zlib.h and zlib.lib, for example:
-
-     set ZLIB_PATH=c:\zlib-1.2.8
-
-   Then run 'nmake vc-zlib' in curl's root directory.
-
-   If you want to compile with SSL support you need the OpenSSL package.
-   Please read the OpenSSL documentation on how to compile and install
-   the OpenSSL libraries.  The build process of OpenSSL generates the
-   libeay32.dll and ssleay32.dll files in the out32dll subdirectory in
-   the OpenSSL home directory.  OpenSSL static libraries (libeay32.lib,
-   ssleay32.lib, RSAglue.lib) are created in the out32 subdirectory.
-
-   Before running nmake define the OPENSSL_PATH environment variable with
-   the root/base directory of OpenSSL, for example:
-
-     set OPENSSL_PATH=c:\openssl-0.9.8zc
-
-   Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
-   directory.  'nmake vc-ssl' will create a libcurl static and dynamic
-   libraries in the lib subdirectory, as well as a statically linked
-   version of curl.exe in the src subdirectory.  This statically linked
-   version is a standalone executable not requiring any DLL at
-   runtime. This make method requires that you have the static OpenSSL
-   libraries available in OpenSSL's out32 subdirectory.
-   'nmake vc-ssl-dll' creates the libcurl dynamic library and
-   links curl.exe against libcurl and OpenSSL dynamically.
-   This executable requires libcurl.dll and the OpenSSL DLLs
-   at runtime.
-   Run 'nmake vc-ssl-zlib' to build with both ssl and zlib support.
-
-   MSVC IDE
-   --------
-
-   A fairly comprehensive set of Visual Studio project files are available for
-   v6.0 through v12.0 and are located in the projects folder to allow proper
-   building of both the libcurl library as well as the curl tool.
-
-   For more information about these projects and building via Visual Studio
-   please see the README file located in the projects folder.
-
-   Borland C++ compiler
-   --------------------
-
-   Ensure that your build environment is properly set up to use the compiler
-   and associated tools. PATH environment variable must include the path to
-   bin subdirectory of your compiler installation, eg: c:\Borland\BCC55\bin
-
-   It is advisable to set environment variable BCCDIR to the base path of
-   the compiler installation.
-
-     set BCCDIR=c:\Borland\BCC55
-
-   In order to build a plain vanilla version of curl and libcurl run the
-   following command from curl's root directory:
-
-     make borland
-
-   To build curl and libcurl with zlib and OpenSSL support set environment
-   variables ZLIB_PATH and OPENSSL_PATH to the base subdirectories of the
-   already built zlib and OpenSSL libraries and from curl's root directory
-   run command:
-
-     make borland-ssl-zlib
-
-   libcurl library will be built in 'lib' subdirectory while curl tool
-   is built in 'src' subdirectory. In order to use libcurl library it is
-   advisable to modify compiler's configuration file bcc32.cfg located
-   in c:\Borland\BCC55\bin to reflect the location of libraries include
-   paths for example the '-I' line could result in something like:
-
-     -I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32"
-
-   bcc3.cfg '-L' line could also be modified to reflect the location of
-   of libcurl library resulting for example:
-
-     -L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32"
-
-   In order to build sample program 'simple.c' from the docs\examples
-   subdirectory run following command from mentioned subdirectory:
-
-     bcc32 simple.c libcurl.lib cw32mt.lib
-
-   In order to build sample program simplessl.c an SSL enabled libcurl
-   is required, as well as the OpenSSL libeay32.lib and ssleay32.lib
-   libraries.
-
-   OTHER MSVC IDEs
-   ---------------
-
-   If you use VC++, Borland or similar compilers. Include all lib source
-   files in a static lib "project" (all .c and .h files that is).
-   (you should name it libcurl or similar)
-
-   Make the sources in the src/ drawer be a "win32 console application"
-   project. Name it curl.
-
-   Disabling Specific Protocols in Win32 builds
-   --------------------------------------------
-
-   The configure utility, unfortunately, is not available for the Windows
-   environment, therefore, you cannot use the various disable-protocol
-   options of the configure utility on this platform.
-
-   However, you can use the following defines to disable specific
-   protocols:
-
-   HTTP_ONLY             disables all protocols except HTTP
-   CURL_DISABLE_FTP      disables FTP
-   CURL_DISABLE_LDAP     disables LDAP
-   CURL_DISABLE_TELNET   disables TELNET
-   CURL_DISABLE_DICT     disables DICT
-   CURL_DISABLE_FILE     disables FILE
-   CURL_DISABLE_TFTP     disables TFTP
-   CURL_DISABLE_HTTP     disables HTTP
-   CURL_DISABLE_IMAP     disables IMAP
-   CURL_DISABLE_POP3     disables POP3
-   CURL_DISABLE_SMTP     disables SMTP
-
-   If you want to set any of these defines you have the following options:
-
-   - Modify lib/config-win32.h
-   - Modify lib/curl_setup.h
-   - Modify lib/Makefile.vc6
-   - Modify the "Preprocessor Definitions" in the libcurl project
-
-   Note: The pre-processor settings can be found using the Visual Studio IDE
-   under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
-   Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
-   versions.
-
-   Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds
-   --------------------------------------------------------------------
-
-   In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack
-   it is necessary to make definition of preprocessor symbol USE_LWIPSOCK
-   visible to libcurl and curl compilation processes. To set this definition
-   you have the following alternatives:
-
-   - Modify lib/config-win32.h and src/config-win32.h
-   - Modify lib/Makefile.vc6
-   - Modify the "Preprocessor Definitions" in the libcurl project
-
-   Note: The pre-processor settings can be found using the Visual Studio IDE
-   under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
-   Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
-   versions.
-
-   Once that libcurl has been built with BSD-style lwIP TCP/IP stack support,
-   in order to use it with your program it is mandatory that your program
-   includes lwIP header file <lwip/opt.h> (or another lwIP header that includes
-   this) before including any libcurl header. Your program does not need the
-   USE_LWIPSOCK preprocessor definition which is for libcurl internals only.
-
-   Compilation has been verified with lwIP 1.4.0 and contrib-1.4.0 from:
-
-   http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip
-   http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip
-
-   This BSD-style lwIP TCP/IP stack support must be considered experimental
-   given that it has been verified that lwIP 1.4.0 still needs some polish,
-   and libcurl might yet need some additional adjustment, caveat emptor.
-
-   Important static libcurl usage note
-   -----------------------------------
-
-   When building an application that uses the static libcurl library, you must
-   add '-DCURL_STATICLIB' to your CFLAGS.  Otherwise the linker will look for
-   dynamic import symbols.
-
-   Legacy Windows and SSL
-   ----------------------
-
-   WinSSL (specifically SChannel from Windows SSPI), is the native SSL library
-   in Windows. However, WinSSL in Windows <= XP is unable to connect to servers
-   that no longer support the legacy handshakes and algorithms used by those
-   versions. If you will be using curl in one of those earlier versions of
-   Windows you should choose another SSL backend such as OpenSSL.
-
-Apple iOS and Mac OS X
-======================
-
-   On recent Apple operating systems, curl can be built to use Apple's
-   SSL/TLS implementation, Secure Transport, instead of OpenSSL. To build with
-   Secure Transport for SSL/TLS, use the configure option --with-darwinssl. (It
-   is not necessary to use the option --without-ssl.) This feature requires iOS
-   5.0 or later, or OS X 10.5 ("Leopard") or later.
-
-   When Secure Transport is in use, the curl options --cacert and --capath and
-   their libcurl equivalents, will be ignored, because Secure Transport uses
-   the certificates stored in the Keychain to evaluate whether or not to trust
-   the server. This, of course, includes the root certificates that ship with
-   the OS. The --cert and --engine options, and their libcurl equivalents, are
-   currently unimplemented in curl with Secure Transport.
-
-   For OS X users: In OS X 10.8 ("Mountain Lion"), Apple made a major
-   overhaul to the Secure Transport API that, among other things, added
-   support for the newer TLS 1.1 and 1.2 protocols. To get curl to support
-   TLS 1.1 and 1.2, you must build curl on Mountain Lion or later, or by
-   using the equivalent SDK. If you set the MACOSX_DEPLOYMENT_TARGET
-   environmental variable to an earlier version of OS X prior to building curl,
-   then curl will use the new Secure Transport API on Mountain Lion and later,
-   and fall back on the older API when the same curl binary is executed on
-   older cats. For example, running these commands in curl's directory in the
-   shell will build the code such that it will run on cats as old as OS X 10.6
-   ("Snow Leopard") (using bash):
-
-      export MACOSX_DEPLOYMENT_TARGET="10.6"
-      ./configure --with-darwinssl
-      make
-
-IBM OS/2
-========
-
-   Building under OS/2 is not much different from building under unix.
-   You need:
-
-      - emx 0.9d
-      - GNU make
-      - GNU patch
-      - ksh
-      - GNU bison
-      - GNU file utilities
-      - GNU sed
-      - autoconf 2.13
-
-   If you want to build with OpenSSL or OpenLDAP support, you'll need to
-   download those libraries, too. Dirk Ohme has done some work to port SSL
-   libraries under OS/2, but it looks like he doesn't care about emx.  You'll
-   find his patches on: http://come.to/Dirk_Ohme
-
-   If during the linking you get an error about _errno being an undefined
-   symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__
-   in your definitions.
-
-   If everything seems to work fine but there's no curl.exe, you need to add
-   -Zexe to your linker flags.
-
-   If you're getting huge binaries, probably your makefiles have the -g in
-   CFLAGS.
-
-VMS
-===
-
-   (The VMS section is in whole contributed by the friendly Nico Baggus)
-
-   Curl seems to work with FTP & HTTP other protocols are not tested.  (the
-   perl http/ftp testing server supplied as testing too cannot work on VMS
-   because vms has no concept of fork(). [ I tried to give it a whack, but
-   that's of no use.
-
-   SSL stuff has not been ported.
-
-   Telnet has about the same issues as for Win32. When the changes for Win32
-   are clear maybe they'll work for VMS too. The basic problem is that select
-   ONLY works for sockets.
-
-   Marked instances of fopen/[f]stat that might become a problem, especially
-   for non stream files. In this regard, the files opened for writing will be
-   created stream/lf and will thus be safe. Just keep in mind that non-binary
-   read/wring from/to files will have a records size limit of 32767 bytes
-   imposed.
-
-   Stat to get the size of the files is again only safe for stream files &
-   fixed record files without implied CC.
-
-   -- My guess is that only allowing access to stream files is the quickest
-   way to get around the most issues. Therefore all files need to to be
-   checked to be sure they will be stream/lf before processing them.  This is
-   the easiest way out, I know. The reason for this is that code that needs to
-   report the filesize will become a pain in the ass otherwise.
-
-   Exit status.... Well we needed something done here,
-
-   VMS has a structured exist status:
-   | 3  |       2    |     1       |  0|
-   |1098|765432109876|5432109876543|210|
-   +----+------------+-------------+---+
-   |Ctrl|  Facility  | Error code  |sev|
-   +----+------------+-------------+---+
-
-   With the Ctrl-bits an application can tell if part or the whole message has
-   already been printed from the program, DCL doesn't need to print it again.
-
-   Facility - basically the program ID. A code assigned to the program
-   the name can be fetched from external or internal message libraries
-   Error code - the err codes assigned by the application
-   Sev. - severity: Even = error, off = non error
-
-      0 = Warning
-      1 = Success
-      2 = Error
-      3 = Information
-      4 = Fatal
-      <5-7> reserved.
-
-   This all presents itself with:
-   %<FACILITY>-<Sev>-<Errorname>, <Error message>
-
-   See also the src/curlmsg.msg file, it has the source for the messages In
-   src/main.c a section is devoted to message status values, the globalvalues
-   create symbols with certain values, referenced from a compiled message
-   file. Have all exit function use a exit status derived from a translation
-   table with the compiled message codes.
-
-   This was all compiled with:
-
-      Compaq C V6.2-003 on OpenVMS Alpha V7.1-1H2
-
-   So far for porting notes as of:
-
-   13-jul-2001
-   N. Baggus
-
-QNX
-===
-
-   (This section was graciously brought to us by David Bentham)
-
-   As QNX is targeted for resource constrained environments, the QNX headers
-   set conservative limits. This includes the FD_SETSIZE macro, set by default
-   to 32. Socket descriptors returned within the CURL library may exceed this,
-   resulting in memory faults/SIGSEGV crashes when passed into select(..)
-   calls using fd_set macros.
-
-   A good all-round solution to this is to override the default when building
-   libcurl, by overriding CFLAGS during configure, example
-
-   #  configure CFLAGS='-DFD_SETSIZE=64 -g -O2'
-
-RISC OS
-=======
-
-   The library can be cross-compiled using gccsdk as follows:
-
-        CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \
-             --host=arm-riscos-aof --without-random --disable-shared
-        make
-
-   where riscos-gcc and riscos-ar are links to the gccsdk tools.
-   You can then link your program with curl/lib/.libs/libcurl.a
-
-AmigaOS
-=======
-
-   (This section was graciously brought to us by Diego Casorran)
-
-   To build cURL/libcurl on AmigaOS just type 'make amiga' ...
-
-   What you need is:    (not tested with others versions)
-
-        GeekGadgets / gcc 2.95.3 (http://www.geekgadgets.org/)
-
-        AmiTCP SDK v4.3 (http://www.aminet.net/comm/tcp/AmiTCP-SDK-4.3.lha)
-
-        Native Developer Kit (http://www.amiga.com/3.9/download/NDK3.9.lha)
-
-   As no ixemul.library is required you will be able to build it for
-   WarpOS/PowerPC (not tested by me), as well a MorphOS version should be
-   possible with no problems.
-
-   To enable SSL support, you need a OpenSSL native version (without ixemul),
-   you can find a precompiled package at http://amiga.sourceforge.net/OpenSSL/
-
-NetWare
-=======
-
-   To compile curl.nlm / libcurl.nlm you need:
-
-   - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later.
-   - gnu make and awk running on the platform you compile on;
-     native Win32 versions can be downloaded from:
-     http://www.gknw.net/development/prgtools/
-   - recent Novell LibC or Novell CLib SDK available from:
-     https://www.novell.com/developer/ndk/
-   - optional recent Novell CLDAP SDK available from:
-     https://www.novell.com/developer/ndk/ldap_libraries_for_c.html
-   - optional zlib sources (static or dynamic linking with zlib.imp);
-     sources with NetWare Makefile can be obtained from:
-     http://www.gknw.net/mirror/zlib/
-   - optional OpenSSL sources (version 0.9.8 or later build with BSD sockets);
-     you can find precompiled packages at:
-     http://www.gknw.net/development/ossl/netware/
-     for CLIB-based builds OpenSSL 0.9.8h or later is required  - earlier versions
-     don't support building with CLIB BSD sockets.
-   - optional SSH2 sources (version 0.17 or later);
-
-   Set a search path to your compiler, linker and tools; on Linux make
-   sure that the var OSTYPE contains the string 'linux'; set the var
-   NDKBASE to point to the base of your Novell NDK; and then type
-   'make netware' from the top source directory; other targets available
-   are 'netware-ssl', 'netware-ssl-zlib', 'netware-zlib' and 'netware-ares';
-   if you need other combinations you can control the build with the
-   environment variables WITH_SSL, WITH_ZLIB, WITH_ARES, WITH_SSH2, and
-   ENABLE_IPV6; you can set LINK_STATIC=1 to link curl.nlm statically.
-   By default LDAP support is enabled, however currently you will need a patch
-   in order to use the CLDAP NDK with BSD sockets (Novell Bug 300237):
-   http://www.gknw.net/test/curl/cldap_ndk/ldap_ndk.diff
-   I found on some Linux systems (RH9) that OS detection didn't work although
-   a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it
-   with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...
-   Any help in testing appreciated!
-   Builds automatically created 8 times a day from current git are here:
-   http://www.gknw.net/mirror/curl/autobuilds/
-   the status of these builds can be viewed at the autobuild table:
-   https://curl.haxx.se/dev/builds.html
-
-eCos
-====
-
-   curl does not use the eCos build system, so you must first build eCos
-   separately, then link curl to the resulting eCos library.  Here's a sample
-   configure line to do so on an x86 Linux box targeting x86:
-
-   GCCLIB=`gcc -print-libgcc-file-name` && \
-   CFLAGS="-D__ECOS=1 -nostdinc -I$ECOS_INSTALL/include \
-    -I`dirname $GCCLIB`/include" \
-   LDFLAGS="-nostdlib -Wl,--gc-sections -Wl,-static \
-    -L$ECOS_INSTALL/lib -Ttarget.ld -ltarget" \
-   ./configure --host=i386 --disable-shared \
-    --without-ssl --without-zlib --disable-manual --disable-ldap
-
-   In most cases, eCos users will be using libcurl from within a custom
-   embedded application.  Using the standard 'curl' executable from
-   within eCos means facing the limitation of the standard eCos C
-   startup code which does not allow passing arguments in main().  To
-   run 'curl' from eCos and have it do something useful, you will need
-   to either modify the eCos startup code to pass in some arguments, or
-   modify the curl application itself to retrieve its arguments from
-   some location set by the bootloader or hard-code them.
-
-   Something like the following patch could be used to hard-code some
-   arguments.  The MTAB_ENTRY line mounts a RAM disk as the root filesystem
-   (without mounting some kind of filesystem, eCos errors out all file
-   operations which curl does not take to well).  The next section synthesizes
-   some command-line arguments for curl to use, in this case to direct curl
-   to read further arguments from a file.  It then creates that file on the
-   RAM disk and places within it a URL to download: a file: URL that
-   just happens to point to the configuration file itself.  The results
-   of running curl in this way is the contents of the configuration file
-   printed to the console.
-
---- src/main.c  19 Jul 2006 19:09:56 -0000    1.363
-+++ src/main.c  24 Jul 2006 21:37:23 -0000
-@@ -4286,11 +4286,31 @@
- }
-
-
-+#ifdef __ECOS
-+#include <cyg/fileio/fileio.h>
-+MTAB_ENTRY( testfs_mte1,
-+                   "/",
-+                   "ramfs",
-+                   "",
-+                   0);
-+#endif
-
- int main(int argc, char *argv[])
- {
-   int res;
-   struct Configurable config;
-+#ifdef __ECOS
-+  char *args[] = {"ecos-curl", "-K", "curlconf.txt"};
-+  FILE *f;
-+  argc = sizeof(args)/sizeof(args[0]);
-+  argv = args;
-+
-+  f = fopen("curlconf.txt", "w");
-+  if (f) {
-+    fprintf(f, "--url file:curlconf.txt");
-+    fclose(f);
-+  }
-+#endif
-   memset(&config, 0, sizeof(struct Configurable));
-
-   config.errors = stderr; /* default errors to stderr */
-
-Minix
-=====
-
-   curl can be compiled on Minix 3 using gcc or ACK (starting with
-   ver. 3.1.3).  Ensure that GNU gawk and bash are both installed and
-   available in the PATH.
-
-   ACK
-   ---
-   Increase the heap sizes of the compiler with the command:
-
-     binsizes xxl
-
-   then configure and compile curl with:
-
-     ./configure CC=cc LD=cc AR=/usr/bin/aal GREP=grep \
-      CPPFLAGS='-D_POSIX_SOURCE=1 -I/usr/local/include'
-     make
-     chmem =256000 src/curl
-
-   GCC
-   ---
-   Make sure gcc is in your PATH with the command:
-
-     export PATH=/usr/gnu/bin:$PATH
-
-   then configure and compile curl with:
-
-     ./configure CC=gcc AR=/usr/gnu/bin/gar GREP=grep
-     make
-     chmem =256000 src/curl
-
-Symbian OS
-==========
-
-   The Symbian OS port uses the Symbian build system to compile.  From the
-   packages/Symbian/group/ directory, run:
-
-      bldmake bldfiles
-      abld build
-
-   to compile and install curl and libcurl using SBSv1. If your Symbian
-   SDK doesn't include support for P.I.P.S., you will need to contact
-   your SDK vendor to obtain that first.
-
-VxWorks
-========
-
-   Build for VxWorks is performed using cross compilation.
-   That means you build on Windows machine using VxWorks tools and
-   run the built image on the VxWorks device.
-
-   To build libcurl for VxWorks you need:
-
-      - CYGWIN (free, https://cygwin.com/)
-      - Wind River Workbench (commercial)
-
-   If you have CYGWIN and Workbench installed on you machine
-   follow after next steps:
-
-    1. Open the Command Prompt window and change directory ('cd')
-       to the libcurl 'lib' folder.
-    2. Add CYGWIN 'bin' folder to the PATH environment variable.
-       For example, type 'set PATH=C:/embedded/cygwin/bin;%PATH%'.
-    3. Adjust environment variables defined in 'Environment' section
-       of the Makefile.vxworks file to point to your software folders.
-    4. Build the libcurl by typing 'make -f ./Makefile.vxworks'
-
-   As a result the libcurl.a library should be created in the 'lib' folder.
-   To clean the build results type 'make -f ./Makefile.vxworks clean'.
-
-Android
-=======
-
-   Method using the static makefile:
-
-      - see the build notes in the packages/Android/Android.mk file.
-
-   Method using a configure cross-compile (tested with Android NDK r7c, r8):
-
-      - prepare the toolchain of the Android NDK for standalone use; this can
-        be done by invoking the script:
-        ./build/tools/make-standalone-toolchain.sh
-        which creates a usual cross-compile toolchain. Lets assume that you put
-        this toolchain below /opt then invoke configure with something like:
-        export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
-        ./configure --host=arm-linux-androideabi [more configure options]
-        make
-      - if you want to compile directly from our GIT repo you might run into
-        this issue with older automake stuff:
-        checking host system type...
-        Invalid configuration `arm-linux-androideabi':
-        system `androideabi' not recognized
-        configure: error: /bin/sh ./config.sub arm-linux-androideabi failed
-        this issue can be fixed with using more recent versions of config.sub
-        and config.guess which can be obtained here:
-        http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree
-        you need to replace your system-own versions which usually can be
-        found in your automake folder:
-        find /usr -name config.sub
-
-   Wrapper for pkg-config:
-
-      - In order to make proper use of pkg-config so that configure is able to
-        find all dependencies you should create a wrapper script for pkg-config;
-        file /opt/arm-linux-androideabi-4.4.3/bin/arm-linux-androideabi-pkg-config:
-
-        #!/bin/sh
-        SYSROOT=$(dirname ${0%/*})/sysroot
-        export PKG_CONFIG_DIR=
-        export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig
-        export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
-        exec pkg-config "$@"
-
-        also create a copy or symlink with name arm-unknown-linux-androideabi-pkg-config.
-
-CROSS COMPILE
-=============
-
-   (This section was graciously brought to us by Jim Duey, with additions by
-   Dan Fandrich)
-
-   Download and unpack the cURL package.
-
-   'cd' to the new directory. (e.g. cd curl-7.12.3)
-
-   Set environment variables to point to the cross-compile toolchain and call
-   configure with any options you need.  Be sure and specify the '--host' and
-   '--build' parameters at configuration time.  The following script is an
-   example of cross-compiling for the IBM 405GP PowerPC processor using the
-   toolchain from MonteVista for Hardhat Linux.
-
-   (begin script)
-
-   #! /bin/sh
-
-   export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
-   export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
-   export AR=ppc_405-ar
-   export AS=ppc_405-as
-   export LD=ppc_405-ld
-   export RANLIB=ppc_405-ranlib
-   export CC=ppc_405-gcc
-   export NM=ppc_405-nm
-
-   ./configure --target=powerpc-hardhat-linux \
-        --host=powerpc-hardhat-linux \
-        --build=i586-pc-linux-gnu \
-        --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \
-        --exec-prefix=/usr/local
-
-   (end script)
-
-   You may also need to provide a parameter like '--with-random=/dev/urandom'
-   to configure as it cannot detect the presence of a random number
-   generating device for a target system.  The '--prefix' parameter
-   specifies where cURL will be installed.  If 'configure' completes
-   successfully, do 'make' and 'make install' as usual.
-
-   In some cases, you may be able to simplify the above commands to as
-   little as:
-
-       ./configure --host=ARCH-OS
-
-REDUCING SIZE
-=============
-
-   There are a number of configure options that can be used to reduce the
-   size of libcurl for embedded applications where binary size is an
-   important factor.  First, be sure to set the CFLAGS variable when
-   configuring with any relevant compiler optimization flags to reduce the
-   size of the binary.  For gcc, this would mean at minimum the -Os option,
-   and potentially the -march=X, -mdynamic-no-pic and -flto options as well,
-   e.g.
-
-      ./configure CFLAGS='-Os' LDFLAGS='-Wl,-Bsymbolic'...
-
-   Note that newer compilers often produce smaller code than older versions
-   due to improved optimization.
-
-   Be sure to specify as many --disable- and --without- flags on the configure
-   command-line as you can to disable all the libcurl features that you
-   know your application is not going to need.  Besides specifying the
-   --disable-PROTOCOL flags for all the types of URLs your application
-   will not use, here are some other flags that can reduce the size of the
-   library:
-
-     --disable-ares (disables support for the C-ARES DNS library)
-     --disable-cookies (disables support for HTTP cookies)
-     --disable-crypto-auth (disables HTTP cryptographic authentication)
-     --disable-ipv6 (disables support for IPv6)
-     --disable-manual (disables support for the built-in documentation)
-     --disable-proxy (disables support for HTTP and SOCKS proxies)
-     --disable-unix-sockets (disables support for UNIX sockets)
-     --disable-verbose (eliminates debugging strings and error code strings)
-     --disable-versioned-symbols (disables support for versioned symbols)
-     --enable-hidden-symbols (eliminates unneeded symbols in the shared library)
-     --without-libidn (disables support for the libidn DNS library)
-     --without-librtmp (disables support for RTMP)
-     --without-ssl (disables support for SSL/TLS)
-     --without-zlib (disables support for on-the-fly decompression)
-
-   The GNU compiler and linker have a number of options that can reduce the
-   size of the libcurl dynamic libraries on some platforms even further.
-   Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
-   configure command-line, e.g.
-
-     CFLAGS="-Os -ffunction-sections -fdata-sections \
-             -fno-unwind-tables -fno-asynchronous-unwind-tables -flto" \
-     LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
-
-   Be sure also to strip debugging symbols from your binaries after
-   compiling using 'strip' (or the appropriate variant if cross-compiling).
-   If space is really tight, you may be able to remove some unneeded
-   sections of the shared library using the -R option to objcopy (e.g. the
-   .comment section).
-
-   Using these techniques it is possible to create a basic HTTP-only shared
-   libcurl library for i386 Linux platforms that is only 109 KiB in size, and
-   an FTP-only library that is 109 KiB in size (as of libcurl version 7.45.0,
-   using gcc 4.9.2).
-
-   You may find that statically linking libcurl to your application will
-   result in a lower total size than dynamically linking.
-
-   Note that the curl test harness can detect the use of some, but not all, of
-   the --disable statements suggested above. Use will cause tests relying on
-   those features to fail.  The test harness can be manually forced to skip
-   the relevant tests by specifying certain key words on the runtests.pl
-   command line.  Following is a list of appropriate key words:
-
-     --disable-cookies          !cookies
-     --disable-manual           !--manual
-     --disable-proxy            !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5
-
-PORTS
-=====
-
-   This is a probably incomplete list of known hardware and operating systems
-   that curl has been compiled for. If you know a system curl compiles and
-   runs on, that isn't listed, please let us know!
-
-        - Alpha DEC OSF 4
-        - Alpha Digital UNIX v3.2
-        - Alpha FreeBSD 4.1, 4.5
-        - Alpha Linux 2.2, 2.4
-        - Alpha NetBSD 1.5.2
-        - Alpha OpenBSD 3.0
-        - Alpha OpenVMS V7.1-1H2
-        - Alpha Tru64 v5.0 5.1
-        - AVR32 Linux
-        - ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
-        - ARM INTEGRITY
-        - ARM iOS
-        - Cell Linux
-        - Cell Cell OS
-        - HP-PA HP-UX 9.X 10.X 11.X
-        - HP-PA Linux
-        - HP3000 MPE/iX
-        - MicroBlaze uClinux
-        - MIPS IRIX 6.2, 6.5
-        - MIPS Linux
-        - OS/400
-        - Pocket PC/Win CE 3.0
-        - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
-        - PowerPC Darwin 1.0
-        - PowerPC INTEGRITY
-        - PowerPC Linux
-        - PowerPC Mac OS 9
-        - PowerPC Mac OS X
-        - SH4 Linux 2.6.X
-        - SH4 OS21
-        - SINIX-Z v5
-        - Sparc Linux
-        - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
-        - Sparc SunOS 4.1.X
-        - StrongARM (and other ARM) RISC OS 3.1, 4.02
-        - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
-        - StrongARM NetBSD 1.4.1
-        - Symbian OS (P.I.P.S.) 9.x
-        - TPF
-        - Ultrix 4.3a
-        - UNICOS 9.0
-        - i386 BeOS
-        - i386 DOS
-        - i386 eCos 1.3.1
-        - i386 Esix 4.1
-        - i386 FreeBSD
-        - i386 HURD
-        - i386 Haiku OS
-        - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
-        - i386 Mac OS X
-        - i386 MINIX 3.1
-        - i386 NetBSD
-        - i386 Novell NetWare
-        - i386 OS/2
-        - i386 OpenBSD
-        - i386 QNX 6
-        - i386 SCO unix
-        - i386 Solaris 2.7
-        - i386 Windows 95, 98, ME, NT, 2000, XP, 2003
-        - i486 ncr-sysv4.3.03 (NCR MP-RAS)
-        - ia64 Linux 2.3.99
-        - m68k AmigaOS 3
-        - m68k Linux
-        - m68k uClinux
-        - m68k OpenBSD
-        - m88k dg-dgux5.4R3.00
-        - s390 Linux
-        - x86_64 Linux
-        - XScale/PXA250 Linux 2.4
-        - Nios II uClinux
-
-Useful URLs
-===========
-
-axTLS        http://axtls.sourceforge.net/
-c-ares       http://c-ares.haxx.se/
-GNU GSS      https://www.gnu.org/software/gss/
-GnuTLS       https://www.gnu.org/software/gnutls/
-Heimdal      http://www.h5l.org/
-libidn       https://www.gnu.org/software/libidn/
-libmetalink  https://launchpad.net/libmetalink/
-libssh2      https://www.libssh2.org/
-MIT Kerberos http://web.mit.edu/kerberos/www/dist/
-NSS          https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
-OpenLDAP     http://www.openldap.org/
-OpenSSL      https://www.openssl.org/
-PolarSSL     https://tls.mbed.org/
-wolfSSL      https://www.wolfssl.com/wolfSSL/
-Zlib         http://www.zlib.net/
-
-MingW        http://www.mingw.org/
-MinGW-w64    http://mingw-w64.sourceforge.net/
-OpenWatcom   http://www.openwatcom.org/
+see INSTALL.md
diff --git a/docs/INSTALL.devcpp b/docs/INSTALL.devcpp
deleted file mode 100644
index f989d52..0000000
--- a/docs/INSTALL.devcpp
+++ /dev/null
@@ -1,302 +0,0 @@
-DevCpp-Mingw Install & Compilation                                   Sept 2005
-==================================
-
-Reference Emails available at curl@haxx.se:
-
-  Libcurl Install and Use Issues
-  Awaiting an Answer for Win 32 Install
-  res = curl_easy_perform(curl); Error
-  Makefile Issues
-
-
-Having previously done a thorough review of what was available that met my
-requirements under GPL, I settled for Libcurl as the software of choice for
-many reasons not the least of which was the support.
-
-Background
-----------
-
-This quest started when I innocently tried to incorporate the libcurl library
-into my simple source code. I figured that a few easy steps would accomplish
-this without major headaches. I had no idea that I would be facing an almost
-insurmountable challenge.
-
-The main problem lies in two areas. First the bulk of support for libcurl
-exists for a Unix/linux command line environments. This is of little help when
-it comes to Windows O/S.
-
-Secondly the help that does exist for the Windows O/S focused around mingw
-through a command line argument environment.
-
-You may ask "Why is this a problem?"
-
-I'm using a Windows O/S with DevCpp. For those of you who are unfamiliar with
-DevCpp, it is a window shell GUI that replaces the command line environment
-for gcc. A definite improvement that I am unwilling to give up. However using
-DevCpp presented its own set of issues. Inadvertently I also made some
-careless errors such as compiling the 7.14 version of Makefile with an older
-version of source code. Thanks to Dan Fandrich for picking this up.
-
-I did eventually with the help of Daniel, Phillipe and others manage to
-implement successfully (the only mingw available version)
-curl-7.13.0-win32-ssl-devel-mingw32 into the DevCpp environment. Only the
-dynamic libcurl.dll libcurldll.a libraries worked. The static library which I
-was interested in did not. Furthermore when I tried to implement one of the
-examples included with the curl package (get info.c) it caused the executable
-to crash. Tracing the bug I found it in the code and function res =
-curl_easy_perform(curl);.
-
-At this point I had to make a choice as to whether invest my limited
-time-energy resource to fixing the bug or to compile the new version
-available. After searching the archives I found a very similar or the same bug
-reported from version 7.12x on. Daniel did inform me that he thought that this
-bug had been fixed with the latest version. So I proceeded to compile the
-latest SSL version where I faced other challenges.
-
-In order to make this process unremarkable for others using the same
-environment I decided to document the process so that others will find it
-routine. It would be a shame if newbies could not implement this excellent
-package for their use.
-
-I would like to thank the many others in this forum and in the DevCpp forum
-for their help. Without your help I may either have given up or it would have
-taken me many times longer to achieve success.
-
-The Cookbook Approach
----------------------
-
-This discussion will be confined to a SSL static library compilation and
-installation. Limited mention and comments will be inserted where appropriate
-to help with non-SSL, dynamic libraries and executables.
-
-
-   Using Makefile from DevCpp to compile Libcurl libraries
-
-Preamble
---------
-
-Using the latest version release - curl-7.14.0.tar.gz. Curl source code is
-platform independent. This simply means that the source code can be compiled
-for any Operating System (Linux/Unix Windows etc. and variations of thereof).
-
-The first thing to note is that inside curl-7.14.0 you will find two folders
-lib and src. Both contain Makefile.m32 (required for win mingw library or exe
-compilation) files which are different. The main difference between these two
-folders and the makefiles is that the src folder contents are used to compile
-an executable file(curl.exe) while the lib folder contents are used to compile
-a static (libcurl.a) and dynamic (libcurl.dll & libcurldll.a) file that can be
-used to compile libcurl with your own source code so that one can use and
-access all libcurl functions.
-
-Before we start please make sure that DevCpp is installed properly. In
-particular make sure you have no spaces in the name of any of the directories
-and subdirectories where DevCpp is installed. Failure to comply with the
-install instructions may produce erratic behaviour in DevCpp. For further info
-check the following sites
-
-http://aditsu.freeunixhost.com/dev-cpp-faq.html
-https://sourceforge.net/p/dev-cpp/discussion/48211/thread/2a85ea46
-
-As I have mentioned before I will confine this to the SSL Library compilations
-but the process is very similar for compilation of the executable - curl.exe;
-just substitute the src folder makefile in its stead.
-
-First use a text processor Notepad, or your own favourite text processor. To
-engage your favourite text processor, select Makefile.m32 click once with your
-mouse on file icon; icon turns blue, press the shift key and right-click on
-mouse, menu appears select "Open with", select your favourite text processor.
-
-Next read the contents of Makefile.m32. It includes instructions on its use.
-
-Method I - DOS Command Line
----------------------------
-
-Note - The only reason I have included this method is that Method II which is
-the preferred method for compiling does not allow for the setting of option
-switches (e.g. SSL = 1 or SSL =0). At least that's what they tell me at the
-Dev-Cpp forum.
-
-1 - Make a copy of (D:\Dev-Cpp\bin) bin folder and name it "bin Original"
-place it in the Dev-Cpp installed directory (D:\Dev-Cpp\ for this example)
-
-2 - Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
-version into the bin folder above (D:\Dev-Cpp\bin). The reason being is that
-the make.exe file resides in this folder. Make.exe will use - Makefile.m32,
-Makefile.inc, and the source code included in the lib folder to compile the
-source code. There is a PATH issue with make.exe that remains unresolved at
-least for me. Unless the entire source code to be compiled is placed entirely
-within the directory of make.exe an error message will be generated - "file
-xxxx.yyy not available".
-
-3- Go to Dev-Cpp\bin and double click on make .exe. You will see a DOS window
-quickly pop up and close very quickly. Not to worry! Please do not skip this
-step.
-
-4- Click on the start button\Programs\MS-DOS Prompt.Once the DOS Window is up
-Type the disk drive letter (e.g. E: ) engage the enter button. The path should
-automatically take you to the directory of the make.exe file.
-
-5- To compile the source code simply type at the DOS prompt make -f
-Makefile.m32 as per instructions contained in the Makefile.m32 file (use any
-text processor to read instructions). I don't believe that this makefile
-allows for the option of non SSL. Ignore any warnings.
-
-6- Collect and make copies of libcurl.a, libcurl.dll, libcurldll.a and any *.o
-compilations you might need in another directory outside of the bin directory
-as you will need this files shortly to set up libcurl for use with
-Dev-cpp. For most apps *.o is not required. Later on we will show what to do
-with these files.
-
-7- You are finished but before closing we need to do cleanup - erase the bin
-folder and rename the "bin Original" folder created in step 1 to bin.
-
-Note to compile a curl executable the process is probably similar but instead
-of using the LIB folder contents use the SRC folder contents and Makefiles in
-curl-7.14.0.tar.gz. File directories relative placements must be respected for
-compiling to take place successfully. This may not be possible with the PATH
-problem that make.exe experiences. If anyone has solved this PATH issue and
-please make sure it actually works on Win 9x/2000/XP before letting me
-know. Then please let me or Daniel in on the solution so that it can be
-included with these instructions. Thanks.
-
-or
-
-Method II - Dev-Cpp GUI
------------------------
-
-1- Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
-version into any folder outside of (Dev-Cpp\bin).
-
-2- Drop the File/New/click on Project.
-
-3- New Project Dialogue box appears. Double click on the Static Library.
-
-4- Create Project Dialogue box appears. Select the LIB folder location to
-place and locate your Project File Name. Placing the Project File Name
-elsewhere may cause problems (PATH issue problem again).
-
-5- Drop down the Project/Project Options. Project Options Dialogue box
-appears.
-
-6- Select the Makefile tab in the Project Options Dialogue Box. Check Box -
-Use Custom Makefile. Click on the Folder icon at the extreme right of the
-Check Box. Select Makefile.m32 in the folder wherever you have placed the
-contents of the LIB Folder. Press OK and close the Dialogue Box.
-
-7- Drop the Menu Project/Click on Add to Project. Open File Dialogue Box
-appears.  The Dialogue Box should open in the folder wherever you have placed
-the contents of the LIB Folder. If not go there.
-
-8- Select Crtl-A to select all files in the LIB folder. Click on open to add
-files and close box. Wait till all files are added. This may take 30 seconds
-or longer.
-
-9- Drop the Menu Execute/Click on Compile.
-
-10- That's it.
-
-
-   The following steps must be completed if Curl is to work properly
-   =================================================================
-
-LIB folder inclusions (*.a placement)
--------------------------------------
-
-1- Refer to Method I - DOS Command Line point # 6 Take libcurl.a, libcurldll.a
-and install it in the directory C( or whichever drive Dev is installed)
-:\Dev-Cpp\lib.
-
-
-Include Folder
---------------
-
-1- Create a new folder by the name of curl (do not change the name curl to
-some other name as it will cause major issues) in the directory
-C:\Dev-Cpp\include.
-
-2- Copy the entire contents of the curl folder of curl-7.14.0.tar.gz or zip
- version into the newly created curl directory - C:\Dev-Cpp\include\curl.
-
-Links To Include And Lib Folder
--------------------------------
-
-1- Drop the Menu - Tools\Compiler Options\Directories\Libraries. Make sure
-that C( or whichever drive Dev is installed):\DEV-CPP\lib is included.
-
-2- Next select the Menu - Tools\Compiler Options\Directories\C Includes. Make
-sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are included.
-
-3- Next select the Menu - Tools\Compiler Options\Directories\C++
-Includes. Make sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are
-included.
-
-Linker Links
-------------
-
-1- Drop the Menu - Tools\Compiler Options\Directories\Compiler.
-
-2- Make sure that the box "Add these commands to the linker command line" is
-checked.
-
-3- Include in the white space immediately below the box referred in 2 -lcurl
--lws2_32.
-
-SSL Files
----------
-
-1- Get the latest openSSL (as of time of this writing)
-openssl-0.9.7e-win32-bin.zip for the minimalist package of the openssl-0.9.7e
-binaries ported to MS Windows 95/98/NT/XP using the MingW32/GCC-3.1
-development environment. The file may be downloaded at
-https://curl.haxx.se/download/.
-
-2- Open the above zip file. You will find two files - SDL.dll,
-SDL_mixer.dll. Install them in the directory C:\WINDOWS\SYSTEM32 for Win 9x
-users and c:\winnt\system32 for NT-family users.
-
-Multithreading Files
---------------------
-
-To be completed
-
-#define
--------
-
-1- Make sure that your program includes the following - #define CURL_STATICLIB
-must be declared FIRST before any other define functions may be
-added. Otherwise you may experience link errors.
-
-2- Don't forget to include   #include "curl/curl.h".
-
-e.g.
-    #define CURL_STATICLIB
-#include <windows.h>
-    #include "curl/curl.h"
-#include <fstream>
-#include <iostream>
-#include <vector>
-etc...
-
-
-Static or Dynamic Library
--------------------------
-
-The above steps apply for the use by a static library. Should you choose to
-use a dynamic library you will be required to perform these additional steps.
-
-1- Refer to Method I - DOS Command Line point # 6. Install libcurl.dll in the
-directory C:\WINDOWS\SYSTEM32 for Win 9x users and c:\winnt\system32 for
-NT-family users.
-
-2- Refer to Linker Links point 3 - Replace -lcurl with -lcurldll.
-
-Voila you're done.
-
-The non-SSL static Library build may not be possible to use at least as of the
-time of this writing - v7.14. Check reference emails - Phillipe and I found it
-impossible to fully compile as certain files were missing for linking. No big
-loss as SSL is a major plus.
-
-Hope this Helps
-
-Tom
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
new file mode 100644
index 0000000..610add6
--- /dev/null
+++ b/docs/INSTALL.md
@@ -0,0 +1,513 @@
+# how to install curl and libcurl
+
+## Installing Binary Packages
+
+Lots of people download binary distributions of curl and libcurl. This
+document does not describe how to install curl or libcurl using such a binary
+package. This document describes how to compile, build and install curl and
+libcurl from source code.
+
+## Building from git
+
+If you get your code off a git repository instead of a release tarball, see
+the `GIT-INFO` file in the root directory for specific instructions on how to
+proceed.
+
+# Unix
+
+A normal Unix installation is made in three or four steps (after you've
+unpacked the source archive):
+
+    ./configure
+    make
+    make test (optional)
+    make install
+
+You probably need to be root when doing the last command.
+
+Get a full listing of all available configure options by invoking it like:
+
+    ./configure --help
+
+If you want to install curl in a different file hierarchy than `/usr/local`,
+specify that when running configure:
+
+    ./configure --prefix=/path/to/curl/tree
+
+If you have write permission in that directory, you can do 'make install'
+without being root. An example of this would be to make a local install in
+your own home directory:
+
+    ./configure --prefix=$HOME
+    make
+    make install
+
+The configure script always tries to find a working SSL library unless
+explicitly told not to. If you have OpenSSL installed in the default search
+path for your compiler/linker, you don't need to do anything special. If you
+have OpenSSL installed in /usr/local/ssl, you can run configure like:
+
+    ./configure --with-ssl
+
+If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL) and
+you have pkg-config installed, set the pkg-config path first, like this:
+
+    env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl
+
+Without pkg-config installed, use this:
+
+   ./configure --with-ssl=/opt/OpenSSL
+
+If you insist on forcing a build without SSL support, even though you may
+have OpenSSL installed in your system, you can run configure like this:
+
+   ./configure --without-ssl
+
+If you have OpenSSL installed, but with the libraries in one place and the
+header files somewhere else, you have to set the LDFLAGS and CPPFLAGS
+environment variables prior to running configure.  Something like this should
+work:
+
+    CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" ./configure
+
+If you have shared SSL libs installed in a directory where your run-time
+linker doesn't find them (which usually causes configure failures), you can
+provide the -R option to ld on some operating systems to set a hard-coded
+path to the run-time linker:
+
+    LDFLAGS=-R/usr/local/ssl/lib ./configure --with-ssl
+
+## More Options
+
+To force a static library compile, disable the shared library creation by
+running configure like:
+
+    ./configure --disable-shared
+
+To tell the configure script to skip searching for thread-safe functions, add
+an option like:
+
+    ./configure --disable-thread
+
+If you're a curl developer and use gcc, you might want to enable more debug
+options with the `--enable-debug` option.
+
+curl can be built to use a whole range of libraries to provide various useful
+services, and configure will try to auto-detect a decent default. But if you
+want to alter it, you can select how to deal with each individual library.
+
+## Select TLS backend
+
+The default OpenSSL configure check will also detect and use BoringSSL or
+libressl.
+
+ - GnuTLS: `--without-ssl --with-gnutls`.
+ - Cyassl: `--without-ssl --with-cyassl`
+ - NSS: `--without-ssl --with-nss`
+ - PolarSSL: `--without-ssl --with-polarssl`
+ - mbedTLS: `--without-ssl --with-mbedtls`
+ - axTLS: `--without-ssl --with-axtls`
+ - schannel: `--without-ssl --with-winssl`
+ - secure transport: `--with-winssl --with-darwinssl`
+
+# Windows
+
+## Building Windows DLLs and C run-time (CRT) linkage issues
+
+ As a general rule, building a DLL with static CRT linkage is highly
+ discouraged, and intermixing CRTs in the same app is something to avoid at
+ any cost.
+
+ Reading and comprehending Microsoft Knowledge Base articles KB94248 and
+ KB140584 is a must for any Windows developer. Especially important is full
+ understanding if you are not going to follow the advice given above.
+
+ - [How To Use the C Run-Time](https://support.microsoft.com/kb/94248/en-us)
+ - [How to link with the correct C Run-Time CRT library](https://support.microsoft.com/kb/140584/en-us)
+ - [Potential Errors Passing CRT Objects Across DLL Boundaries](https://msdn.microsoft.com/en-us/library/ms235460)
+
+If your app is misbehaving in some strange way, or it is suffering from
+memory corruption, before asking for further help, please try first to
+rebuild every single library your app uses as well as your app using the
+debug multithreaded dynamic C runtime.
+
+ If you get linkage errors read section 5.7 of the FAQ document.
+
+## MingW32
+
+Make sure that MinGW32's bin dir is in the search path, for example:
+
+    set PATH=c:\mingw32\bin;%PATH%
+
+then run `mingw32-make mingw32` in the root dir. There are other
+make targets available to build libcurl with more features, use:
+
+ - `mingw32-make mingw32-zlib` to build with Zlib support;
+ - `mingw32-make mingw32-ssl-zlib` to build with SSL and Zlib enabled;
+ - `mingw32-make mingw32-ssh2-ssl-zlib` to build with SSH2, SSL, Zlib;
+ - `mingw32-make mingw32-ssh2-ssl-sspi-zlib` to build with SSH2, SSL, Zlib
+   and SSPI support.
+
+If you have any problems linking libraries or finding header files, be sure
+to verify that the provided "Makefile.m32" files use the proper paths, and
+adjust as necessary. It is also possible to override these paths with
+environment variables, for example:
+
+    set ZLIB_PATH=c:\zlib-1.2.8
+    set OPENSSL_PATH=c:\openssl-1.0.2c
+    set LIBSSH2_PATH=c:\libssh2-1.6.0
+
+It is also possible to build with other LDAP SDKs than MS LDAP; currently
+it is possible to build with native Win32 OpenLDAP, or with the Novell CLDAP
+SDK. If you want to use these you need to set these vars:
+
+    set LDAP_SDK=c:\openldap
+    set USE_LDAP_OPENLDAP=1
+
+or for using the Novell SDK:
+
+    set USE_LDAP_NOVELL=1
+
+If you want to enable LDAPS support then set LDAPS=1.
+
+## Cygwin
+
+Almost identical to the unix installation. Run the configure script in the
+curl source tree root with `sh configure`. Make sure you have the sh
+executable in /bin/ or you'll see the configure fail toward the end.
+
+Run `make`
+
+## Borland C++ compiler
+
+Ensure that your build environment is properly set up to use the compiler and
+associated tools. PATH environment variable must include the path to bin
+subdirectory of your compiler installation, eg: `c:\Borland\BCC55\bin`
+
+It is advisable to set environment variable BCCDIR to the base path of the
+compiler installation.
+
+    set BCCDIR=c:\Borland\BCC55
+
+In order to build a plain vanilla version of curl and libcurl run the
+following command from curl's root directory:
+
+    make borland
+
+To build curl and libcurl with zlib and OpenSSL support set environment
+variables `ZLIB_PATH` and `OPENSSL_PATH` to the base subdirectories of the
+already built zlib and OpenSSL libraries and from curl's root directory run
+command:
+
+    make borland-ssl-zlib
+
+libcurl library will be built in 'lib' subdirectory while curl tool is built
+in 'src' subdirectory. In order to use libcurl library it is advisable to
+modify compiler's configuration file bcc32.cfg located in
+`c:\Borland\BCC55\bin` to reflect the location of libraries include paths for
+example the '-I' line could result in something like:
+
+    -I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32"
+
+bcc3.cfg `-L` line could also be modified to reflect the location of of
+libcurl library resulting for example:
+
+    -L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32"
+
+In order to build sample program `simple.c` from the docs\examples
+subdirectory run following command from mentioned subdirectory:
+
+    bcc32 simple.c libcurl.lib cw32mt.lib
+
+In order to build sample program simplessl.c an SSL enabled libcurl is
+required, as well as the OpenSSL libeay32.lib and ssleay32.lib libraries.
+
+## Disabling Specific Protocols in Windows builds
+
+The configure utility, unfortunately, is not available for the Windows
+environment, therefore, you cannot use the various disable-protocol options of
+the configure utility on this platform.
+
+However, you can use the following defines to disable specific
+protocols:
+
+ - `HTTP_ONLY`             disables all protocols except HTTP
+ - `CURL_DISABLE_FTP`      disables FTP
+ - `CURL_DISABLE_LDAP`     disables LDAP
+ - `CURL_DISABLE_TELNET`   disables TELNET
+ - `CURL_DISABLE_DICT`     disables DICT
+ - `CURL_DISABLE_FILE`     disables FILE
+ - `CURL_DISABLE_TFTP`     disables TFTP
+ - `CURL_DISABLE_HTTP`     disables HTTP
+ - `CURL_DISABLE_IMAP`     disables IMAP
+ - `CURL_DISABLE_POP3`     disables POP3
+ - `CURL_DISABLE_SMTP`     disables SMTP
+
+If you want to set any of these defines you have the following options:
+
+ - Modify lib/config-win32.h
+ - Modify lib/curl_setup.h
+ - Modify lib/Makefile.vc6
+ - Modify the "Preprocessor Definitions" in the libcurl project
+
+Note: The pre-processor settings can be found using the Visual Studio IDE
+under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
+Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
+versions.
+
+## Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds
+
+In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack it is
+necessary to make definition of preprocessor symbol USE_LWIPSOCK visible to
+libcurl and curl compilation processes. To set this definition you have the
+following alternatives:
+
+ - Modify lib/config-win32.h and src/config-win32.h
+ - Modify lib/Makefile.vc6
+ - Modify the "Preprocessor Definitions" in the libcurl project
+
+Note: The pre-processor settings can be found using the Visual Studio IDE
+under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
+Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
+versions.
+
+Once that libcurl has been built with BSD-style lwIP TCP/IP stack support, in
+order to use it with your program it is mandatory that your program includes
+lwIP header file `<lwip/opt.h>` (or another lwIP header that includes this)
+before including any libcurl header. Your program does not need the
+`USE_LWIPSOCK` preprocessor definition which is for libcurl internals only.
+
+Compilation has been verified with [lwIP
+1.4.0](http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip) and
+[contrib-1.4.0](http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip).
+
+This BSD-style lwIP TCP/IP stack support must be considered experimental given
+that it has been verified that lwIP 1.4.0 still needs some polish, and libcurl
+might yet need some additional adjustment, caveat emptor.
+
+## Important static libcurl usage note
+
+When building an application that uses the static libcurl library on Windows,
+you must add `-DCURL_STATICLIB` to your `CFLAGS`.  Otherwise the linker will
+look for dynamic import symbols.
+
+## Legacy Windows and SSL
+
+WinSSL (specifically SChannel from Windows SSPI), is the native SSL library in
+Windows. However, WinSSL in Windows <= XP is unable to connect to servers that
+no longer support the legacy handshakes and algorithms used by those
+versions. If you will be using curl in one of those earlier versions of
+Windows you should choose another SSL backend such as OpenSSL.
+
+# Apple iOS and Mac OS X
+
+On modern Apple operating systems, curl can be built to use Apple's SSL/TLS
+implementation, Secure Transport, instead of OpenSSL. To build with Secure
+Transport for SSL/TLS, use the configure option `--with-darwinssl`. (It is not
+necessary to use the option `--without-ssl`.) This feature requires iOS 5.0 or
+later, or OS X 10.5 ("Leopard") or later.
+
+When Secure Transport is in use, the curl options `--cacert` and `--capath`
+and their libcurl equivalents, will be ignored, because Secure Transport uses
+the certificates stored in the Keychain to evaluate whether or not to trust
+the server. This, of course, includes the root certificates that ship with the
+OS. The `--cert` and `--engine` options, and their libcurl equivalents, are
+currently unimplemented in curl with Secure Transport.
+
+For OS X users: In OS X 10.8 ("Mountain Lion"), Apple made a major overhaul to
+the Secure Transport API that, among other things, added support for the newer
+TLS 1.1 and 1.2 protocols. To get curl to support TLS 1.1 and 1.2, you must
+build curl on Mountain Lion or later, or by using the equivalent SDK. If you
+set the `MACOSX_DEPLOYMENT_TARGET` environmental variable to an earlier
+version of OS X prior to building curl, then curl will use the new Secure
+Transport API on Mountain Lion and later, and fall back on the older API when
+the same curl binary is executed on older cats. For example, running these
+commands in curl's directory in the shell will build the code such that it
+will run on cats as old as OS X 10.6 ("Snow Leopard") (using bash):
+
+    export MACOSX_DEPLOYMENT_TARGET="10.6"
+    ./configure --with-darwinssl
+    make
+
+# Cross compile
+
+Download and unpack the curl package.
+
+'cd' to the new directory. (e.g. `cd curl-7.12.3`)
+
+Set environment variables to point to the cross-compile toolchain and call
+configure with any options you need.  Be sure and specify the `--host` and
+`--build` parameters at configuration time.  The following script is an
+example of cross-compiling for the IBM 405GP PowerPC processor using the
+toolchain from MonteVista for Hardhat Linux.
+
+    #! /bin/sh
+
+    export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
+    export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
+    export AR=ppc_405-ar
+    export AS=ppc_405-as
+    export LD=ppc_405-ld
+    export RANLIB=ppc_405-ranlib
+    export CC=ppc_405-gcc
+    export NM=ppc_405-nm
+
+    ./configure --target=powerpc-hardhat-linux
+        --host=powerpc-hardhat-linux
+        --build=i586-pc-linux-gnu
+        --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
+        --exec-prefix=/usr/local
+
+You may also need to provide a parameter like `--with-random=/dev/urandom` to
+configure as it cannot detect the presence of a random number generating
+device for a target system.  The `--prefix` parameter specifies where curl
+will be installed.  If `configure` completes successfully, do `make` and `make
+install` as usual.
+
+In some cases, you may be able to simplify the above commands to as little as:
+
+    ./configure --host=ARCH-OS
+
+# REDUCING SIZE
+
+There are a number of configure options that can be used to reduce the size of
+libcurl for embedded applications where binary size is an important factor.
+First, be sure to set the CFLAGS variable when configuring with any relevant
+compiler optimization flags to reduce the size of the binary.  For gcc, this
+would mean at minimum the -Os option, and potentially the `-march=X`,
+`-mdynamic-no-pic` and `-flto` options as well, e.g.
+
+    ./configure CFLAGS='-Os' LDFLAGS='-Wl,-Bsymbolic'...
+
+Note that newer compilers often produce smaller code than older versions
+due to improved optimization.
+
+Be sure to specify as many `--disable-` and `--without-` flags on the
+configure command-line as you can to disable all the libcurl features that you
+know your application is not going to need.  Besides specifying the
+`--disable-PROTOCOL` flags for all the types of URLs your application will not
+use, here are some other flags that can reduce the size of the library:
+
+ - `--disable-ares` (disables support for the C-ARES DNS library)
+ - `--disable-cookies` (disables support for HTTP cookies)
+ - `--disable-crypto-auth` (disables HTTP cryptographic authentication)
+ - `--disable-ipv6` (disables support for IPv6)
+ - `--disable-manual` (disables support for the built-in documentation)
+ - `--disable-proxy` (disables support for HTTP and SOCKS proxies)
+ - `--disable-unix-sockets` (disables support for UNIX sockets)
+ - `--disable-verbose` (eliminates debugging strings and error code strings)
+ - `--disable-versioned-symbols` (disables support for versioned symbols)
+ - `--enable-hidden-symbols` (eliminates unneeded symbols in the shared library)
+ - `--without-libidn` (disables support for the libidn DNS library)
+ - `--without-librtmp` (disables support for RTMP)
+ - `--without-ssl` (disables support for SSL/TLS)
+ - `--without-zlib` (disables support for on-the-fly decompression)
+
+The GNU compiler and linker have a number of options that can reduce the
+size of the libcurl dynamic libraries on some platforms even further.
+Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
+configure command-line, e.g.
+
+    CFLAGS="-Os -ffunction-sections -fdata-sections
+            -fno-unwind-tables -fno-asynchronous-unwind-tables -flto"
+    LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
+
+Be sure also to strip debugging symbols from your binaries after compiling
+using 'strip' (or the appropriate variant if cross-compiling).  If space is
+really tight, you may be able to remove some unneeded sections of the shared
+library using the -R option to objcopy (e.g. the .comment section).
+
+Using these techniques it is possible to create a basic HTTP-only shared
+libcurl library for i386 Linux platforms that is only 113 KiB in size, and an
+FTP-only library that is 113 KiB in size (as of libcurl version 7.50.3, using
+gcc 5.4.0).
+
+You may find that statically linking libcurl to your application will result
+in a lower total size than dynamically linking.
+
+Note that the curl test harness can detect the use of some, but not all, of
+the `--disable` statements suggested above. Use will cause tests relying on
+those features to fail.  The test harness can be manually forced to skip the
+relevant tests by specifying certain key words on the runtests.pl command
+line.  Following is a list of appropriate key words:
+
+ - `--disable-cookies`          !cookies
+ - `--disable-manual`           !--manual
+ - `--disable-proxy`            !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5
+
+# PORTS
+
+This is a probably incomplete list of known hardware and operating systems
+that curl has been compiled for. If you know a system curl compiles and
+runs on, that isn't listed, please let us know!
+
+  - Alpha DEC OSF 4
+  - Alpha Digital UNIX v3.2
+  - Alpha FreeBSD 4.1, 4.5
+  - Alpha Linux 2.2, 2.4
+  - Alpha NetBSD 1.5.2
+  - Alpha OpenBSD 3.0
+  - Alpha OpenVMS V7.1-1H2
+  - Alpha Tru64 v5.0 5.1
+  - AVR32 Linux
+  - ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
+  - ARM INTEGRITY
+  - ARM iOS
+  - Cell Linux
+  - Cell Cell OS
+  - HP-PA HP-UX 9.X 10.X 11.X
+  - HP-PA Linux
+  - HP3000 MPE/iX
+  - MicroBlaze uClinux
+  - MIPS IRIX 6.2, 6.5
+  - MIPS Linux
+  - OS/400
+  - Pocket PC/Win CE 3.0
+  - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
+  - PowerPC Darwin 1.0
+  - PowerPC INTEGRITY
+  - PowerPC Linux
+  - PowerPC Mac OS 9
+  - PowerPC Mac OS X
+  - SH4 Linux 2.6.X
+  - SH4 OS21
+  - SINIX-Z v5
+  - Sparc Linux
+  - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
+  - Sparc SunOS 4.1.X
+  - StrongARM (and other ARM) RISC OS 3.1, 4.02
+  - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
+  - StrongARM NetBSD 1.4.1
+  - Symbian OS (P.I.P.S.) 9.x
+  - TPF
+  - Ultrix 4.3a
+  - UNICOS 9.0
+  - i386 BeOS
+  - i386 DOS
+  - i386 eCos 1.3.1
+  - i386 Esix 4.1
+  - i386 FreeBSD
+  - i386 HURD
+  - i386 Haiku OS
+  - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
+  - i386 Mac OS X
+  - i386 MINIX 3.1
+  - i386 NetBSD
+  - i386 Novell NetWare
+  - i386 OS/2
+  - i386 OpenBSD
+  - i386 QNX 6
+  - i386 SCO unix
+  - i386 Solaris 2.7
+  - i386 Windows 95, 98, ME, NT, 2000, XP, 2003
+  - i486 ncr-sysv4.3.03 (NCR MP-RAS)
+  - ia64 Linux 2.3.99
+  - m68k AmigaOS 3
+  - m68k Linux
+  - m68k uClinux
+  - m68k OpenBSD
+  - m88k dg-dgux5.4R3.00
+  - s390 Linux
+  - x86_64 Linux
+  - XScale/PXA250 Linux 2.4
+  - Nios II uClinux
diff --git a/docs/INTERNALS b/docs/INTERNALS.md
similarity index 87%
rename from docs/INTERNALS
rename to docs/INTERNALS.md
index 565d9df..77b993e 100644
--- a/docs/INTERNALS
+++ b/docs/INTERNALS.md
@@ -1,5 +1,5 @@
-Table of Contents
-=================
+curl internals
+==============
 
  - [Intro](#intro)
  - [git](#git)
@@ -40,8 +40,8 @@
  - [Structs in libcurl](#structs)
 
 <a name="intro"></a>
-curl internals
-==============
+Intro
+=====
 
  This project is split in two. The library and the client. The client part
  uses the library, but the library is designed to allow other applications to
@@ -174,7 +174,7 @@
  rather small and easy-to-follow. All the ones prefixed with `curl_easy` are
  put in the lib/easy.c file.
 
- `curl_global_init_()` and `curl_global_cleanup()` should be called by the
+ `curl_global_init()` and `curl_global_cleanup()` should be called by the
  application to initialize and clean up global stuff in the library. As of
  today, it can handle the global SSL initing if SSL is enabled and it can init
  the socket layer on windows machines. libcurl itself has no "global" scope.
@@ -184,14 +184,14 @@
 
  [ `curl_easy_init()`][2] allocates an internal struct and makes some
  initializations.  The returned handle does not reveal internals. This is the
- 'Curl_easy' struct which works as an "anchor" struct for all `curl_easy`
+ `Curl_easy` struct which works as an "anchor" struct for all `curl_easy`
  functions. All connections performed will get connect-specific data allocated
  that should be used for things related to particular connections/requests.
 
  [`curl_easy_setopt()`][1] takes three arguments, where the option stuff must
  be passed in pairs: the parameter-ID and the parameter-value. The list of
  options is documented in the man page. This function mainly sets things in
- the 'Curl_easy' struct.
+ the `Curl_easy` struct.
 
  `curl_easy_perform()` is just a wrapper function that makes use of the multi
  API.  It basically calls `curl_multi_init()`, `curl_multi_add_handle()`,
@@ -218,7 +218,7 @@
    This function makes sure there's an allocated and initiated 'connectdata'
    struct that is used for this particular connection only (although there may
    be several requests performed on the same connect). A bunch of things are
-   inited/inherited from the Curl_easy struct.
+   inited/inherited from the `Curl_easy` struct.
 
 <a name="Curl_do"></a>
 Curl_do()
@@ -385,11 +385,11 @@
  The persistent connection support in libcurl requires some considerations on
  how to do things inside of the library.
 
- - The 'Curl_easy' struct returned in the [`curl_easy_init()`][2] call
+ - The `Curl_easy` struct returned in the [`curl_easy_init()`][2] call
    must never hold connection-oriented data. It is meant to hold the root data
    as well as all the options etc that the library-user may choose.
 
- - The 'Curl_easy' struct holds the "connection cache" (an array of
+ - The `Curl_easy` struct holds the "connection cache" (an array of
    pointers to 'connectdata' structs).
 
  - This enables the 'curl handle' to be reused on subsequent transfers.
@@ -485,7 +485,7 @@
  main() resides in `src/tool_main.c`.
 
  `src/tool_hugehelp.c` is automatically generated by the mkhelp.pl perl script
- to display the complete "manual" and the src/tool_urlglob.c file holds the
+ to display the complete "manual" and the `src/tool_urlglob.c` file holds the
  functions used for the URL-"globbing" support. Globbing in the sense that the
  {} and [] expansion stuff is there.
 
@@ -589,7 +589,7 @@
 `curl_off_t`
 ==========
 
- curl_off_t is a data type provided by the external libcurl include
+ `curl_off_t` is a data type provided by the external libcurl include
  headers. It is the type meant to be used for the [`curl_easy_setopt()`][1]
  options that end with LARGE. The type is 64bit large on most modern
  platforms.
@@ -607,10 +607,10 @@
 
 `curlx_strtoofft()`
 -------------------
-   A macro that converts a string containing a number to a curl_off_t number.
-   This might use the curlx_strtoll() function which is provided as source
+   A macro that converts a string containing a number to a `curl_off_t` number.
+   This might use the `curlx_strtoll()` function which is provided as source
    code in strtoofft.c. Note that the function is only provided if no
-   strtoll() (or equivalent) function exist on your platform. If curl_off_t
+   strtoll() (or equivalent) function exist on your platform. If `curl_off_t`
    is only a 32 bit number on your platform, this macro uses strtol().
 
 `curlx_tvnow()`
@@ -624,17 +624,17 @@
 
 `curlx_tvdiff_secs()`
 ---------------------
-   returns the same as curlx_tvdiff but with full usec resolution (as a
+   returns the same as `curlx_tvdiff` but with full usec resolution (as a
    double)
 
 Future
 ------
 
- Several functions will be removed from the public curl_ name space in a
- future libcurl release. They will then only become available as curlx_
+ Several functions will be removed from the public `curl_` name space in a
+ future libcurl release. They will then only become available as `curlx_`
  functions instead. To make the transition easier, we already today provide
- these functions with the curlx_ prefix to allow sources to get built properly
- with the new function names. The functions this concerns are:
+ these functions with the `curlx_` prefix to allow sources to get built
+ properly with the new function names. The functions this concerns are:
 
  - `curlx_getenv`
  - `curlx_strequal`
@@ -719,7 +719,7 @@
 
  this host has getaddrinfo() and family, and thus we use that. The host may
  not be able to resolve IPv6, but we don't really have to take that into
- account. Hosts that aren't IPv6-enabled have CURLRES_IPV4 defined.
+ account. Hosts that aren't IPv6-enabled have `CURLRES_IPV4` defined.
 
 ## `CURLRES_ARES`
 
@@ -750,7 +750,7 @@
  - hostip6.c     - IPv6 specific functions
 
  The hostip.h is the single united header file for all this. It defines the
- `CURLRES_*` defines based on the config*.h and curl_setup.h defines.
+ `CURLRES_*` defines based on the config*.h and `curl_setup.h` defines.
 
 <a name="memoryleak"></a>
 Track Down Memory Leaks
@@ -858,7 +858,7 @@
 
 ## Curl_easy
 
-  The Curl_easy struct is the one returned to the outside in the external API
+  The `Curl_easy` struct is the one returned to the outside in the external API
   as a "CURL *". This is usually known as an easy handle in API documentations
   and examples.
 
@@ -866,27 +866,27 @@
   'connectdata' struct. When a transfer is about to be made, libcurl will
   either create a new connection or re-use an existing one. The particular
   connectdata that is used by this handle is pointed out by
-  Curl_easy->easy_conn.
+  `Curl_easy->easy_conn`.
 
   Data and information that regard this particular single transfer is put in
   the SingleRequest sub-struct.
 
-  When the Curl_easy struct is added to a multi handle, as it must be in order
-  to do any transfer, the ->multi member will point to the `Curl_multi` struct
-  it belongs to. The ->prev and ->next members will then be used by the multi
-  code to keep a linked list of Curl_easy structs that are added to that same
-  multi handle. libcurl always uses multi so ->multi *will* point to a
-  `Curl_multi` when a transfer is in progress.
+  When the `Curl_easy` struct is added to a multi handle, as it must be in
+  order to do any transfer, the ->multi member will point to the `Curl_multi`
+  struct it belongs to. The ->prev and ->next members will then be used by the
+  multi code to keep a linked list of `Curl_easy` structs that are added to
+  that same multi handle. libcurl always uses multi so ->multi *will* point to
+  a `Curl_multi` when a transfer is in progress.
 
-  ->mstate is the multi state of this particular Curl_easy. When
+  ->mstate is the multi state of this particular `Curl_easy`. When
   `multi_runsingle()` is called, it will act on this handle according to which
   state it is in. The mstate is also what tells which sockets to return for a
-  specific Curl_easy when [`curl_multi_fdset()`][12] is called etc.
+  specific `Curl_easy` when [`curl_multi_fdset()`][12] is called etc.
 
   The libcurl source code generally use the name 'data' for the variable that
-  points to the Curl_easy.
+  points to the `Curl_easy`.
 
-  When doing multiplexed HTTP/2 transfers, each Curl_easy is associated with
+  When doing multiplexed HTTP/2 transfers, each `Curl_easy` is associated with
   an individual stream, sharing the same connectdata struct. Multiplexing
   makes it even more important to keep things associated with the right thing!
 
@@ -901,21 +901,21 @@
   the connection can't be kept alive, the connection will be closed after use
   and then this struct can be removed from the cache and freed.
 
-  Thus, the same Curl_easy can be used multiple times and each time select
+  Thus, the same `Curl_easy` can be used multiple times and each time select
   another connectdata struct to use for the connection. Keep this in mind, as
   it is then important to consider if options or choices are based on the
-  connection or the Curl_easy.
+  connection or the `Curl_easy`.
 
   Functions in libcurl will assume that connectdata->data points to the
-  Curl_easy that uses this connection (for the moment).
+  `Curl_easy` that uses this connection (for the moment).
 
   As a special complexity, some protocols supported by libcurl require a
   special disconnect procedure that is more than just shutting down the
   socket. It can involve sending one or more commands to the server before
   doing so. Since connections are kept in the connection cache after use, the
-  original Curl_easy may no longer be around when the time comes to shut down
+  original `Curl_easy` may no longer be around when the time comes to shut down
   a particular connection. For this purpose, libcurl holds a special dummy
-  `closure_handle` Curl_easy in the `Curl_multi` struct to use when needed.
+  `closure_handle` `Curl_easy` in the `Curl_multi` struct to use when needed.
 
   FTP uses two TCP connections for a typical transfer but it keeps both in
   this single struct and thus can be considered a single connection for most
@@ -929,36 +929,37 @@
   Internally, the easy interface is implemented as a wrapper around multi
   interface functions. This makes everything multi interface.
 
-  `Curl_multi` is the multi handle struct exposed as "CURLM *" in external APIs.
+  `Curl_multi` is the multi handle struct exposed as "CURLM *" in external
+  APIs.
 
-  This struct holds a list of Curl_easy structs that have been added to this
+  This struct holds a list of `Curl_easy` structs that have been added to this
   handle with [`curl_multi_add_handle()`][13]. The start of the list is
-  ->easyp and ->num_easy is a counter of added Curl_easys.
+  `->easyp` and `->num_easy` is a counter of added `Curl_easy`s.
 
-  ->msglist is a linked list of messages to send back when
+  `->msglist` is a linked list of messages to send back when
   [`curl_multi_info_read()`][14] is called. Basically a node is added to that
-  list when an individual Curl_easy's transfer has completed.
+  list when an individual `Curl_easy`'s transfer has completed.
 
-  ->hostcache points to the name cache. It is a hash table for looking up name
-  to IP. The nodes have a limited life time in there and this cache is meant
-  to reduce the time for when the same name is wanted within a short period of
-  time.
+  `->hostcache` points to the name cache. It is a hash table for looking up
+  name to IP. The nodes have a limited life time in there and this cache is
+  meant to reduce the time for when the same name is wanted within a short
+  period of time.
 
-  ->timetree points to a tree of Curl_easys, sorted by the remaining time
-  until it should be checked - normally some sort of timeout. Each Curl_easy
+  `->timetree` points to a tree of `Curl_easy`s, sorted by the remaining time
+  until it should be checked - normally some sort of timeout. Each `Curl_easy`
   has one node in the tree.
 
-  ->sockhash is a hash table to allow fast lookups of socket descriptor to
-  which Curl_easy that uses that descriptor. This is necessary for the
+  `->sockhash` is a hash table to allow fast lookups of socket descriptor to
+  which `Curl_easy` that uses that descriptor. This is necessary for the
   `multi_socket` API.
 
-  ->conn_cache points to the connection cache. It keeps track of all
+  `->conn_cache` points to the connection cache. It keeps track of all
   connections that are kept after use. The cache has a maximum size.
 
-  ->closure_handle is described in the 'connectdata' section.
+  `->closure_handle` is described in the 'connectdata' section.
 
   The libcurl source code generally use the name 'multi' for the variable that
-  points to the Curl_multi struct.
+  points to the `Curl_multi` struct.
 
 ## Curl_handler
 
@@ -971,41 +972,41 @@
   from a single array which is scanned through when a URL is given to libcurl
   to work with.
 
-  ->scheme is the URL scheme name, usually spelled out in uppercase. That's
-  "HTTP" or "FTP" etc. SSL versions of the protcol need its own `Curl_handler`
+  `->scheme` is the URL scheme name, usually spelled out in uppercase. That's
+  "HTTP" or "FTP" etc. SSL versions of the protocol need its own `Curl_handler`
   setup so HTTPS separate from HTTP.
 
-  ->setup_connection is called to allow the protocol code to allocate protocol
-  specific data that then gets associated with that Curl_easy for the rest of
-  this transfer. It gets freed again at the end of the transfer. It will be
-  called before the 'connectdata' for the transfer has been selected/created.
-  Most protocols will allocate its private 'struct [PROTOCOL]' here and assign
-  Curl_easy->req.protop to point to it.
+  `->setup_connection` is called to allow the protocol code to allocate
+  protocol specific data that then gets associated with that `Curl_easy` for
+  the rest of this transfer. It gets freed again at the end of the transfer.
+  It will be called before the 'connectdata' for the transfer has been
+  selected/created. Most protocols will allocate its private
+  'struct [PROTOCOL]' here and assign `Curl_easy->req.protop` to point to it.
 
-  ->connect_it allows a protocol to do some specific actions after the TCP
+  `->connect_it` allows a protocol to do some specific actions after the TCP
   connect is done, that can still be considered part of the connection phase.
 
-  Some protocols will alter the connectdata->recv[] and connectdata->send[]
-  function pointers in this function.
+  Some protocols will alter the `connectdata->recv[]` and
+  `connectdata->send[]` function pointers in this function.
 
-  ->connecting is similarly a function that keeps getting called as long as the
-  protocol considers itself still in the connecting phase.
+  `->connecting` is similarly a function that keeps getting called as long as
+  the protocol considers itself still in the connecting phase.
 
-  ->do_it is the function called to issue the transfer request. What we call
+  `->do_it` is the function called to issue the transfer request. What we call
   the DO action internally. If the DO is not enough and things need to be kept
-  getting done for the entire DO sequence to complete, ->doing is then usually
-  also provided. Each protocol that needs to do multiple commands or similar
-  for do/doing need to implement their own state machines (see SCP, SFTP,
-  FTP). Some protocols (only FTP and only due to historical reasons) has a
-  separate piece of the DO state called `DO_MORE`.
+  getting done for the entire DO sequence to complete, `->doing` is then
+  usually also provided. Each protocol that needs to do multiple commands or
+  similar for do/doing need to implement their own state machines (see SCP,
+  SFTP, FTP). Some protocols (only FTP and only due to historical reasons) has
+  a separate piece of the DO state called `DO_MORE`.
 
-  ->doing keeps getting called while issuing the transfer request command(s)
+  `->doing` keeps getting called while issuing the transfer request command(s)
 
-  ->done gets called when the transfer is complete and DONE. That's after the
+  `->done` gets called when the transfer is complete and DONE. That's after the
   main data has been transferred.
 
-  ->do_more gets called during the `DO_MORE` state. The FTP protocol uses this
-  state when setting up the second connection.
+  `->do_more` gets called during the `DO_MORE` state. The FTP protocol uses
+  this state when setting up the second connection.
 
   ->`proto_getsock`
   ->`doing_getsock`
@@ -1050,9 +1051,9 @@
 
 ## conncache
 
-  Is a hash table with connections for later re-use. Each Curl_easy has a
+  Is a hash table with connections for later re-use. Each `Curl_easy` has a
   pointer to its connection cache. Each multi handle sets up a connection
-  cache that all added Curl_easys share by default.
+  cache that all added `Curl_easy`s share by default.
 
 ## Curl_share
 
@@ -1061,10 +1062,10 @@
 
   The idea is that the struct can have a set of own versions of caches and
   pools and then by providing this struct in the `CURLOPT_SHARE` option, those
-  specific Curl_easys will use the caches/pools that this share handle
+  specific `Curl_easy`s will use the caches/pools that this share handle
   holds.
 
-  Then individual Curl_easy structs can be made to share specific things
+  Then individual `Curl_easy` structs can be made to share specific things
   that they otherwise wouldn't, such as cookies.
 
   The `Curl_share` struct can currently hold cookies, DNS cache and the SSL
@@ -1073,7 +1074,7 @@
 ## CookieInfo
 
   This is the main cookie struct. It holds all known cookies and related
-  information. Each Curl_easy has its own private CookieInfo even when
+  information. Each `Curl_easy` has its own private CookieInfo even when
   they are added to a multi handle. They can be made to share cookies by using
   the share API.
 
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index 578e015..84339ba 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -22,8 +22,8 @@
  1.8 DNS timing is wrong for HTTP redirects
  1.9 HTTP/2 frames while in the connection pool kill reuse
  1.10 Strips trailing dot from host name
- 1.11 transfer-encoding: chunked in HTTP/2
- 1.12 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
+ 1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
+ 1.12 HTTP/2 server push enabled when no pushes can be accepted
 
  2. TLS
  2.1 Hangs with PolarSSL
@@ -48,12 +48,17 @@
  5.3 libidn and old iconv
  5.4 AIX shared build with c-ares fails
  5.5 can't handle Unicode arguments in Windows
+ 5.6 cmake support gaps
+ 5.7 Visual Studio project gaps
+ 5.8 configure finding libs in wrong directory
+ 5.9 Utilize Requires.private directives in libcurl.pc
+ 5.10 Fix the gcc typechecks
 
  6. Authentication
  6.1 NTLM authentication and unicode
  6.2 MIT Kerberos for Windows build
  6.3 NTLM in system context uses wrong name
- 6.4 Negotiate needs a fake user name
+ 6.4 Negotiate and Kerberos V5 need a fake user name
 
  7. FTP
  7.1 FTP without or slow 220 response
@@ -63,6 +68,7 @@
  7.5 ASCII FTP
  7.6 FTP with NULs in URL parts
  7.7 FTP and empty path parts in the URL
+ 7.8 Premature transfer end but healthy control channel
 
  8. TELNET
  8.1 TELNET and time limtiations don't work
@@ -76,16 +82,16 @@
  10.2 SOCKS don't support timeouts
  10.3 FTPS over SOCKS
  10.4 active FTP over a SOCKS
- 10.5 SOCKS proxy not working via IPv6
 
  11. Internals
  11.1 Curl leaks .onion hostnames in DNS
  11.2 error buffer not set if connection to multiple addresses fails
+ 11.3 c-ares deviates from stock resolver on http://1346569778
 
  12. LDAP and OpenLDAP
  12.1 OpenLDAP hangs after returning results
 
- 13 TCP/IP
+ 13. TCP/IP
  13.1 --interface for ipv6 binds to unusable IP address
 
 
@@ -196,15 +202,7 @@
 
  See https://github.com/curl/curl/issues/716 for the discussion.
 
-1.11 transfer-encoding: chunked in HTTP/2
-
- For HTTP/1, when -H transfer-encoding:chunked option is given, curl encodes
- the request using chunked encoding. But when HTTP/2 is being used, the
- command wrongly sends a request with both content-length and
- transfer-encoding: chunked headers being set (and the request body is not
- chunked-encoded). See https://github.com/curl/curl/issues/662
-
-1.12 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
+1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
 
  I'm using libcurl to POST form data using a FILE* with the CURLFORM_STREAM
  option of curl_formadd(). I've noticed that if the connection drops at just
@@ -215,6 +213,13 @@
  seem to fix the issue or even get called. See
  https://github.com/curl/curl/issues/768
 
+1.12 HTTP/2 server push enabled when no pushes can be accepted
+
+ If the easy interface is used, we can't accept any server pushes so we should
+ switch off them already in the h2 settings as otherwise we risk wasting
+ bandwidth when the server tries to send pushes libcurl will never accept.
+
+ See https://github.com/curl/curl/issues/927
 
 2. TLS
 
@@ -341,6 +346,59 @@
   https://curl.haxx.se/bug/?i=345
   https://curl.haxx.se/bug/?i=731
 
+5.6 cmake support gaps
+
+ The cmake build setup lacks several features that the autoconf build
+ offers. This includes:
+
+  - symbol hiding when the shared library is built
+  - use of correct soname for the shared library build
+  - support for several TLS backends are missing
+  - the unit tests cause link failures in regular non-static builds
+  - no nghttp2 check
+
+5.7 Visual Studio project gaps
+
+ The Visual Studio projects lack some features that the autoconf and nmake
+ builds offer, such as the following:
+
+  - support for zlib and nghttp2
+  - use of static runtime libraries
+  - add the test suite components
+
+ In addition to this the following could be implemented:
+
+  - support for other development IDEs
+  - add PATH environment variables for third-party DLLs
+
+5.8 configure finding libs in wrong directory
+
+ When the configure script checks for third-party libraries, it adds those
+ directories to the LDFLAGS variable and then tries linking to see if it
+ works. When successful, the found directory is kept in the LDFLAGS variable
+ when the script continues to execute and do more tests and possibly check for
+ more libraries.
+
+ This can make subsequent checks for libraries wrongly detect another
+ installation in a directory that was previously added to LDFLAGS by another
+ library check!
+
+ A possibly better way to do these checks would be to keep the pristine LDFLAGS
+ even after successful checks and instead add those verified paths to a
+ separate variable that only after all library checks have been performed gets
+ appended to LDFLAGS.
+
+5.9 Utilize Requires.private directives in libcurl.pc
+
+ https://github.com/curl/curl/issues/864
+
+5.10 Fix the gcc typechecks
+
+ Issue #846 identifies a problem with the gcc-typechecks and how the types are
+ documented and checked for CURLINFO_CERTINFO but our attempts to fix the
+ issue were futile and needs more attention.
+
+ https://github.com/curl/curl/issues/846
 
 6. Authentication
 
@@ -367,13 +425,17 @@
  "system context" will make it use wrong(?) user name - at least when compared
  to what winhttp does. See https://curl.haxx.se/bug/view.cgi?id=535
 
-6.4 Negotiate needs a fake user name
+6.4 Negotiate and Kerberos V5 need a fake user name
 
- To get HTTP Negotiate (SPNEGO) authentication to work fine, you need to
- provide a (fake) user name (this concerns both curl and the lib) because the
- code wrongly only considers authentication if there's a user name provided.
- https://curl.haxx.se/bug/view.cgi?id=440 How?
- https://curl.haxx.se/mail/lib-2004-08/0182.html
+ In order to get Negotiate (SPNEGO) authentication to work in HTTP or Kerberos
+ V5 in the e-mail protocols, you need to  provide a (fake) user name (this
+ concerns both curl and the lib) because the code wrongly only considers
+ authentication if there's a user name provided by setting
+ conn->bits.user_passwd in url.c  https://curl.haxx.se/bug/view.cgi?id=440 How?
+ https://curl.haxx.se/mail/lib-2004-08/0182.html A possible solution is to
+ either modify this variable to be set or introduce a variable such as
+ new conn->bits.want_authentication which is set when any of the authentication
+ options are set.
 
 
 7. FTP
@@ -442,6 +504,17 @@
  the user wants to reach the root dir (this exception SHALL remain even when
  this bug is fixed).
 
+7.8 Premature transfer end but healthy control channel
+
+ When 'multi_done' is called before the transfer has been completed the normal
+ way, it is considered a "premature" transfer end. In this situation, libcurl
+ closes the connection assuming it doesn't know the state of the connection so
+ it can't be reused for subsequent requests.
+
+ With FTP however, this isn't necessarily true but there are a bunch of
+ situations (listed in the ftp_done code) where it *could* keep the connection
+ alive even in this situation - but the current code doesn't. Fixing this would
+ allow libcurl to reuse FTP connections better.
 
 8. TELNET
 
@@ -493,12 +566,6 @@
 
  libcurl doesn't support active FTP over a SOCKS proxy
 
-10.5 SOCKS proxy not working via IPv6
-
- `curl --proxy "socks://hostname-with-AAAA-record" example.com`
-
- curl: (7) Can't complete SOCKS4 connection to 1.2.3.4:109. (91),
- request rejected or failed.
 
 11. Internals
 
@@ -517,6 +584,18 @@
  CURLE_COULDNT_CONNECT. But the error buffer set by CURLOPT_ERRORBUFFER
  remains empty. Issue: https://github.com/curl/curl/issues/544
 
+11.3 c-ares deviates from stock resolver on http://1346569778
+
+ When using the socket resolvers, that URL becomes:
+
+     * Rebuilt URL to: http://1346569778/
+     *   Trying 80.67.6.50...
+
+ but with c-ares it instead says "Could not resolve: 1346569778 (Domain name
+ not found)"
+
+ See https://github.com/curl/curl/issues/893
+
 
 12. LDAP and OpenLDAP
 
@@ -540,7 +619,7 @@
      https://curl.haxx.se/mail/lib-2016-01/0101.html
 
 
-13 TCP/IP
+13. TCP/IP
 
 13.1 --interface for ipv6 binds to unusable IP address
 
diff --git a/docs/LICENSE-MIXING b/docs/LICENSE-MIXING
deleted file mode 100644
index d8e36ca..0000000
--- a/docs/LICENSE-MIXING
+++ /dev/null
@@ -1,130 +0,0 @@
-         License Mixing with apps, libcurl and Third Party Libraries
-         ===========================================================
-
-libcurl can be built to use a fair amount of various third party libraries,
-libraries that are written and provided by other parties that are distributed
-using their own licenses. Even libcurl itself contains code that may cause
-problems to some. This document attempts to describe what licenses libcurl and
-the other libraries use and what possible dilemmas linking and mixing them all
-can lead to for end users.
-
-I am not a lawyer and this is not legal advice!
-
-One common dilemma is that GPL[1]-licensed code is not allowed to be linked
-with code licensed under the Original BSD license (with the announcement
-clause). You may still build your own copies that use them all, but
-distributing them as binaries would be to violate the GPL license - unless you
-accompany your license with an exception[2]. This particular problem was
-addressed when the Modified BSD license was created, which does not have the
-announcement clause that collides with GPL.
-
-libcurl https://curl.haxx.se/docs/copyright.html
-
-        Uses an MIT (or Modified BSD)-style license that is as liberal as
-        possible.
-
-OpenSSL https://www.openssl.org/source/license.html
-
-        (May be used for SSL/TLS support) Uses an Original BSD-style license
-        with an announcement clause that makes it "incompatible" with GPL. You
-        are not allowed to ship binaries that link with OpenSSL that includes
-        GPL code (unless that specific GPL code includes an exception for
-        OpenSSL - a habit that is growing more and more common). If OpenSSL's
-        licensing is a problem for you, consider using another TLS library.
-
-GnuTLS  http://www.gnutls.org/
-
-        (May be used for SSL/TLS support) Uses the LGPL[3] license. If this is
-        a problem for you, consider using another TLS library. Also note that
-        GnuTLS itself depends on and uses other libs (libgcrypt and
-        libgpg-error) and they too are LGPL- or GPL-licensed.
-
-WolfSSL   https://www.wolfssl.com/
-
-        (May be used for SSL/TLS support) Uses the GPL[1] license or a
-        propietary license. If this is a problem for you, consider using
-        another TLS library.
-
-NSS     https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
-
-        (May be used for SSL/TLS support) Is covered by the MPL[4] license,
-        the GPL[1] license and the LGPL[3] license. You may choose to license
-        the code under MPL terms, GPL terms, or LGPL terms. These licenses
-        grant you different permissions and impose different obligations. You
-        should select the license that best meets your needs.
-
-axTLS   http://axtls.sourceforge.net/
-
-        (May be used for SSL/TLS support) Uses a Modified BSD-style license.
-
-mbedTLS https://tls.mbed.org/
-
-        (May be used for SSL/TLS support) Uses the GPL[1] license or a
-        propietary license. If this is a problem for you, consider using
-        another TLS library.
-
-BoringSSL https://boringssl.googlesource.com/
-
-        (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
-        license as that.
-
-libressl http://www.libressl.org/
-
-        (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
-        license as that.
-
-c-ares  https://daniel.haxx.se/projects/c-ares/license.html
-
-        (Used for asynchronous name resolves) Uses an MIT license that is very
-        liberal and imposes no restrictions on any other library or part you
-        may link with.
-
-zlib    http://www.zlib.net/zlib_license.html
-
-        (Used for compressed Transfer-Encoding support) Uses an MIT-style
-        license that shouldn't collide with any other library.
-
-MIT Kerberos http://web.mit.edu/kerberos/www/dist/
-
-        (May be used for GSS support) MIT licensed, that shouldn't collide
-        with any other parts.
-
-Heimdal http://www.h5l.org
-
-        (May be used for GSS support) Heimdal is Original BSD licensed with
-        the announcement clause.
-
-GNU GSS https://www.gnu.org/software/gss/
-
-        (May be used for GSS support) GNU GSS is GPL licensed. Note that you
-        may not distribute binary curl packages that uses this if you build
-        curl to also link and use any Original BSD licensed libraries!
-
-libidn  http://josefsson.org/libidn/
-
-        (Used for IDNA support) Uses the GNU Lesser General Public
-        License [3]. LGPL is a variation of GPL with slightly less aggressive
-        "copyleft". This license requires more requirements to be met when
-        distributing binaries, see the license for details. Also note that if
-        you distribute a binary that includes this library, you must also
-        include the full LGPL license text. Please properly point out what
-        parts of the distributed package that the license addresses.
-
-OpenLDAP http://www.openldap.org/software/release/license.html
-
-        (Used for LDAP support) Uses a Modified BSD-style license. Since
-        libcurl uses OpenLDAP as a shared library only, I have not heard of
-        anyone that ships OpenLDAP linked with libcurl in an app.
-
-libssh2 https://www.libssh2.org/
-
-        (Used for scp and sftp support) libssh2 uses a Modified BSD-style
-        license.
-
-[1] = GPL - GNU General Public License: https://www.gnu.org/licenses/gpl.html
-[2] = https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
-      how to write such an exception to the GPL
-[3] = LGPL - GNU Lesser General Public License:
-      https://www.gnu.org/licenses/lgpl.html
-[4] = MPL - Mozilla Public License:
-      https://www.mozilla.org/MPL/
diff --git a/docs/LICENSE-MIXING.md b/docs/LICENSE-MIXING.md
new file mode 100644
index 0000000..5376bdb
--- /dev/null
+++ b/docs/LICENSE-MIXING.md
@@ -0,0 +1,127 @@
+License Mixing
+==============
+
+libcurl can be built to use a fair amount of various third party libraries,
+libraries that are written and provided by other parties that are distributed
+using their own licenses. Even libcurl itself contains code that may cause
+problems to some. This document attempts to describe what licenses libcurl and
+the other libraries use and what possible dilemmas linking and mixing them all
+can lead to for end users.
+
+I am not a lawyer and this is not legal advice!
+
+One common dilemma is that [GPL](https://www.gnu.org/licenses/gpl.html)
+licensed code is not allowed to be linked with code licensed under the
+[Original BSD license](https://spdx.org/licenses/BSD-4-Clause.html) (with the
+announcement clause). You may still build your own copies that use them all,
+but distributing them as binaries would be to violate the GPL license - unless
+you accompany your license with an
+[exception](https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs). This
+particular problem was addressed when the [Modified BSD
+license](https://opensource.org/licenses/BSD-3-Clause) was created, which does
+not have the announcement clause that collides with GPL.
+
+## libcurl
+
+ Uses an [MIT style license](https://curl.haxx.se/docs/copyright.html) that is
+ very liberal.
+
+## OpenSSL
+
+ (May be used for SSL/TLS support) Uses an Original BSD-style license with an
+ announcement clause that makes it "incompatible" with GPL. You are not
+ allowed to ship binaries that link with OpenSSL that includes GPL code
+ (unless that specific GPL code includes an exception for OpenSSL - a habit
+ that is growing more and more common). If OpenSSL's licensing is a problem
+ for you, consider using another TLS library.
+
+## GnuTLS
+
+ (May be used for SSL/TLS support) Uses the
+ [LGPL](https://www.gnu.org/licenses/lgpl.html) license. If this is a problem
+ for you, consider using another TLS library. Also note that GnuTLS itself
+ depends on and uses other libs (libgcrypt and libgpg-error) and they too are
+ LGPL- or GPL-licensed.
+
+## WolfSSL
+
+ (May be used for SSL/TLS support) Uses the GPL license or a proprietary
+ license. If this is a problem for you, consider using another TLS library.
+
+## NSS
+
+ (May be used for SSL/TLS support) Is covered by the
+ [MPL](https://www.mozilla.org/MPL/) license, the GPL license and the LGPL
+ license. You may choose to license the code under MPL terms, GPL terms, or
+ LGPL terms. These licenses grant you different permissions and impose
+ different obligations. You should select the license that best meets your
+ needs.
+
+## axTLS
+
+ (May be used for SSL/TLS support) Uses a Modified BSD-style license.
+
+## mbedTLS
+
+ (May be used for SSL/TLS support) Uses the [Apache 2.0
+ license](https://opensource.org/licenses/Apache-2.0) or the GPL license.
+ You may choose to license the code under Apache 2.0 terms or GPL terms.
+ These licenses grant you different permissions and impose different
+ obligations. You should select the license that best meets your needs.
+
+## BoringSSL
+
+ (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
+ license as that.
+
+## libressl
+
+ (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
+ license as that.
+
+## c-ares
+
+ (Used for asynchronous name resolves) Uses an MIT license that is very
+ liberal and imposes no restrictions on any other library or part you may link
+ with.
+
+## zlib
+
+ (Used for compressed Transfer-Encoding support) Uses an MIT-style license
+ that shouldn't collide with any other library.
+
+## MIT Kerberos
+
+ (May be used for GSS support) MIT licensed, that shouldn't collide with any
+ other parts.
+
+## Heimdal
+
+ (May be used for GSS support) Heimdal is Original BSD licensed with the
+ announcement clause.
+
+## GNU GSS
+
+ (May be used for GSS support) GNU GSS is GPL licensed. Note that you may not
+ distribute binary curl packages that uses this if you build curl to also link
+ and use any Original BSD licensed libraries!
+
+## libidn
+
+ (Used for IDNA support) Uses the GNU Lesser General Public License [3]. LGPL
+ is a variation of GPL with slightly less aggressive "copyleft". This license
+ requires more requirements to be met when distributing binaries, see the
+ license for details. Also note that if you distribute a binary that includes
+ this library, you must also include the full LGPL license text. Please
+ properly point out what parts of the distributed package that the license
+ addresses.
+
+## OpenLDAP
+
+ (Used for LDAP support) Uses a Modified BSD-style license. Since libcurl uses
+ OpenLDAP as a shared library only, I have not heard of anyone that ships
+ OpenLDAP linked with libcurl in an app.
+
+## libssh2
+
+ (Used for scp and sftp support) libssh2 uses a Modified BSD-style license.
diff --git a/docs/MAIL-ETIQUETTE b/docs/MAIL-ETIQUETTE
index 7505800..4d439aa 100644
--- a/docs/MAIL-ETIQUETTE
+++ b/docs/MAIL-ETIQUETTE
@@ -48,7 +48,7 @@
   each particular group and subculture there will be differences in what is
   acceptable and what is considered good manners.
 
-  This document outlines what we in the cURL project considers to be good
+  This document outlines what we in the curl project considers to be good
   etiquette, and primarily this focus on how to behave on and how to use our
   mailing lists.
 
@@ -108,7 +108,7 @@
   off-list. The subject will be taken care of as good as possible to prevent
   repeated offenses, but responding on the list to such messages never lead to
   anything good and only puts the light even more on the offender: which was
-  the entire purpose of it getting to the list in the first place.
+  the entire purpose of it getting sent to the list in the first place.
 
   Don't feed the trolls!
 
@@ -119,7 +119,7 @@
   your email address and password and press the unsubscribe button.
 
   Also, this information is included in the headers of every mail that is sent
-  out to all curl related mailing lists and there's footer in each mail that
+  out to all curl related mailing lists and there's a footer in each mail that
   links to the "admin" page on which you can unsubscribe and change other
   options.
 
@@ -200,8 +200,7 @@
 
   This is why top posting is so bad:
 
-      A: Because it messes up the order in which people normally read
-         text.
+      A: Because it messes up the order in which people normally read text.
       Q: Why is top-posting such a bad thing?
       A: Top-posting.
       Q: What is the most annoying thing in e-mail?
diff --git a/docs/MANUAL b/docs/MANUAL
index 08fdb57..0ea3e61 100644
--- a/docs/MANUAL
+++ b/docs/MANUAL
@@ -817,12 +817,8 @@
   and offer ldap:// support.
 
   LDAP is a complex thing and writing an LDAP query is not an easy task. I do
-  advise you to dig up the syntax description for that elsewhere. Two places
-  that might suit you are:
-
-  Netscape's "Netscape Directory SDK 3.0 for C Programmer's Guide Chapter 10:
-  Working with LDAP URLs":
-  http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
+  advise you to dig up the syntax description for that elsewhere. One such
+  place might be:
 
   RFC 2255, "The LDAP URL Format" https://curl.haxx.se/rfc/rfc2255.txt
 
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 284e531..fd045d2 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -33,12 +33,12 @@
 
 CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
 
-EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS     \
- README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS      \
- KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL           \
- $(PDFPAGES) LICENSE-MIXING README.netware INSTALL.devcpp               \
- MAIL-ETIQUETTE HTTP-COOKIES.md SECURITY RELEASE-PROCEDURE SSL-PROBLEMS \
- HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md CODE_STYLE.md CHECKSRC.md
+EXTRA_DIST = MANUAL BUGS CONTRIBUTE.md FAQ FEATURES INTERNALS.md SSLCERTS.md  \
+ README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS KNOWN_BUGS \
+ BINDINGS.md $(man_MANS) HISTORY.md INSTALL INSTALL.md LICENSE-MIXING.md         \
+ README.netware MAIL-ETIQUETTE HTTP-COOKIES.md SECURITY.md RELEASE-PROCEDURE  \
+ SSL-PROBLEMS.md HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md CODE_STYLE.md         \
+ CHECKSRC.md
 
 MAN2HTML= roffit $< >$@
 
diff --git a/docs/RELEASE-PROCEDURE b/docs/RELEASE-PROCEDURE
index 479078f..1b57452 100644
--- a/docs/RELEASE-PROCEDURE
+++ b/docs/RELEASE-PROCEDURE
@@ -83,10 +83,10 @@
 Based on the description above, here are some planned release dates (at the
 time of this writing):
 
-- March 23, 2016 (version 7.48.0)
-- May 18, 2016
-- July 13, 2016
-- September 7, 2016
+- September 7, 2016 (version 7.50.2)
 - November 2, 2016
 - December 28, 2016
 - February 22, 2017
+- April 19, 2017
+- June 14, 2017
+- August 9, 2017
diff --git a/docs/SECURITY b/docs/SECURITY.md
similarity index 81%
rename from docs/SECURITY
rename to docs/SECURITY.md
index 3c07e0b..c88cc9c 100644
--- a/docs/SECURITY
+++ b/docs/SECURITY.md
@@ -1,9 +1,3 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
 curl security for developers
 ============================
 
@@ -81,9 +75,11 @@
   to the 'distros' mailing list to allow them to use the fix prior to the
   public announcement.
 
-- At the day of the next release, the private branch is merged into the master
-  branch and pushed. Once pushed, the information is accessible to the public
-  and the actual release should follow suit immediately afterwards.
+- No more than 48 hours before the release, the private branch is merged into
+  the master branch and pushed. Once pushed, the information is accessible to
+  the public and the actual release should follow suit immediately afterwards.
+  The time between the push and the release is used for final tests and
+  reviews.
 
 - The project team creates a release that includes the fix.
 
@@ -94,9 +90,19 @@
 - The security web page on the web site should get the new vulnerability
   mentioned.
 
+Pre-notification
+----------------
 
+If you think you are or should be eligible for a pre-notification about
+upcoming security announcements for curl, we urge OS distros and similar
+vendors to primarily join the distros@openwall list as that is one of the
+purposes of that list - and not just for curl of course.
 
-CURL-SECURITY (at haxx dot se)
+If you are not a distro or otherwise not suitable for distros@openwall and yet
+want pre-notifications from us, contact the curl security team with a detailed
+and clear explanation why this is the case.
+
+curl-security (at haxx dot se)
 ------------------------------
 
 Who is on this list? There are a couple of criteria you must meet, and then we
@@ -106,5 +112,5 @@
 of working. You must've been around for a good while and you should have no
 plans in vanishing in the near future.
 
-We do not make the list of partipants public mostly because it tends to vary
+We do not make the list of participants public mostly because it tends to vary
 somewhat over time and a list somewhere will only risk getting outdated.
diff --git a/docs/SSL-PROBLEMS b/docs/SSL-PROBLEMS.md
similarity index 94%
rename from docs/SSL-PROBLEMS
rename to docs/SSL-PROBLEMS.md
index e639871..91803e2 100644
--- a/docs/SSL-PROBLEMS
+++ b/docs/SSL-PROBLEMS.md
@@ -4,7 +4,7 @@
                             | (__| |_| |  _ <| |___
                              \___|\___/|_| \_\_____|
 
-SSL problems
+# SSL problems
 
   First, let's establish that we often refer to TLS and SSL interchangeably as
   SSL here. The current protocol is called TLS, it was called SSL a long time
@@ -14,19 +14,19 @@
   fail. This is a document that attempts to details the most common ones and
   how to mitigate them.
 
-CA certs
+## CA certs
 
   CA certs are used to digitally verify the server's certificate. You need a
   "ca bundle" for this. See lots of more details on this in the SSLCERTS
   document.
 
-CA bundle missing intermediate certificates
+## CA bundle missing intermediate certificates
 
   When using said CA bundle to verify a server cert, you will experience
   problems if your CA cert does not have the certificates for the
   intermediates in the whole trust chain.
 
-Protocol version
+## Protocol version
 
   Some broken servers fail to support the protocol negotiation properly that
   SSL servers are supposed to handle. This may cause the connection to fail
@@ -38,7 +38,7 @@
 
   All versions of SSL are considered insecure and should be avoided. Use TLS.
 
-Ciphers
+## Ciphers
 
   Clients give servers a list of ciphers to select from. If the list doesn't
   include any ciphers the server wants/can use, the connection handshake
@@ -61,7 +61,7 @@
 
   https://tools.ietf.org/html/draft-popov-tls-prohibiting-rc4-01
 
-Allow BEAST
+## Allow BEAST
 
   BEAST is the name of a TLS 1.0 attack that surfaced 2011. When adding means
   to mitigate this attack, it turned out that some broken servers out there in
@@ -72,7 +72,7 @@
   but on the other hand it allows curl to connect to that kind of strange
   servers.
 
-Disabling certificate revocation checks
+## Disabling certificate revocation checks
 
   Some SSL backends may do certificate revocation checks (CRL, OCSP, etc)
   depending on the OS or build configuration. The --ssl-no-revoke option was
diff --git a/docs/SSLCERTS b/docs/SSLCERTS.md
similarity index 100%
rename from docs/SSLCERTS
rename to docs/SSLCERTS.md
diff --git a/docs/THANKS b/docs/THANKS
index 0f1a94f..2ebbf47 100644
--- a/docs/THANKS
+++ b/docs/THANKS
@@ -20,6 +20,7 @@
 Ajit Dhumale
 Aki Koskinen
 Akos Pasztory
+Akshay Vernekar
 Alain Danteny
 Alan Pinstein
 Albert Chin-A-Young
@@ -28,6 +29,7 @@
 Alejandro Alvarez Ayllon
 Aleksandar Milivojevic
 Aleksey Tulinov
+Ales Novak
 Alessandro Ghedini
 Alessandro Vesely
 Alex Bligh
@@ -47,6 +49,7 @@
 Alexander Lazic
 Alexander Pepper
 Alexander Peslyak
+Alexander Sinditskiy
 Alexander Traud
 Alexander Zhuravlev
 Alexey Borzov
@@ -76,10 +79,12 @@
 Andreas Olsson
 Andreas Rieke
 Andreas Schuldei
+Andreas Streichardt
 Andreas Wurf
 Andrei Benea
 Andrei Cipu
 Andrei Kurushin
+Andrei Sedoi
 Andrej E Baranov
 Andrew Benham
 Andrew Biggs
@@ -212,7 +217,9 @@
 Chris Mumford
 Chris Smowton
 Chris Young
+Christian Fillion
 Christian Grothoff
+Christian Heimes
 Christian Hägele
 Christian Krause
 Christian Kurz
@@ -256,12 +263,14 @@
 Da-Yoon Chung
 Dag Ekengren
 Dagobert Michelsen
+Dambaev Alexander
 Damian Dixon
 Damien Adant
 Damien Vielpeau
 Dan Becker
 Dan C
 Dan Cristian
+Dan Donahue
 Dan Fandrich
 Dan Locks
 Dan Nelson
@@ -271,6 +280,7 @@
 Daniel Black
 Daniel Cater
 Daniel Egger
+Daniel Gustafsson
 Daniel Hwang
 Daniel Johnson
 Daniel Kahn Gillmor
@@ -286,6 +296,7 @@
 Daniel at touchtunes
 Darryl House
 Darshan Mody
+Darío Hereñú
 Dave Dribin
 Dave Halbakken
 Dave Hamilton
@@ -305,6 +316,7 @@
 David Hull
 David J Meyer
 David James
+David Kalnischkies
 David Kierznowski
 David Kimdon
 David Lang
@@ -450,6 +462,7 @@
 Gabriel Sjoberg
 Garrett Holmstrom
 Gary Maxwell
+Gaurav Malhotra
 Gautam Kachroo
 Gautam Mani
 Gavrie Philipson
@@ -489,6 +502,7 @@
 Greg Onufer
 Greg Pratt
 Greg Zavertnik
+Gregory Szorc
 Grigory Entin
 Guenole Bescon
 Guenter Knauf
@@ -509,6 +523,7 @@
 Hans-Jurgen May
 Hardeep Singh
 Haris Okanovic
+Harold Stuart
 Harshal Pradhan
 Hauke Duden
 He Qin
@@ -711,6 +726,7 @@
 Justin Fletcher
 Justin Karneges
 Justin Maggard
+János Fekete
 Jörg Mueller-Tolk
 Jörn Hartroth
 K. R. Walker
@@ -808,6 +824,7 @@
 Luke Dashjr
 Luo Jinghua
 Luong Dinh Dung
+Luật Nguyễn
 Lyndon Hill
 Maciej Karpiuk
 Maciej Puzio
@@ -823,7 +840,7 @@
 Marc Deslauriers
 Marc Doughty
 Marc Hesse
-Marc Hoersken
+Marc Hörsken
 Marc Kleine-Budde
 Marc Renault
 Marcel Raad
@@ -833,6 +850,7 @@
 Marcin Adamski
 Marcin Gryszkalis
 Marcin Konicki
+Marco Deckel
 Marco G. Salvagno
 Marco Maggi
 Marcus Sundberg
@@ -842,9 +860,11 @@
 Mark Butler
 Mark Davies
 Mark Eichin
+Mark Hamilton
 Mark Incley
 Mark Karpeles
 Mark Lentczner
+Mark Nottingham
 Mark Salisbury
 Mark Snelling
 Mark Tully
@@ -857,12 +877,13 @@
 Martijn Koster
 Martin C. Martin
 Martin Drasar
+Martin Frodl
 Martin Hager
 Martin Hedenfalk
 Martin Jansen
 Martin Lemke
 Martin Skinner
-Martin Storsjo
+Martin Storsjö
 Martin Vejnár
 Marty Kuhrt
 Maruko
@@ -936,6 +957,7 @@
 Mike Protts
 Mike Revi
 Miklos Nemeth
+Miloš Ljumović
 Miroslav Franc
 Miroslav Spousta
 Mitz Wark
@@ -990,6 +1012,7 @@
 Oliver Kuckertz
 Oliver Schindler
 Olivier Berger
+Olivier Brunel
 Orange Tsai
 Oren Souroujon
 Oren Tirosh
@@ -1018,6 +1041,7 @@
 Paul Donohue
 Paul Harrington
 Paul Howarth
+Paul Joyce
 Paul Marks
 Paul Marquis
 Paul Moore
@@ -1088,12 +1112,14 @@
 Rainer Canavan
 Rainer Jung
 Rainer Koenig
+Rainer Müller
 Rajesh Naganathan
 Rajkumar Mandal
 Ralf S. Engelschall
 Ralph Beckmann
 Ralph Mitchell
 Ramana Mokkapati
+Randy Armstrong
 Randy McMurchy
 Ravi Pratap
 Ray Dassen
@@ -1103,6 +1129,7 @@
 Reinhard Max
 Reinout van Schouwen
 Remi Gacogne
+Remo E
 Renato Botelho
 Renaud Chaillat
 Renaud Duhaut
@@ -1131,6 +1158,7 @@
 Richard van den Berg
 Rick Jones
 Rick Richardson
+Rider Linden
 Rob Crittenden
 Rob Davies
 Rob Jones
@@ -1164,6 +1192,7 @@
 Romulo A. Ceccon
 Ron Parker
 Ron Zapp
+Ronnie Mose
 Rosimildo da Silva
 Roy Shan
 Rune Kleveland
@@ -1173,6 +1202,7 @@
 Ryan Chan
 Ryan Nelson
 Ryan Schmidt
+Ryan Scott
 Rémy Léone
 S. Moonesamy
 Salvador Dávila
@@ -1200,12 +1230,15 @@
 Scott Davis
 Scott McCreary
 Sean Boudreau
+Sebastian Mundry
 Sebastian Pohlschmidt
 Sebastian Rasmussen
 Senthil Raja Velu
+Sergei Kuzmin
 Sergei Nikulov
 Sergey Tatarincev
 Sergio Ballestrero
+Serj Kalichev
 Seshubabu Pasam
 Seth Mos
 Sh Diao
@@ -1223,6 +1256,7 @@
 Simon H.
 Simon Josefsson
 Simon Liu
+Simon Warta
 Song Ma
 Sonia Subramanian
 Spacen Jasset
@@ -1242,6 +1276,7 @@
 Stefan Ulrich
 Steinar H. Gunderson
 Stephan Bergmann
+Stephen Brokenshire
 Stephen Collyer
 Stephen Kick
 Stephen More
@@ -1312,6 +1347,7 @@
 Toby Peterson
 Todd A Ouska
 Todd Kulesza
+Todd Short
 Todd Vierling
 Tom Benoist
 Tom Donovan
@@ -1336,8 +1372,10 @@
 Tommy Tam
 Ton Voon
 Toni Moreno
+Tony Kelman
 Toon Verwaest
 Tor Arntsen
+Torben Dannhauer
 Torsten Foertsch
 Toshio Kuratomi
 Toshiyuki Maezawa
@@ -1353,6 +1391,7 @@
 Ulrich Doehner
 Ulrich Telle
 Ulrich Zadow
+Valentin David
 Venkat Akella
 Victor Snezhko
 Vijay Panghal
@@ -1420,12 +1459,15 @@
 eXeC64 on github
 jveazey on github
 kreshano on github
+lukaszgn on github
 marc-groundctl on github
 neex on github
 nk
+nopjmp on github
 silveja1 on github
 swalkaus at yahoo.com
 tommink[at]post.pl
 vanillajonathan on github
+wmsch on github
 Štefan Kremeň
 Никита Дорохин
diff --git a/docs/THANKS-filter b/docs/THANKS-filter
index defd605..1c6f398 100644
--- a/docs/THANKS-filter
+++ b/docs/THANKS-filter
@@ -68,3 +68,5 @@
 s/Joern Hartroth$/Jörn Hartroth/
 s/Hongli Lai (Phusion)$/Hongli Lai/
 s/github user 'kreshano'$/kreshano on github/
+s/Marc Hoersken$/Marc Hörsken/
+s/Martin Storsjo$/Martin Storsjö/
diff --git a/docs/TODO b/docs/TODO
index 30f2087..99c610f 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -6,7 +6,7 @@
 
                 Things that could be nice to do in the future
 
- Things to do in project cURL. Please tell us what you think, contribute and
+ Things to do in project curl. Please tell us what you think, contribute and
  send us patches that improve things!
 
  Be aware that these are things that we could do, or have once been considered
@@ -25,16 +25,19 @@
  1.7 Detect when called from within callbacks
  1.8 Allow SSL (HTTPS) to proxy
  1.9 Cache negative name resolves
- 1.10 Support IDNA2008
  1.11 minimize dependencies with dynamicly loaded modules
  1.12 have form functions use CURL handle argument
- 1.13 Add CURLOPT_MAIL_CLIENT option
  1.14 Typesafe curl_easy_setopt()
- 1.15 TCP Fast Open
+ 1.15 Monitor connections in the connection pool
  1.16 Try to URL encode given URL
  1.17 Add support for IRIs
  1.18 try next proxy if one doesn't work
  1.19 Timeout idle connections from the pool
+ 1.20 SRV and URI DNS records
+ 1.21 API for URL parsing/splitting
+ 1.23 Offer API to flush the connection pool
+ 1.24 TCP Fast Open for windows
+ 1.25 Remove the generated include file
 
  2. libcurl - multi interface
  2.1 More non-blocking
@@ -60,10 +63,12 @@
  5.1 Better persistency for HTTP 1.0
  5.2 support FF3 sqlite cookie files
  5.3 Rearrange request header order
- 5.4 SPDY
  5.5 auth= in URLs
  5.6 Refuse "downgrade" redirects
- 5.7 More compressions
+ 5.7 Brotli compression
+ 5.8 QUIC
+ 5.9 Add easy argument to formpost functions
+ 5.10 Leave secure cookies alone
 
  6. TELNET
  6.1 ditch stdin
@@ -74,6 +79,7 @@
  7. SMTP
  7.1 Pipelining
  7.2 Enhanced capability support
+ 7.3 Add CURLOPT_MAIL_CLIENT option
 
  8. POP3
  8.1 Pipelining
@@ -103,6 +109,11 @@
  13.6 Provide callback for cert verification
  13.7 improve configure --with-ssl
  13.8 Support DANE
+ 13.9 Support TLS v1.3
+ 13.10 Support SSLKEYLOGFILE
+ 13.11 Support intermediate & root pinning for PINNEDPUBLICKEY
+ 13.12 Support HSTS
+ 13.13 Support HPKP
 
  14. GnuTLS
  14.1 SSL engine stuff
@@ -118,47 +129,55 @@
  16.2 Add QOP support to GSSAPI authentication
  16.3 Support binary messages (i.e.: non-base64)
 
- 17. Command line tool
- 17.1 sync
- 17.2 glob posts
- 17.3 prevent file overwriting
- 17.4 simultaneous parallel transfers
- 17.5 provide formpost headers
- 17.6 warning when setting an option
- 17.7 warning when sending binary output to terminal
- 17.8 offer color-coded HTTP header output
- 17.9 Choose the name of file in braces for complex URLs
- 17.10 improve how curl works in a windows console window
- 17.11 -w output to stderr
- 17.12 keep running, read instructions from pipe/socket
- 17.13 support metalink in http headers
- 17.14 --fail without --location should treat 3xx as a failure
+ 17. SSH protocols
+ 17.1 Multiplexing
+ 17.2 SFTP performance
+ 17.3 Support better than MD5 hostkey hash
 
- 18. Build
- 18.1 roffit
+ 18. Command line tool
+ 18.1 sync
+ 18.2 glob posts
+ 18.3 prevent file overwriting
+ 18.4 simultaneous parallel transfers
+ 18.5 provide formpost headers
+ 18.6 warning when setting an option
+ 18.7 warning when sending binary output to terminal
+ 18.8 offer color-coded HTTP header output
+ 18.9 Choose the name of file in braces for complex URLs
+ 18.10 improve how curl works in a windows console window
+ 18.11 -w output to stderr
+ 18.12 keep running, read instructions from pipe/socket
+ 18.13 support metalink in http headers
+ 18.14 --fail without --location should treat 3xx as a failure
+ 18.15 Introduce --fail-fast to exit on first transfer fail
+ 18.16 --retry should resume
 
- 19. Test suite
- 19.1 SSL tunnel
- 19.2 nicer lacking perl message
- 19.3 more protocols supported
- 19.4 more platforms supported
- 19.5 Add support for concurrent connections
- 19.6 Use the RFC6265 test suite
+ 19. Build
+ 19.1 roffit
+ 19.2 Enable PIE and RELRO by default
 
- 20. Next SONAME bump
- 20.1 http-style HEAD output for FTP
- 20.2 combine error codes
- 20.3 extend CURLOPT_SOCKOPTFUNCTION prototype
+ 20. Test suite
+ 20.1 SSL tunnel
+ 20.2 nicer lacking perl message
+ 20.3 more protocols supported
+ 20.4 more platforms supported
+ 20.5 Add support for concurrent connections
+ 20.6 Use the RFC6265 test suite
 
- 21. Next major release
- 21.1 cleanup return codes
- 21.2 remove obsolete defines
- 21.3 size_t
- 21.4 remove several functions
- 21.5 remove CURLOPT_FAILONERROR
- 21.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
- 21.7 remove progress meter from libcurl
- 21.8 remove 'curl_httppost' from public
+ 21. Next SONAME bump
+ 21.1 http-style HEAD output for FTP
+ 21.2 combine error codes
+ 21.3 extend CURLOPT_SOCKOPTFUNCTION prototype
+
+ 22. Next major release
+ 22.1 cleanup return codes
+ 22.2 remove obsolete defines
+ 22.3 size_t
+ 22.4 remove several functions
+ 22.5 remove CURLOPT_FAILONERROR
+ 22.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
+ 22.7 remove progress meter from libcurl
+ 22.8 remove 'curl_httppost' from public
 
 ==============================================================================
 
@@ -227,23 +246,18 @@
 1.8 Allow SSL (HTTPS) to proxy
 
  To prevent local users from snooping on your traffic to the proxy. Supported
- by Chrome already:
+ by Firefox and Chrome already:
  https://www.chromium.org/developers/design-documents/secure-web-proxy
 
- ...and by Firefox soon:
- https://bugzilla.mozilla.org/show_bug.cgi?id=378637
+ See this stale work in progress branch:
+ https://github.com/curl/curl/tree/HTTPS-proxy based on this PR:
+ https://github.com/curl/curl/pull/305
 
 1.9 Cache negative name resolves
 
  A name resolve that has failed is likely to fail when made again within a
  short period of time. Currently we only cache positive responses.
 
-1.10 Support IDNA2008
-
- International Domain Names are supported in libcurl since years back, powered
- by libidn. libidn implements IDNA2003 which has been superseded by IDNA2008.
- libidn2 is an existing library offering support for IDNA2008.
-
 1.11 minimize dependencies with dynamicly loaded modules
 
  We can create a system with loadable modules/plug-ins, where these modules
@@ -264,16 +278,6 @@
  to use and less error-prone. Probably easiest by splitting it into several
  function calls.
 
-1.13 Add CURLOPT_MAIL_CLIENT option
-
- Rather than use the URL to specify the mail client string to present in the
- HELO and EHLO commands, libcurl should support a new CURLOPT specifically for
- specifying this data as the URL is non-standard and to be honest a bit of a
- hack ;-)
-
- Please see the following thread for more information:
- https://curl.haxx.se/mail/lib-2012-05/0178.html
-
 1.14 Typesafe curl_easy_setopt()
 
  One of the most common problems in libcurl using applications is the lack of
@@ -342,6 +346,56 @@
  in the pool), we should introduce a timeout so that connections that have
  been idle for N seconds get closed.
 
+1.20 SRV and URI DNS records
+
+ Offer support for resolving SRV and URI DNS records for libcurl to know which
+ server to connect to for various protocols (including HTTP!).
+
+1.21 API for URL parsing/splitting
+
+ libcurl has always parsed URLs internally and never exposed any API or
+ features to allow applications to do it. Still most or many applications
+ using libcurl need that ability. In polls to users, we've learned that many
+ libcurl users would like to see and use such an API.
+
+1.23 Offer API to flush the connection pool
+
+ Sometimes applications want to flush all the existing connections kept alive.
+ An API could allow a forced flush or just a forced loop that would properly
+ close all connections that have been closed by the server already.
+
+1.24 TCP Fast Open for windows
+
+ libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and
+ Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607
+ and we should add support for it.
+
+1.25 Remove the generated include file
+
+ When curl and libcurl are built, one of the public include files are
+ generated and is populated with a set of defines that are derevid from sizes
+ and constants for the particular target architecture that build is made. For
+ platforms that can select between 32 bit and 64 bit at build time, this
+ approach makes the libcurl build only create a set of public headers suitable
+ for one of the architectures and not both. If you build libcurl for such a
+ platform and you want to allow applications to get built using either 32/64
+ version, you must generate the libcurl headers once for each setup and you
+ must then add a replacement curl header that would itself select the correct
+ 32 or 64 bit specific header as necessary.
+
+ Your curl/curl.h alternative could then look like (replace with suitable CPP
+ variable to check):
+
+     #ifdef ARCH_32bit
+     #include <curl32/curl.h>
+     #else /* ARCH_64bit  */
+     #include <curl64/curl.h>
+     #endif
+
+ A fix would either (A) fix the 32/64 setup automatically or even better (B)
+ work away the architecture specific defines from the headers so that they can
+ be used for all architectures independently of what libcurl was built for.
+
 
 2. libcurl - multi interface
 
@@ -473,14 +527,6 @@
  headers use a default value so only headers that need to be moved have to be
  specified.
 
-5.4 SPDY
-
- Chrome and Firefox already support SPDY and lots of web services do. There's
- a library for us to use for this (spdylay) that has a similar API and the
- same author as nghttp2.
-
- spdylay: https://github.com/tatsuhiro-t/spdylay
-
 5.5 auth= in URLs
 
  Add the ability to specify the preferred authentication mechanism to use by
@@ -500,7 +546,7 @@
  Consider a way to tell curl to refuse to "downgrade" protocol with a redirect
  and/or possibly a bit that refuses redirect to change protocol completely.
 
-5.7 More compressions
+5.7 Brotli compression
 
  Compression algorithms that perform better than gzip are being considered for
  use and inclusion in existing browsers. For example 'brotli'. If servers
@@ -508,6 +554,30 @@
  of this. The algorithm: https://github.com/google/brotli The Firefox bug:
  https://bugzilla.mozilla.org/show_bug.cgi?id=366559
 
+5.8 QUIC
+
+ The standardization process of QUIC has been taken to the IETF and can be
+ followed on the [IETF QUIC Mailing
+ list](https://www.ietf.org/mailman/listinfo/quic). I'd like us to get on the
+ bandwagon. Ideally, this would be done with a separate library/project to
+ handle the binary/framing layer in a similar fashion to how HTTP/2 is
+ implemented. This, to allow other projects to benefit from the work and to
+ thus broaden the interest and chance of others to participate.
+
+5.9 Add easy argument to formpost functions
+
+ Make sure there's an easy handle passed in to `curl_formadd()`,
+ `curl_formget()` and `curl_formfree()` by adding replacement functions and
+ deprecating the old ones. Allows better error messages and is generally good
+ API hygiene.
+
+5.10 Leave secure cookies alone
+
+ Non-secure origins (HTTP sites) should not be allowed to set or modify
+ cookies with the 'secure' property:
+
+ https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01
+
 
 6. TELNET
 
@@ -544,6 +614,17 @@
  Add the ability, for an application that uses libcurl, to obtain the list of
  capabilities returned from the EHLO command.
 
+7.3 Add CURLOPT_MAIL_CLIENT option
+
+ Rather than use the URL to specify the mail client string to present in the
+ HELO and EHLO commands, libcurl should support a new CURLOPT specifically for
+ specifying this data as the URL is non-standard and to be honest a bit of a
+ hack ;-)
+
+ Please see the following thread for more information:
+ https://curl.haxx.se/mail/lib-2012-05/0178.html
+
+
 8. POP3
 
 8.1 Pipelining
@@ -658,6 +739,63 @@
  https://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the
  correct library to base this development on.
 
+ Björn Stenberg wrote a separate initial take on DANE that was never
+ completed.
+
+13.9 Support TLS v1.3
+
+ TLS version 1.3 is about to ship and is getting implemented by TLS libraries
+ as we speak. We should start to support the symbol and make sure all backends
+ handle it accordingly, then gradually add support as the TLS libraries add
+ the corresponding support. There may be a need to add some additional options
+ to allow libcurl to take advantage of the new features in 1.3.
+
+13.10 Support SSLKEYLOGFILE
+
+ When used, Firefox and Chrome dumps their master TLS keys to the file name
+ this environment variable specifies. This allows tools like for example
+ Wireshark to capture and decipher TLS traffic to/from those clients. libcurl
+ could be made to support this more widely (presumably this already works when
+ built with NSS). Peter Wu made a OpenSSL preload to make possible that can be
+ used as inspiration and guidance
+ https://git.lekensteyn.nl/peter/wireshark-notes/tree/src/sslkeylog.c
+
+13.11 Support intermediate & root pinning for PINNEDPUBLICKEY
+
+ CURLOPT_PINNEDPUBLICKEY does not consider the hashes of intermediate & root
+ certificates when comparing the pinned keys. Therefore it is not compatible
+ with "HTTP Public Key Pinning" as there also intermediate and root certificates
+ can be pinned. This is very useful as it prevents webadmins from "locking
+ themself out of their servers".
+
+ Adding this feature would make curls pinning 100% compatible to HPKP and allow
+ more flexible pinning.
+
+13.12 Support HSTS
+
+ "HTTP Strict Transport Security" is TOFU (trust on first use), time-based
+ features indicated by a HTTP header send by the webserver. It is widely used
+ in browsers and it's purpose is to prevent insecure HTTP connections after
+ a previous HTTPS connection. It protects against SSLStripping attacks.
+
+ Doc: https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
+ RFC 6797: https://tools.ietf.org/html/rfc6797
+
+13.13 Support HPKP
+
+ "HTTP Public Key Pinning" is TOFU (trust on first use), time-based
+ features indicated by a HTTP header send by the webserver. It's purpose is
+ to prevent Man-in-the-middle attacks by trusted CAs by allowing webadmins
+ to specify which CAs/certificates/public keys to trust when connection to
+ their websites.
+
+ It can be build based on PINNEDPUBLICKEY.
+
+ Wikipedia: https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning
+ OWASP: https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning
+ Doc: https://developer.mozilla.org/de/docs/Web/Security/Public_Key_Pinning
+ RFC: https://tools.ietf.org/html/draft-ietf-websec-key-pinning-21
+
 14. GnuTLS
 
 14.1 SSL engine stuff
@@ -722,9 +860,38 @@
 
   Mandatory to support LDAP SASL authentication.
 
-17. Command line tool
 
-17.1 sync
+17. SSH protocols
+
+17.1 Multiplexing
+
+ SSH is a perfectly fine multiplexed protocols which would allow libcurl to do
+ multiple parallel transfers from the same host using the same connection,
+ much in the same spirit as HTTP/2 does. libcurl however does not take
+ advantage of that ability but will instead always create a new connection for
+ new transfers even if an existing connection already exists to the host.
+
+ To fix this, libcurl would have to detect an existing connection and "attach"
+ the new transfer to the existing one.
+
+17.2 SFTP performance
+
+ libcurl's SFTP transfer performance is sub par and can be improved, mostly by
+ the approach mentioned in "1.6 Modified buffer size approach".
+
+17.3 Support better than MD5 hostkey hash
+
+ libcurl offers the CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 option for verifying the
+ server's key. MD5 is generally being deprecated so we should implement
+ support for stronger hashing algorithms. libssh2 itself is what provides this
+ underlying functionality and it supports at least SHA-1 as an alternative.
+ SHA-1 is also being deprecated these days so we should consider workign with
+ libssh2 to instead offer support for SHA-256 or similar.
+
+
+18. Command line tool
+
+18.1 sync
 
  "curl --sync http://example.com/feed[1-100].rss" or
  "curl --sync http://example.net/{index,calendar,history}.html"
@@ -733,20 +900,20 @@
  remote file is newer than the local file. A Last-Modified HTTP date header
  should also be used to set the mod date on the downloaded file.
 
-17.2 glob posts
+18.2 glob posts
 
  Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
  This is easily scripted though.
 
-17.3 prevent file overwriting
+18.3 prevent file overwriting
 
- Add an option that prevents cURL from overwriting existing local files. When
+ Add an option that prevents curl from overwriting existing local files. When
  used, and there already is an existing file with the target file name
  (either -O or -o), a number should be appended (and increased if already
  existing). So that index.html becomes first index.html.1 and then
  index.html.2 etc.
 
-17.4 simultaneous parallel transfers
+18.4 simultaneous parallel transfers
 
  The client could be told to use maximum N simultaneous parallel transfers and
  then just make sure that happens. It should of course not make more than one
@@ -756,7 +923,7 @@
  Using the multi interface would also allow properly using parallel transfers
  with HTTP/2 and supporting HTTP/2 server push from the command line.
 
-17.5 provide formpost headers
+18.5 provide formpost headers
 
  Extending the capabilities of the multipart formposting. How about leaving
  the ';type=foo' syntax as it is and adding an extra tag (headers) which
@@ -770,24 +937,24 @@
  which should overwrite the program reasonable defaults (plain/text,
  8bit...)
 
-17.6 warning when setting an option
+18.6 warning when setting an option
 
  Display a warning when libcurl returns an error when setting an option.
  This can be useful to tell when support for a particular feature hasn't been
  compiled into the library.
 
-17.7 warning when sending binary output to terminal
+18.7 warning when sending binary output to terminal
 
  Provide a way that prompts the user for confirmation before binary data is
  sent to the terminal, much in the style 'less' does it.
 
-17.8 offer color-coded HTTP header output
+18.8 offer color-coded HTTP header output
 
  By offering different color output on the header name and the header
  contents, they could be made more readable and thus help users working on
  HTTP services.
 
-17.9 Choose the name of file in braces for complex URLs
+18.9 Choose the name of file in braces for complex URLs
 
  When using braces to download a list of URLs and you use complicated names
  in the list of alternatives, it could be handy to allow curl to use other
@@ -799,13 +966,13 @@
 
  See https://github.com/curl/curl/issues/221
 
-17.10 improve how curl works in a windows console window
+18.10 improve how curl works in a windows console window
 
  If you pull the scrollbar when transferring with curl in a Windows console
  window, the transfer is interrupted and can get disconnected. This can
  probably be improved. See https://github.com/curl/curl/issues/322
 
-17.11 -w output to stderr
+18.11 -w output to stderr
 
  -w is quite useful, but not to those of us who use curl without -o or -O
  (such as for scripting through a higher level language). It would be nice to
@@ -813,7 +980,7 @@
  instead. Proposed name: --write-stderr. See
  https://github.com/curl/curl/issues/613
 
-17.12 keep running, read instructions from pipe/socket
+18.12 keep running, read instructions from pipe/socket
 
  Provide an option that makes curl not exit after the last URL (or even work
  without a given URL), and then make it read instructions passed on a pipe or
@@ -821,7 +988,7 @@
  invoke can talk to the still running instance and ask for transfers to get
  done, and thus maintain its connection pool, DNS cache and more.
 
-17.13 support metalink in http headers
+18.13 support metalink in http headers
 
  Curl has support for downloading a metalink xml file, processing it, and then
  downloading the target of the metalink. This is done via the --metalink option.
@@ -834,7 +1001,7 @@
  See also https://lists.gnu.org/archive/html/bug-wget/2015-06/msg00034.html for
  an implematation of this in wget.
 
-17.14 --fail without --location should treat 3xx as a failure
+18.14 --fail without --location should treat 3xx as a failure
 
  To allow a command line like this to detect a redirect and consider it a
  failure:
@@ -845,38 +1012,68 @@
  way to implement this is probably to add that new logic in the command line
  tool only and not in the underlying CURLOPT_FAILONERROR logic.
 
+18.15 Introduce --fail-fast to exit on first transfer fail
 
-18. Build
+ curl will transfer all URLs given on the command line one by one but only
+ returns the error code for the last transfer. Transfer failures on the first
+ ones will not be returned as error code etc to the shell. A --fail-fast
+ option would make curl exit and return an error for the first transfer that
+ fails.
 
-18.1 roffit
+18.16 --retry should resume
+
+ When --retry is used and curl actually retries transfer, it should use the
+ already transfered data and do a resumed transfer for the rest (when
+ possible) so that it doesn't have to transfer the same data again that was
+ already tranfered before the retry.
+
+ See https://github.com/curl/curl/issues/1084
+
+
+19. Build
+
+19.1 roffit
 
  Consider extending 'roffit' to produce decent ASCII output, and use that
  instead of (g)nroff when building src/tool_hugehelp.c
 
-19. Test suite
+19.2 Enable PIE and RELRO by default
 
-19.1 SSL tunnel
+ Especially when having programs that execute curl via the command line, PIE
+ renders the exploitation of memory corruption vulnerabilities a lot more
+ difficult. This can be attributed to the additional information leaks being
+ required to conduct a successful attack. RELRO, on the other hand, masks
+ different binary sections like the GOT as read-only and thus kills a handful
+ of techniques that come in handy when attackers are able to arbitrarily
+ overwrite memory. A few tests showed that enabling these features had close
+ to no impact, neither on the performance nor on the general functionality of
+ curl.
+
+
+20. Test suite
+
+20.1 SSL tunnel
 
  Make our own version of stunnel for simple port forwarding to enable HTTPS
  and FTP-SSL tests without the stunnel dependency, and it could allow us to
  provide test tools built with either OpenSSL or GnuTLS
 
-19.2 nicer lacking perl message
+20.2 nicer lacking perl message
 
  If perl wasn't found by the configure script, don't attempt to run the tests
  but explain something nice why it doesn't.
 
-19.3 more protocols supported
+20.3 more protocols supported
 
  Extend the test suite to include more protocols. The telnet could just do FTP
  or http operations (for which we have test servers).
 
-19.4 more platforms supported
+20.4 more platforms supported
 
  Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
  fork()s and it should become even more portable.
 
-19.5 Add support for concurrent connections
+20.5 Add support for concurrent connections
 
  Tests 836, 882 and 938 were designed to verify that separate connections aren't
  used when using different login credentials in protocols that shouldn't re-use
@@ -890,7 +1087,7 @@
  and thus the wait for connections loop is never entered to receive the second
  connection.
 
-19.6 Use the RFC6265 test suite
+20.6 Use the RFC6265 test suite
 
  A test suite made for HTTP cookies (RFC 6265) by Adam Barth is available at
  https://github.com/abarth/http-state/tree/master/tests
@@ -900,14 +1097,14 @@
  incorporated into our regular test suite.
 
 
-20. Next SONAME bump
+21. Next SONAME bump
 
-20.1 http-style HEAD output for FTP
+21.1 http-style HEAD output for FTP
 
  #undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
  from being output in NOBODY requests over FTP
 
-20.2 combine error codes
+21.2 combine error codes
 
  Combine some of the error codes to remove duplicates.  The original
  numbering should not be changed, and the old identifiers would be
@@ -932,29 +1129,29 @@
 
     CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
 
-20.3 extend CURLOPT_SOCKOPTFUNCTION prototype
+21.3 extend CURLOPT_SOCKOPTFUNCTION prototype
 
  The current prototype only provides 'purpose' that tells what the
  connection/socket is for, but not any protocol or similar. It makes it hard
  for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
  similar.
 
-21. Next major release
+22. Next major release
 
-21.1 cleanup return codes
+22.1 cleanup return codes
 
  curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
  CURLMcode. These should be changed to be the same.
 
-21.2 remove obsolete defines
+22.2 remove obsolete defines
 
  remove obsolete defines from curl/curl.h
 
-21.3 size_t
+22.3 size_t
 
  make several functions use size_t instead of int in their APIs
 
-21.4 remove several functions
+22.4 remove several functions
 
  remove the following functions from the public API:
 
@@ -975,18 +1172,18 @@
 
  curl_multi_socket_all
 
-21.5 remove CURLOPT_FAILONERROR
+22.5 remove CURLOPT_FAILONERROR
 
  Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
  internally. Let the app judge success or not for itself.
 
-21.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
+22.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
 
  Remove support for a global DNS cache. Anything global is silly, and we
  already offer the share interface for the same functionality but done
  "right".
 
-21.7 remove progress meter from libcurl
+22.7 remove progress meter from libcurl
 
  The internally provided progress meter output doesn't belong in the library.
  Basically no application wants it (apart from curl) but instead applications
@@ -996,7 +1193,7 @@
  variable types passed to it instead of doubles so that big files work
  correctly.
 
-21.8 remove 'curl_httppost' from public
+22.8 remove 'curl_httppost' from public
 
  curl_formadd() was made to fill in a public struct, but the fact that the
  struct is public is never really used by application for their own advantage
diff --git a/docs/TheArtOfHttpScripting b/docs/TheArtOfHttpScripting
index 047db80..0e81d1a 100644
--- a/docs/TheArtOfHttpScripting
+++ b/docs/TheArtOfHttpScripting
@@ -755,4 +755,4 @@
 
  14.2 Sites
 
- https://curl.haxx.se is the home of the cURL project
+ https://curl.haxx.se is the home of the curl project
diff --git a/docs/cmdline-opts/MANPAGE.md b/docs/cmdline-opts/MANPAGE.md
new file mode 100644
index 0000000..d9f550f
--- /dev/null
+++ b/docs/cmdline-opts/MANPAGE.md
@@ -0,0 +1,53 @@
+# curl man page generator
+
+This is the curl man page generator. It generates a single nroff man page
+output from the set of sources files in this directory.
+
+There is one source file for each supported command line option. The format is
+described below.
+
+## Option files
+
+Each command line option is described in a file named `<long name>.d`, where
+option name is written without any prefixing dashes. Like the file name for
+the -v, --verbose option is named `verbose.d`.
+
+Each file has a set of meta-data and a body of text.
+
+### Meta-data
+
+    Short: (single letter, without dash)
+    Long: (long form name, without dashes)
+    Arg: (the argument the option takes)
+    Magic: (description of "magic" options)
+    Tags: (space separated list)
+    Protocols: (space separated list for which protocols this option works)
+    Added: (version number in which this was added)
+    Mutexed: (space separated list of options this overrides)
+    Requires: (space separated list of features this option requires)
+    See-also: (space separated list of related options)
+    Redirect: (option name to use instead)
+    Help: (short text for the --help output for this option)
+    --- (end of meta-data)
+
+### Body
+
+The body of the description. Only refer to options with their long form option
+version, like --verbose. The output generator will replace such with the
+correct markup that shows both short and long version.
+
+## Header
+
+`page-header` is the nroff formatted file that will be output before the
+generated options output for the master man page.
+
+## Generate
+
+`./gen.pl mainpage`
+
+This command outputs a single huge nroff file, meant to become `curl.1`. The
+full curl man page.
+
+`./gen.pl listhelp`
+
+Generates a full `curl --help` output for all known command line options.
diff --git a/docs/cmdline-opts/anyauth.d b/docs/cmdline-opts/anyauth.d
new file mode 100644
index 0000000..c32d1ed
--- /dev/null
+++ b/docs/cmdline-opts/anyauth.d
@@ -0,0 +1,17 @@
+Long: anyauth
+Help: Pick any authentication method
+Protocols: HTTP
+See-also: proxy-anyauth basic digest
+---
+Tells curl to figure out authentication method by itself, and use the most
+secure one the remote site claims to support. This is done by first doing a
+request and checking the response-headers, thus possibly inducing an extra
+network round-trip. This is used instead of setting a specific authentication
+method, which you can do with --basic, --digest, --ntlm, and --negotiate.
+
+Using --anyauth is not recommended if you do uploads from stdin, since it may
+require data to be sent twice and then the client must be able to rewind. If
+the need should arise when uploading from stdin, the upload operation will
+fail.
+
+Used together with --user.
diff --git a/docs/cmdline-opts/append.d b/docs/cmdline-opts/append.d
new file mode 100644
index 0000000..f001b12
--- /dev/null
+++ b/docs/cmdline-opts/append.d
@@ -0,0 +1,8 @@
+Short: a
+Long: append
+Help: Append to target file when uploading
+Protocols: FTP SFTP
+---
+When used in an upload, this makes curl append to the target file instead of
+overwriting it. If the remote file doesn't exist, it will be created.  Note
+that this flag is ignored by some SFTP servers (including OpenSSH).
diff --git a/docs/cmdline-opts/basic.d b/docs/cmdline-opts/basic.d
new file mode 100644
index 0000000..09d42af
--- /dev/null
+++ b/docs/cmdline-opts/basic.d
@@ -0,0 +1,11 @@
+Long: basic
+Help: Use HTTP Basic Authentication
+See-also: proxy-basic
+Protocols: HTTP
+---
+Tells curl to use HTTP Basic authentication with the remote host. This is the
+default and this option is usually pointless, unless you use it to override a
+previously set option that sets a different authentication method (such as
+--ntlm, --digest, or --negotiate).
+
+Used together with --user.
diff --git a/docs/cmdline-opts/cacert.d b/docs/cmdline-opts/cacert.d
new file mode 100644
index 0000000..04e1139
--- /dev/null
+++ b/docs/cmdline-opts/cacert.d
@@ -0,0 +1,28 @@
+Long: cacert
+Arg: <CA certificate>
+Help: CA certificate to verify peer against
+Protocols: TLS
+---
+Tells curl to use the specified certificate file to verify the peer. The file
+may contain multiple CA certificates. The certificate(s) must be in PEM
+format. Normally curl is built to use a default file for this, so this option
+is typically used to alter that default file.
+
+curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is
+set, and uses the given path as a path to a CA cert bundle. This option
+overrides that variable.
+
+The windows version of curl will automatically look for a CA certs file named
+\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the
+Current Working Directory, or in any folder along your PATH.
+
+If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
+(libnsspem.so) needs to be available for this option to work properly.
+
+(iOS and macOS only) If curl is built against Secure Transport, then this
+option is supported for backward compatibility with other SSL engines, but it
+should not be set. If the option is not set, then curl will use the
+certificates in the system and user Keychain to verify the peer, which is the
+preferred method of verifying the peer's certificate chain.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/capath.d b/docs/cmdline-opts/capath.d
new file mode 100644
index 0000000..0763f7a
--- /dev/null
+++ b/docs/cmdline-opts/capath.d
@@ -0,0 +1,15 @@
+Long: capath
+Arg: <dir>
+Help: CA directory to verify peer against
+Protocols: TLS
+---
+Tells curl to use the specified certificate directory to verify the
+peer. Multiple paths can be provided by separating them with ":" (e.g.
+\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is
+built against OpenSSL, the directory must have been processed using the
+c_rehash utility supplied with OpenSSL. Using --capath can allow
+OpenSSL-powered curl to make SSL-connections much more efficiently than using
+--cacert if the --cacert file contains many CA certificates.
+
+If this option is set, the default capath value will be ignored, and if it is
+used several times, the last one will be used.
diff --git a/docs/cmdline-opts/cert-status.d b/docs/cmdline-opts/cert-status.d
new file mode 100644
index 0000000..f1aaa21
--- /dev/null
+++ b/docs/cmdline-opts/cert-status.d
@@ -0,0 +1,13 @@
+Long: cert-status
+Protocols: TLS
+Added: 7.41.0
+Help: Verify the status of the server certificate
+---
+Tells curl to verify the status of the server certificate by using the
+Certificate Status Request (aka. OCSP stapling) TLS extension.
+
+If this option is enabled and the server sends an invalid (e.g. expired)
+response, if the response suggests that the server certificate has been revoked,
+or no response at all is received, the verification fails.
+
+This is currently only implemented in the OpenSSL, GnuTLS and NSS backends.
diff --git a/docs/cmdline-opts/cert-type.d b/docs/cmdline-opts/cert-type.d
new file mode 100644
index 0000000..a04bdce
--- /dev/null
+++ b/docs/cmdline-opts/cert-type.d
@@ -0,0 +1,10 @@
+Long: cert-type
+Protocols: TLS
+Arg: <type>
+Help: Certificate file type (DER/PEM/ENG)
+See-also: cert key key-type
+---
+Tells curl what certificate type the provided certificate is in. PEM, DER and
+ENG are recognized types.  If not specified, PEM is assumed.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/cert.d b/docs/cmdline-opts/cert.d
new file mode 100644
index 0000000..0cd5d53
--- /dev/null
+++ b/docs/cmdline-opts/cert.d
@@ -0,0 +1,32 @@
+Short: E
+Long: cert
+Arg: <certificate[:password]>
+Help: Client certificate file and password
+Protocols: TLS
+See-also: cert-type key key-type
+---
+Tells curl to use the specified client certificate file when getting a file
+with HTTPS, FTPS or another SSL-based protocol. The certificate must be in
+PKCS#12 format if using Secure Transport, or PEM format if using any other
+engine.  If the optional password isn't specified, it will be queried for on
+the terminal. Note that this option assumes a \&"certificate" file that is the
+private key and the client certificate concatenated! See --cert and --key to
+specify them independently.
+
+If curl is built against the NSS SSL library then this option can tell
+curl the nickname of the certificate to use within the NSS database defined
+by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
+NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
+loaded. If you want to use a file from the current directory, please precede
+it with "./" prefix, in order to avoid confusion with a nickname.  If the
+nickname contains ":", it needs to be preceded by "\\" so that it is not
+recognized as password delimiter.  If the nickname contains "\\", it needs to
+be escaped as "\\\\" so that it is not recognized as an escape character.
+
+(iOS and macOS only) If curl is built against Secure Transport, then the
+certificate string can either be the name of a certificate/private key in the
+system or user keychain, or the path to a PKCS#12-encoded certificate and
+private key. If you want to use a file from the current directory, please
+precede it with "./" prefix, in order to avoid confusion with a nickname.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/ciphers.d b/docs/cmdline-opts/ciphers.d
new file mode 100644
index 0000000..b1e5ac9
--- /dev/null
+++ b/docs/cmdline-opts/ciphers.d
@@ -0,0 +1,16 @@
+Long: ciphers
+Arg: <list of ciphers>
+help: SSL ciphers to use
+Protocols: TLS
+---
+Specifies which ciphers to use in the connection. The list of ciphers must
+specify valid ciphers. Read up on SSL cipher list details on this URL:
+
+ https://www.openssl.org/docs/apps/ciphers.html
+
+NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of NSS
+ciphers is in the NSSCipherSuite entry at this URL:
+
+ https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/compressed.d b/docs/cmdline-opts/compressed.d
new file mode 100644
index 0000000..dc130c1
--- /dev/null
+++ b/docs/cmdline-opts/compressed.d
@@ -0,0 +1,7 @@
+Long: compressed
+Help: Request compressed response
+Protocols: HTTP
+---
+Request a compressed response using one of the algorithms curl supports, and
+save the uncompressed document.  If this option is used and the server sends
+an unsupported encoding, curl will report an error.
diff --git a/docs/cmdline-opts/config.d b/docs/cmdline-opts/config.d
new file mode 100644
index 0000000..4a32512
--- /dev/null
+++ b/docs/cmdline-opts/config.d
@@ -0,0 +1,60 @@
+Long: config
+Arg: <file>
+Help: Read config from a file
+Short: K
+---
+Specify which config file to read curl arguments from. The config file is a
+text file in which command line arguments can be written which then will be
+used as if they were written on the actual command line.
+
+Options and their parameters must be specified on the same config file line,
+separated by whitespace, colon, or the equals sign. Long option names can
+optionally be given in the config file without the initial double dashes and
+if so, the colon or equals characters can be used as separators. If the option
+is specified with one or two dashes, there can be no colon or equals character
+between the option and its parameter.
+
+If the parameter is to contain whitespace, the parameter must be enclosed
+within quotes. Within double quotes, the following escape sequences are
+available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash preceding any other
+letter is ignored. If the first column of a config line is a '#' character,
+the rest of the line will be treated as a comment. Only write one option per
+physical line in the config file.
+
+Specify the filename to --config as '-' to make curl read the file from stdin.
+
+Note that to be able to specify a URL in the config file, you need to specify
+it using the --url option, and not by simply writing the URL on its own
+line. So, it could look similar to this:
+
+url = "https://curl.haxx.se/docs/"
+
+When curl is invoked, it always (unless --disable is used) checks for a
+default config file and uses it if found. The default config file is checked
+for in the following places in this order:
+
+1) curl tries to find the "home dir": It first checks for the CURL_HOME and
+then the HOME environment variables. Failing that, it uses getpwuid() on
+Unix-like systems (which returns the home dir given the current user in your
+system). On Windows, it then checks for the APPDATA variable, or as a last
+resort the '%USERPROFILE%\\Application Data'.
+
+2) On windows, if there is no _curlrc file in the home dir, it checks for one
+in the same dir the curl executable is placed. On Unix-like systems, it will
+simply try to load .curlrc from the determined home dir.
+
+.nf
+# --- Example file ---
+# this is a comment
+url = "example.com"
+output = "curlhere.html"
+user-agent = "superagent/1.0"
+
+# and fetch another URL too
+url = "example.com/docs/manpage.html"
+-O
+referer = "http://nowhereatall.example.com/"
+# --- End of example file ---
+.fi
+
+This option can be used multiple times to load multiple config files.
diff --git a/docs/cmdline-opts/connect-timeout.d b/docs/cmdline-opts/connect-timeout.d
new file mode 100644
index 0000000..3a32d86
--- /dev/null
+++ b/docs/cmdline-opts/connect-timeout.d
@@ -0,0 +1,11 @@
+Long: connect-timeout
+Arg: <seconds>
+Help: Maximum time allowed for connection
+See-also: max-time
+---
+Maximum time in seconds that you allow curl's connection to take.  This only
+limits the connection phase, so if curl connects within the given period it
+will continue - if not it will exit.  Since version 7.32.0, this option
+accepts decimal values.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/connect-to.d b/docs/cmdline-opts/connect-to.d
new file mode 100644
index 0000000..3fa0568
--- /dev/null
+++ b/docs/cmdline-opts/connect-to.d
@@ -0,0 +1,18 @@
+Long: connect-to
+Arg: <HOST1:PORT1:HOST2:PORT2>
+Help: Connect to host
+Added: 7.49.0
+See-also: resolve header
+---
+
+For a request to the given HOST:PORT pair, connect to
+CONNECT-TO-HOST:CONNECT-TO-PORT instead.  This option is suitable to direct
+requests at a specific server, e.g. at a specific cluster node in a cluster of
+servers.  This option is only used to establish the network connection. It
+does NOT affect the hostname/port that is used for TLS/SSL (e.g. SNI,
+certificate verification) or for the application protocols.  "host" and "port"
+may be the empty string, meaning "any host/port".  "connect-to-host" and
+"connect-to-port" may also be the empty string, meaning "use the request's
+original host/port".
+
+This option can be used many times to add many connect rules.
diff --git a/docs/cmdline-opts/continue-at.d b/docs/cmdline-opts/continue-at.d
new file mode 100644
index 0000000..733f494
--- /dev/null
+++ b/docs/cmdline-opts/continue-at.d
@@ -0,0 +1,15 @@
+Short: C
+Long: continue-at
+Arg: <offset>
+Help: Resumed transfer offset
+See-also: range
+---
+Continue/Resume a previous file transfer at the given offset. The given offset
+is the exact number of bytes that will be skipped, counting from the beginning
+of the source file before it is transferred to the destination.  If used with
+uploads, the FTP server command SIZE will not be used by curl.
+
+Use "-C -" to tell curl to automatically find out where/how to resume the
+transfer. It then uses the given output/input files to figure that out.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/cookie-jar.d b/docs/cmdline-opts/cookie-jar.d
new file mode 100644
index 0000000..da79777
--- /dev/null
+++ b/docs/cmdline-opts/cookie-jar.d
@@ -0,0 +1,24 @@
+Short: c
+Long: cookie-jar
+Arg: <filename>
+Protocols: HTTP
+Help: Write cookies to <filename> after operation
+---
+Specify to which file you want curl to write all cookies after a completed
+operation. Curl writes all cookies from its in-memory cookie storage to the
+given file at the end of operations. If no cookies are known, no data will be
+written. The file will be written using the Netscape cookie file format. If
+you set the file name to a single dash, "-", the cookies will be written to
+stdout.
+
+This command line option will activate the cookie engine that makes curl
+record and use cookies. Another way to activate it is to use the --cookie
+option.
+
+If the cookie jar can't be created or written to, the whole curl operation
+won't fail or even report an error clearly. Using --verbose will get a warning
+displayed, but that is the only visible feedback you get about this possibly
+lethal situation.
+
+If this option is used several times, the last specified file name will be
+used.
diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d
new file mode 100644
index 0000000..383adda
--- /dev/null
+++ b/docs/cmdline-opts/cookie.d
@@ -0,0 +1,36 @@
+Short: b
+Long: cookie
+Arg: <data>
+Protocols: HTTP
+Help: Send cookies from string/file
+---
+Pass the data to the HTTP server in the Cookie header. It is supposedly
+the data previously received from the server in a "Set-Cookie:" line.  The
+data should be in the format "NAME1=VALUE1; NAME2=VALUE2".
+
+If no '=' symbol is used in the argument, it is instead treated as a filename
+to read previously stored cookie from. This option also activates the cookie
+engine which will make curl record incoming cookies, which may be handy if
+you're using this in combination with the --location option or do multiple URL
+transfers on the same invoke.
+
+The file format of the file to read cookies from should be plain HTTP headers
+(Set-Cookie style) or the Netscape/Mozilla cookie file format.
+
+The file specified with --cookie is only used as input. No cookies will be
+written to the file. To store cookies, use the --cookie-jar option.
+
+Exercise caution if you are using this option and multiple transfers may
+occur.  If you use the NAME1=VALUE1; format, or in a file use the Set-Cookie
+format and don't specify a domain, then the cookie is sent for any domain
+(even after redirects are followed) and cannot be modified by a server-set
+cookie. If the cookie engine is enabled and a server sets a cookie of the same
+name then both will be sent on a future transfer to that server, likely not
+what you intended.  To address these issues set a domain in Set-Cookie (doing
+that will include sub domains) or use the Netscape format.
+
+If this option is used several times, the last one will be used.
+
+Users very often want to both read cookies from a file and write updated
+cookies back to a file, so using both --cookie and --cookie-jar in the same
+command line is common.
diff --git a/docs/cmdline-opts/create-dirs.d b/docs/cmdline-opts/create-dirs.d
new file mode 100644
index 0000000..49e22e7
--- /dev/null
+++ b/docs/cmdline-opts/create-dirs.d
@@ -0,0 +1,9 @@
+Long: create-dirs
+Help: Create necessary local directory hierarchy
+---
+When used in conjunction with the --output option, curl will create the
+necessary local directory hierarchy as needed. This option creates the dirs
+mentioned with the --output option, nothing else. If the --output file name
+uses no dir or if the dirs it mentions already exist, no dir will be created.
+
+To create remote directories when using FTP or SFTP, try --ftp-create-dirs.
diff --git a/docs/cmdline-opts/crlf.d b/docs/cmdline-opts/crlf.d
new file mode 100644
index 0000000..f6694b6
--- /dev/null
+++ b/docs/cmdline-opts/crlf.d
@@ -0,0 +1,7 @@
+Long: crlf
+Help: Convert LF to CRLF in upload
+Protocols: FTP SMTP
+---
+Convert LF to CRLF in upload. Useful for MVS (OS/390).
+
+(SMTP added in 7.40.0)
diff --git a/docs/cmdline-opts/crlfile.d b/docs/cmdline-opts/crlfile.d
new file mode 100644
index 0000000..ae216b9
--- /dev/null
+++ b/docs/cmdline-opts/crlfile.d
@@ -0,0 +1,10 @@
+Long: crfile
+Arg: <file>
+Protocols: TLS
+Help: Get a CRL list in PEM format from the given file
+Added: 7.19.7
+---
+Provide a file using PEM format with a Certificate Revocation List that may
+specify peer certificates that are to be considered revoked.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/data-ascii.d b/docs/cmdline-opts/data-ascii.d
new file mode 100644
index 0000000..52f8031
--- /dev/null
+++ b/docs/cmdline-opts/data-ascii.d
@@ -0,0 +1,5 @@
+Long: data-ascii
+Arg: <data>
+Help: HTTP POST ASCII data
+Protocols: HTTP
+Redirect: data
diff --git a/docs/cmdline-opts/data-binary.d b/docs/cmdline-opts/data-binary.d
new file mode 100644
index 0000000..c6721c6
--- /dev/null
+++ b/docs/cmdline-opts/data-binary.d
@@ -0,0 +1,13 @@
+Long: data-binary
+Arg: <data>
+Help: HTTP POST binary data
+Protocols: HTTP
+---
+This posts data exactly as specified with no extra processing whatsoever.
+
+If you start the data with the letter @, the rest should be a filename.  Data
+is posted in a similar manner as --data does, except that newlines and
+carriage returns are preserved and conversions are never done.
+
+If this option is used several times, the ones following the first will append
+data as described in --data.
diff --git a/docs/cmdline-opts/data-raw.d b/docs/cmdline-opts/data-raw.d
new file mode 100644
index 0000000..7669b4a
--- /dev/null
+++ b/docs/cmdline-opts/data-raw.d
@@ -0,0 +1,9 @@
+Long: data-raw
+Arg: <data>
+Protocols: HTTP
+Help: HTTP POST data, '@' allowed
+Added: 7.43.0
+See-also: data
+---
+This posts data similarly to --data but without the special
+interpretation of the @ character.
diff --git a/docs/cmdline-opts/data-urlencode.d b/docs/cmdline-opts/data-urlencode.d
new file mode 100644
index 0000000..9873f33
--- /dev/null
+++ b/docs/cmdline-opts/data-urlencode.d
@@ -0,0 +1,33 @@
+Long: data-urlencode
+Arg: <data>
+Help: HTTP POST data url encoded
+Protocols: HTTP
+See-also: data data-raw
+Added: 7.18.0
+---
+This posts data, similar to the other --data options with the exception
+that this performs URL-encoding.
+
+To be CGI-compliant, the <data> part should begin with a \fIname\fP followed
+by a separator and a content specification. The <data> part can be passed to
+curl using one of the following syntaxes:
+.RS
+.IP "content"
+This will make curl URL-encode the content and pass that on. Just be careful
+so that the content doesn't contain any = or @ symbols, as that will then make
+the syntax match one of the other cases below!
+.IP "=content"
+This will make curl URL-encode the content and pass that on. The preceding =
+symbol is not included in the data.
+.IP "name=content"
+This will make curl URL-encode the content part and pass that on. Note that
+the name part is expected to be URL-encoded already.
+.IP "@filename"
+This will make curl load data from the given file (including any newlines),
+URL-encode that data and pass it on in the POST.
+.IP "name@filename"
+This will make curl load data from the given file (including any newlines),
+URL-encode that data and pass it on in the POST. The name part gets an equal
+sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the
+name is expected to be URL-encoded already.
+.RE
diff --git a/docs/cmdline-opts/data.d b/docs/cmdline-opts/data.d
new file mode 100644
index 0000000..353b41f
--- /dev/null
+++ b/docs/cmdline-opts/data.d
@@ -0,0 +1,30 @@
+Long: data
+Short: d
+Arg: <data>
+Help: HTTP POST data
+Protocols: HTTP
+See-also: data-binary data-urlencode data-raw
+Mutexed: form head upload
+---
+Sends the specified data in a POST request to the HTTP server, in the same way
+that a browser does when a user has filled in an HTML form and presses the
+submit button. This will cause curl to pass the data to the server using the
+content-type application/x-www-form-urlencoded.  Compare to --form.
+
+--data-raw is almost the same but does not have a special interpretation of
+the @ character. To post data purely binary, you should instead use the
+--data-binary option.  To URL-encode the value of a form field you may use
+--data-urlencode.
+
+If any of these options is used more than once on the same command line, the
+data pieces specified will be merged together with a separating
+&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post
+chunk that looks like \&'name=daniel&skill=lousy'.
+
+If you start the data with the letter @, the rest should be a file name to
+read the data from, or - if you want curl to read the data from
+stdin. Multiple files can also be specified. Posting data from a file named
+'foobar' would thus be done with \fI--data\fP @foobar. When --data is told to
+read from a file like that, carriage returns and newlines will be stripped
+out. If you don't want the @ character to have a special interpretation use
+--data-raw instead.
diff --git a/docs/cmdline-opts/delegation.d b/docs/cmdline-opts/delegation.d
new file mode 100644
index 0000000..138d823
--- /dev/null
+++ b/docs/cmdline-opts/delegation.d
@@ -0,0 +1,16 @@
+Long: delegation
+Arg: <LEVEL>
+Help: GSS-API delegation permission
+Protocols: GSS/kerberos
+---
+Set LEVEL to tell the server what it is allowed to delegate when it
+comes to user credentials.
+.RS
+.IP "none"
+Don't allow any delegation.
+.IP "policy"
+Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos
+service ticket, which is a matter of realm policy.
+.IP "always"
+Unconditionally allow the server to delegate.
+.RE
diff --git a/docs/cmdline-opts/digest.d b/docs/cmdline-opts/digest.d
new file mode 100644
index 0000000..5cdd925
--- /dev/null
+++ b/docs/cmdline-opts/digest.d
@@ -0,0 +1,11 @@
+Long: digest
+Help: Use HTTP Digest Authentication
+Protocols: HTTP
+Mutexed: basic ntlm negotiate
+See-also: user proxy-digest anyauth
+---
+Enables HTTP Digest authentication. This is an authentication scheme that
+prevents the password from being sent over the wire in clear text. Use this in
+combination with the normal --user option to set user name and password.
+
+If this option is used several times, only the first one is used.
diff --git a/docs/cmdline-opts/disable-eprt.d b/docs/cmdline-opts/disable-eprt.d
new file mode 100644
index 0000000..a1e53c0
--- /dev/null
+++ b/docs/cmdline-opts/disable-eprt.d
@@ -0,0 +1,19 @@
+Long: disable-eprt
+Help: Inhibit using EPRT or LPRT
+Protocols: FTP
+---
+Tell curl to disable the use of the EPRT and LPRT commands when doing active
+FTP transfers. Curl will normally always first attempt to use EPRT, then LPRT
+before using PORT, but with this option, it will use PORT right away. EPRT and
+LPRT are extensions to the original FTP protocol, and may not work on all
+servers, but they enable more functionality in a better way than the
+traditional PORT command.
+
+--eprt can be used to explicitly enable EPRT again and --no-eprt is an alias
+for --disable-eprt.
+
+If the server is accessed using IPv6, this option will have no effect as EPRT
+is necessary then.
+
+Disabling EPRT only changes the active behavior. If you want to switch to
+passive mode you need to not use --ftp-port or force it with --ftp-pasv.
diff --git a/docs/cmdline-opts/dns-interface.d b/docs/cmdline-opts/dns-interface.d
new file mode 100644
index 0000000..45e5af2
--- /dev/null
+++ b/docs/cmdline-opts/dns-interface.d
@@ -0,0 +1,11 @@
+Long: dns-interface
+Arg: <interface>
+Help: Interface to use for DNS requests
+Protocols: DNS
+See-also: dns-ipv4-addr dns-ipv6-addr
+Added: 7.33.0
+Requires: c-ares
+---
+Tell curl to send outgoing DNS requests through <interface>. This option is a
+counterpart to --interface (which does not affect DNS). The supplied string
+must be an interface name (not an address).
diff --git a/docs/cmdline-opts/dns-ipv4-addr.d b/docs/cmdline-opts/dns-ipv4-addr.d
new file mode 100644
index 0000000..597b858
--- /dev/null
+++ b/docs/cmdline-opts/dns-ipv4-addr.d
@@ -0,0 +1,11 @@
+Long: dns-ipv4-addr
+Arg: <address>
+Help: IPv4 address to use for DNS requests
+Protocols: DNS
+See-also: dns-interface dns-ipv6-addr
+Added: 7.33.0
+Requires: c-ares
+---
+Tell curl to bind to <ip-address> when making IPv4 DNS requests, so that
+the DNS requests originate from this address. The argument should be a
+single IPv4 address.
diff --git a/docs/cmdline-opts/dns-ipv6-addr.d b/docs/cmdline-opts/dns-ipv6-addr.d
new file mode 100644
index 0000000..581f019
--- /dev/null
+++ b/docs/cmdline-opts/dns-ipv6-addr.d
@@ -0,0 +1,11 @@
+Long: dns-ipv6-addr
+Arg: <address>
+Help: IPv6 address to use for DNS requests
+Protocols: DNS
+See-also: dns-interface dns-ipv4-addr
+Added: 7.33.0
+Requires: c-ares
+---
+Tell curl to bind to <ip-address> when making IPv6 DNS requests, so that
+the DNS requests originate from this address. The argument should be a
+single IPv6 address.
diff --git a/docs/cmdline-opts/dns-servers.d b/docs/cmdline-opts/dns-servers.d
new file mode 100644
index 0000000..a98fd07
--- /dev/null
+++ b/docs/cmdline-opts/dns-servers.d
@@ -0,0 +1,10 @@
+Long: dns-servers
+Arg: <addresses>
+Help: DNS server addrs to use
+Requires: c-ares
+Added: 7.33.0
+---
+Set the list of DNS servers to be used instead of the system default.
+The list of IP addresses should be separated with commas. Port numbers
+may also optionally be given as \fI:<port-number>\fP after each IP
+address.
diff --git a/docs/cmdline-opts/dump-header.d b/docs/cmdline-opts/dump-header.d
new file mode 100644
index 0000000..05c10af
--- /dev/null
+++ b/docs/cmdline-opts/dump-header.d
@@ -0,0 +1,18 @@
+Long: dump-header
+Short: D
+Arg: <filename>
+Help: Write the received headers to <filename>
+Protocols: HTTP FTP
+See-also: output
+---
+Write the received protocol headers to the specified file.
+
+This option is handy to use when you want to store the headers that an HTTP
+site sends to you. Cookies from the headers could then be read in a second
+curl invocation by using the --cookie option! The --cookie-jar option is a
+better way to store cookies.
+
+When used in FTP, the FTP server response lines are considered being "headers"
+and thus are saved there.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/egd-file.d b/docs/cmdline-opts/egd-file.d
new file mode 100644
index 0000000..2ee6d34
--- /dev/null
+++ b/docs/cmdline-opts/egd-file.d
@@ -0,0 +1,7 @@
+Long: egd-file
+Help: EGD socket path for random data
+Protocols: TLS
+See-also: random-file
+---
+Specify the path name to the Entropy Gathering Daemon socket. The socket is
+used to seed the random engine for SSL connections.
diff --git a/docs/cmdline-opts/engine.d b/docs/cmdline-opts/engine.d
new file mode 100644
index 0000000..53b7c33
--- /dev/null
+++ b/docs/cmdline-opts/engine.d
@@ -0,0 +1,8 @@
+Long: engine
+Arg: <name>
+Help: Crypto engine to use
+Protocols: TLS
+---
+Select the OpenSSL crypto engine to use for cipher operations. Use \fI--engine
+list\fP to print a list of build-time supported engines. Note that not all (or
+none) of the engines may be available at run-time.
diff --git a/docs/cmdline-opts/environment.d b/docs/cmdline-opts/environment.d
new file mode 100644
index 0000000..6289e53
--- /dev/null
+++ b/docs/cmdline-opts/environment.d
@@ -0,0 +1,7 @@
+Long: environment
+Help: Write results to environment variables
+Requires: RISC OS
+---
+Sets a range of environment variables, using the names the --write-out option
+supports, to allow easier extraction of useful information after having run
+curl.
diff --git a/docs/cmdline-opts/expect100-timeout.d b/docs/cmdline-opts/expect100-timeout.d
new file mode 100644
index 0000000..c88f0b8
--- /dev/null
+++ b/docs/cmdline-opts/expect100-timeout.d
@@ -0,0 +1,11 @@
+Long: expect100-timeout
+Arg: <seconds>
+Help: How long to wait for 100-continue
+Protocols: HTTP
+Added: 7.47.0
+See-also: connect-timeout
+---
+Maximum time in seconds that you allow curl to wait for a 100-continue
+response when curl emits an Expects: 100-continue header in its request. By
+default curl will wait one second. This option accepts decimal values! When
+curl stops waiting, it will continue as if the response has been received.
diff --git a/docs/cmdline-opts/fail-early.d b/docs/cmdline-opts/fail-early.d
new file mode 100644
index 0000000..4489b4f
--- /dev/null
+++ b/docs/cmdline-opts/fail-early.d
@@ -0,0 +1,18 @@
+Long: fail-early
+Help: Fail on first transfer error, do not continue
+Added: 7.52.0
+---
+Fail and exit on first detected error.
+
+When curl is used to do multiple transfers on the command line, it will
+attempt to operate on each given URL, one by one. By default, it will ignore
+errors if there are more URLs given and the last URL's success will determine
+the error code curl returns. So early failures will be "hidden" by subsequent
+successful transfers.
+
+Using this option, curl will instead return an error on the first transfers
+that fails, independent on the amount of more URLs that are given on the
+command line. This way, no transfer failures go undetected by scripts and
+similar.
+
+This option will apply for all given URLs even if you use --next.
diff --git a/docs/cmdline-opts/fail.d b/docs/cmdline-opts/fail.d
new file mode 100644
index 0000000..c46c571
--- /dev/null
+++ b/docs/cmdline-opts/fail.d
@@ -0,0 +1,14 @@
+Long: fail
+Short: f
+Protocols: HTTP
+Help: Fail silently (no output at all) on HTTP errors
+---
+Fail silently (no output at all) on server errors. This is mostly done to
+better enable scripts etc to better deal with failed attempts. In normal cases
+when an HTTP server fails to deliver a document, it returns an HTML document
+stating so (which often also describes why and more). This flag will prevent
+curl from outputting that and return error 22.
+
+This method is not fail-safe and there are occasions where non-successful
+response codes will slip through, especially when authentication is involved
+(response codes 401 and 407).
diff --git a/docs/cmdline-opts/false-start.d b/docs/cmdline-opts/false-start.d
new file mode 100644
index 0000000..65a8afb
--- /dev/null
+++ b/docs/cmdline-opts/false-start.d
@@ -0,0 +1,12 @@
+Long: false-start
+Help: Enable TLS False Start
+Protocols: TLS
+Added: 7.42.0
+---
+Tells curl to use false start during the TLS handshake. False start is a mode
+where a TLS client will start sending application data before verifying the
+server's Finished message, thus saving a round trip when performing a full
+handshake.
+
+This is currently only implemented in the NSS and Secure Transport (on iOS 7.0
+or later, or OS X 10.9 or later) backends.
diff --git a/docs/cmdline-opts/form-string.d b/docs/cmdline-opts/form-string.d
new file mode 100644
index 0000000..db1856b
--- /dev/null
+++ b/docs/cmdline-opts/form-string.d
@@ -0,0 +1,10 @@
+Long: form-string
+Help: Specify HTTP multipart POST data
+Protocols: HTTP
+See-also: form
+---
+Similar to --form except that the value string for the named parameter is used
+literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in
+the value have no special meaning. Use this in preference to --form\fP if
+there's any possibility that the string value may accidentally trigger the
+\&'@' or \&'<' features of --form.
diff --git a/docs/cmdline-opts/form.d b/docs/cmdline-opts/form.d
new file mode 100644
index 0000000..87a7d07
--- /dev/null
+++ b/docs/cmdline-opts/form.d
@@ -0,0 +1,54 @@
+Long: form
+Short: F
+Arg: <name=content>
+Help: Specify HTTP multipart POST data
+Protocols: HTTP
+Mutexed: data head upload
+---
+This lets curl emulate a filled-in form in which a user has pressed the submit
+button. This causes curl to POST data using the Content-Type
+multipart/form-data according to RFC 2388. This enables uploading of binary
+files etc. To force the 'content' part to be a file, prefix the file name with
+an @ sign. To just get the content part from a file, prefix the file name with
+the symbol <. The difference between @ and < is then that @ makes a file get
+attached in the post as a file upload, while the < makes a text field and just
+get the contents for that text field from a file.
+
+Example: to send an image to a server, where \&'profile' is the name of the
+form-field to which portrait.jpg will be the input:
+
+ curl -F profile=@portrait.jpg https://example.com/upload.cgi
+
+To read content from stdin instead of a file, use - as the filename. This goes
+for both @ and < constructs. Unfortunately it does not support reading the
+file from a named pipe or similar, as it needs the full size before the
+transfer starts.
+
+You can also tell curl what Content-Type to use by using 'type=', in a manner
+similar to:
+
+ curl -F "web=@index.html;type=text/html" example.com
+
+or
+
+ curl -F "name=daniel;type=text/foo" example.com
+
+You can also explicitly change the name field of a file upload part by setting
+filename=, like this:
+
+ curl -F "file=@localfile;filename=nameinpost" example.com
+
+If filename/path contains ',' or ';', it must be quoted by double-quotes like:
+
+ curl -F "file=@\\"localfile\\";filename=\\"nameinpost\\"" example.com
+
+or
+
+ curl -F 'file=@"localfile";filename="nameinpost"' example.com
+
+Note that if a filename/path is quoted by double-quotes, any double-quote
+or backslash within the filename must be escaped by backslash.
+
+See further examples and details in the MANUAL.
+
+This option can be used multiple times.
diff --git a/docs/cmdline-opts/ftp-account.d b/docs/cmdline-opts/ftp-account.d
new file mode 100644
index 0000000..013c4f3
--- /dev/null
+++ b/docs/cmdline-opts/ftp-account.d
@@ -0,0 +1,10 @@
+Long: ftp-account
+Arg: <data>
+Help: Account data string
+Protocols: FTP
+Added: 7.13.0
+---
+When an FTP server asks for "account data" after user name and password has
+been provided, this data is sent off using the ACCT command.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/ftp-alternative-to-user.d b/docs/cmdline-opts/ftp-alternative-to-user.d
new file mode 100644
index 0000000..8982ba8
--- /dev/null
+++ b/docs/cmdline-opts/ftp-alternative-to-user.d
@@ -0,0 +1,10 @@
+Long: ftp-alternative-to-user
+Arg: <command>
+Help: String to replace USER [name]
+Protocols: FTP
+Added: 7.15.5
+---
+If authenticating with the USER and PASS commands fails, send this command.
+When connecting to Tumbleweed's Secure Transport server over FTPS using a
+client certificate, using "SITE AUTH" will tell the server to retrieve the
+username from the certificate.
diff --git a/docs/cmdline-opts/ftp-create-dirs.d b/docs/cmdline-opts/ftp-create-dirs.d
new file mode 100644
index 0000000..ede5710
--- /dev/null
+++ b/docs/cmdline-opts/ftp-create-dirs.d
@@ -0,0 +1,8 @@
+Long: ftp-create-dirs
+Protocols: FTP SFTP
+Help: Create the remote dirs if not present
+See-also: create-dirs
+---
+When an FTP or SFTP URL/operation uses a path that doesn't currently exist on
+the server, the standard behavior of curl is to fail. Using this option, curl
+will instead attempt to create missing directories.
diff --git a/docs/cmdline-opts/ftp-method.d b/docs/cmdline-opts/ftp-method.d
new file mode 100644
index 0000000..95aa522
--- /dev/null
+++ b/docs/cmdline-opts/ftp-method.d
@@ -0,0 +1,21 @@
+Long: ftp-method
+Arg: <method>
+Help: Control CWD usage
+Protocols: FTP
+Added: 7.15.1
+---
+Control what method curl should use to reach a file on an FTP(S)
+server. The method argument should be one of the following alternatives:
+.RS
+.IP multicwd
+curl does a single CWD operation for each path part in the given URL. For deep
+hierarchies this means very many commands. This is how RFC 1738 says it should
+be done. This is the default but the slowest behavior.
+.IP nocwd
+curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full
+path to the server for all these commands. This is the fastest behavior.
+.IP singlecwd
+curl does one CWD with the full target directory and then operates on the file
+\&"normally" (like in the multicwd case). This is somewhat more standards
+compliant than 'nocwd' but without the full penalty of 'multicwd'.
+.RE
diff --git a/docs/cmdline-opts/ftp-pasv.d b/docs/cmdline-opts/ftp-pasv.d
new file mode 100644
index 0000000..44103e2
--- /dev/null
+++ b/docs/cmdline-opts/ftp-pasv.d
@@ -0,0 +1,16 @@
+Long: ftp-pasv
+Help: Use PASV/EPSV instead of PORT
+Protocols: FTP
+Added: 7.11.0
+See-also: disable-epsv
+---
+Use passive mode for the data connection. Passive is the internal default
+behavior, but using this option can be used to override a previous --ftp-port
+option.
+
+If this option is used several times, only the first one is used. Undoing an
+enforced passive really isn't doable but you must then instead enforce the
+correct --ftp-port again.
+
+Passive mode means that curl will try the EPSV command first and then PASV,
+unless --disable-epsv is used.
diff --git a/docs/cmdline-opts/ftp-port.d b/docs/cmdline-opts/ftp-port.d
new file mode 100644
index 0000000..a852e90
--- /dev/null
+++ b/docs/cmdline-opts/ftp-port.d
@@ -0,0 +1,32 @@
+Long: ftp-port
+Arg: <address>
+Help: Use PORT instead of PASV
+Short: P
+Protocols: FTP
+See-also: ftp-pasv disable-eprt
+---
+Reverses the default initiator/listener roles when connecting with FTP. This
+option makes curl use active mode. curl then tells the server to connect back
+to the client's specified address and port, while passive mode asks the server
+to setup an IP address and port for it to connect to. <address> should be one
+of:
+.RS
+.IP interface
+i.e "eth0" to specify which interface's IP address you want to use (Unix only)
+.IP "IP address"
+i.e "192.168.10.1" to specify the exact IP address
+.IP "host name"
+i.e "my.host.domain" to specify the machine
+.IP "-"
+make curl pick the same IP address that is already used for the control
+connection
+.RE
+
+If this option is used several times, the last one will be used. Disable the
+use of PORT with --ftp-pasv. Disable the attempt to use the EPRT command
+instead of PORT by using --disable-eprt. EPRT is really PORT++.
+
+Since 7.19.5, you can append \&":[start]-[end]\&" to the right of the address,
+to tell curl what TCP port range to use. That means you specify a port range,
+from a lower to a higher number. A single number works as well, but do note
+that it increases the risk of failure since the port may not be available.
diff --git a/docs/cmdline-opts/ftp-pret.d b/docs/cmdline-opts/ftp-pret.d
new file mode 100644
index 0000000..dac4c35
--- /dev/null
+++ b/docs/cmdline-opts/ftp-pret.d
@@ -0,0 +1,8 @@
+Long: ftp-pret
+Help: Send PRET before PASV
+Protocols: FTP
+Added: 7.20.0
+---
+Tell curl to send a PRET command before PASV (and EPSV). Certain FTP servers,
+mainly drftpd, require this non-standard command for directory listings as
+well as up and downloads in PASV mode.
diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d
new file mode 100644
index 0000000..da6ab11
--- /dev/null
+++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d
@@ -0,0 +1,12 @@
+Long: ftp-skip-pasv-ip
+Help: Skip the IP address for PASV
+Protocols: FTP
+Added: 7.14.2
+See-also: ftp-pasv
+---
+Tell curl to not use the IP address the server suggests in its response
+to curl's PASV command when curl connects the data connection. Instead curl
+will re-use the same IP address it already uses for the control
+connection.
+
+This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
diff --git a/docs/cmdline-opts/ftp-ssl-ccc-mode.d b/docs/cmdline-opts/ftp-ssl-ccc-mode.d
new file mode 100644
index 0000000..be10294
--- /dev/null
+++ b/docs/cmdline-opts/ftp-ssl-ccc-mode.d
@@ -0,0 +1,11 @@
+Long: ftp-ssl-ccc-mode
+Arg: <active/passive>
+Help: Set CCC mode
+Protocols: FTP
+Added: 7.16.2
+See-also: ftp-ssl-ccc
+---
+Sets the CCC mode. The passive mode will not initiate the shutdown, but
+instead wait for the server to do it, and will not reply to the shutdown from
+the server. The active mode initiates the shutdown and waits for a reply from
+the server.
diff --git a/docs/cmdline-opts/ftp-ssl-ccc.d b/docs/cmdline-opts/ftp-ssl-ccc.d
new file mode 100644
index 0000000..c6edc5b
--- /dev/null
+++ b/docs/cmdline-opts/ftp-ssl-ccc.d
@@ -0,0 +1,10 @@
+Long: ftp-ssl-ccc
+Help: Send CCC after authenticating
+Protocols: FTP
+See-also: ssl ftp-ssl-ccc-mode
+Added: 7.16.1
+---
+Use CCC (Clear Command Channel) Shuts down the SSL/TLS layer after
+authenticating. The rest of the control channel communication will be
+unencrypted. This allows NAT routers to follow the FTP transaction. The
+default mode is passive.
diff --git a/docs/cmdline-opts/ftp-ssl-control.d b/docs/cmdline-opts/ftp-ssl-control.d
new file mode 100644
index 0000000..87a8225
--- /dev/null
+++ b/docs/cmdline-opts/ftp-ssl-control.d
@@ -0,0 +1,8 @@
+Long: ftp-ssl-control
+Help: Require SSL/TLS for FTP login, clear for transfer
+Protocols: FTP
+Added: 7.16.0
+---
+Require SSL/TLS for the FTP login, clear for transfer.  Allows secure
+authentication, but non-encrypted data transfers for efficiency.  Fails the
+transfer if the server doesn't support SSL/TLS.
diff --git a/docs/cmdline-opts/ftp-ssl-reqd.d b/docs/cmdline-opts/ftp-ssl-reqd.d
new file mode 100644
index 0000000..2f80484
--- /dev/null
+++ b/docs/cmdline-opts/ftp-ssl-reqd.d
@@ -0,0 +1,3 @@
+Long: ftp-ssl-reqd
+Help: Require SSL/TLS
+Redirect: ssl-reqd
diff --git a/docs/cmdline-opts/ftp-ssl.d b/docs/cmdline-opts/ftp-ssl.d
new file mode 100644
index 0000000..aee48a1
--- /dev/null
+++ b/docs/cmdline-opts/ftp-ssl.d
@@ -0,0 +1,3 @@
+Long: ftp-ssl
+Help: Try SSL/TLS
+Redirect: ssl
diff --git a/docs/cmdline-opts/gen.pl b/docs/cmdline-opts/gen.pl
new file mode 100755
index 0000000..cd9e3cf
--- /dev/null
+++ b/docs/cmdline-opts/gen.pl
@@ -0,0 +1,374 @@
+#!/usr/bin/perl
+
+my $some_dir=".";
+
+opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!";
+my @s = grep { /\.d$/ && -f "$some_dir/$_" } readdir($dh);
+closedir $dh;
+
+my %optshort;
+my %optlong;
+my %helplong;
+my %arglong;
+my %redirlong;
+my %protolong;
+
+# get the long name version, return the man page string
+sub manpageify {
+    my ($k)=@_;
+    my $l;
+    if($optlong{$k} ne "") {
+        # both short + long
+        $l = "\\fI-".$optlong{$k}.", --$k\\fP";
+    }
+    else {
+        # only long
+        $l = "\\fI--$k\\fP";
+    }
+    return $l;
+}
+
+sub printdesc {
+    my @desc = @_;
+    for my $d (@desc) {
+        # skip lines starting with space (examples)
+        if($d =~ /^[^ ]/) {
+            for my $k (keys %optlong) {
+                my $l = manpageify($k);
+                $d =~ s/--$k([^a-z0-9_-])/$l$1/;
+            }
+        }
+        print $d;
+    }
+}
+
+sub seealso {
+    my($standalone, $data)=@_;
+    if($standalone) {
+        return sprintf
+            ".SH \"SEE ALSO\"\n$data\n";
+    }
+    else {
+        return "See also $data. ";
+    }
+}
+
+sub overrides {
+    my ($standalone, $data)=@_;
+    if($standalone) {
+        return ".SH \"OVERRIDES\"\n$data\n";
+    }
+    else {
+        return $data;
+    }
+}
+
+sub protocols {
+    my ($standalone, $data)=@_;
+    if($standalone) {
+        return ".SH \"PROTOCOLS\"\n$data\n";
+    }
+    else {
+        return "($data) ";
+    }
+}
+
+sub added {
+    my ($standalone, $data)=@_;
+    if($standalone) {
+        return ".SH \"ADDED\"\nAdded in curl version $data\n";
+    }
+    else {
+        return "Added in $added. ";
+    }
+}
+
+sub single {
+    my ($f, $standalone)=@_;
+    open(F, "<$f") ||
+        return 1;
+    my $short;
+    my $long;
+    my $tags;
+    my $added;
+    my $protocols;
+    my $arg;
+    my $mutexed;
+    my $requires;
+    my $redirect;
+    my $seealso;
+    my $magic; # cmdline special option
+    while(<F>) {
+        if(/^Short: *(.)/i) {
+            $short=$1;
+        }
+        elsif(/^Long: *(.*)/i) {
+            $long=$1;
+        }
+        elsif(/^Added: *(.*)/i) {
+            $added=$1;
+        }
+        elsif(/^Tags: *(.*)/i) {
+            $tags=$1;
+        }
+        elsif(/^Arg: *(.*)/i) {
+            $arg=$1;
+        }
+        elsif(/^Magic: *(.*)/i) {
+            $magic=$1;
+        }
+        elsif(/^Mutexed: *(.*)/i) {
+            $mutexed=$1;
+        }
+        elsif(/^Protocols: *(.*)/i) {
+            $protocols=$1;
+        }
+        elsif(/^See-also: *(.*)/i) {
+            $seealso=$1;
+        }
+        elsif(/^Requires: *(.*)/i) {
+            $requires=$1;
+        }
+        elsif(/^Redirect: *(.*)/i) {
+            $redirect=$1;
+        }
+        elsif(/^Help: *(.*)/i) {
+            ;
+        }
+        elsif(/^---/) {
+            if(!$long) {
+                print STDERR "WARN: no 'Long:' in $f\n";
+            }
+            last;
+        }
+        else {
+            chomp;
+            print STDERR "WARN: unrecognized line in $f, ignoring:\n:'$_';"
+        }
+    }
+    my @dest;
+    while(<F>) {
+        push @desc, $_;
+    }
+    close(F);
+    my $opt;
+    if(defined($short) && $long) {
+        $opt = "-$short, --$long";
+    }
+    elsif($short && !$long) {
+        $opt = "-$short";
+    }
+    elsif($long && !$short) {
+        $opt = "--$long";
+    }
+
+    if($arg) {
+        $opt .= " $arg";
+    }
+
+    if($standalone) {
+        print ".TH curl 1 \"30 Nov 2016\" \"curl 7.52.0\" \"curl manual\"\n";
+        print ".SH OPTION\n";
+        print "curl $opt\n";
+    }
+    else {
+        print ".IP \"$opt\"\n";
+    }
+    if($redirect) {
+        my $l = manpageify($redirect);
+        print "Use $l instead!\n";
+    }
+    else {
+        if($protocols) {
+            print protocols($standalone, $protocols);
+        }
+    }
+
+    if($standalone) {
+        print ".SH DESCRIPTION\n";
+    }
+
+    printdesc(@desc);
+    undef @desc;
+
+    my @foot;
+    if($seealso) {
+        my @m=split(/ /, $seealso);
+        my $mstr;
+        for my $k (@m) {
+            my $l = manpageify($k);
+            $mstr .= sprintf "%s$l", $mstr?" and ":"";
+        }
+        push @foot, seealso($standalone, $mstr);
+    }
+    if($requires) {
+        my $l = manpageify($long);
+        push @foot, "$l requires that the underlying libcurl".
+            " was built to support $requires. ";
+    }
+    if($mutexed) {
+        my @m=split(/ /, $mutexed);
+        my $mstr;
+        for my $k (@m) {
+            my $l = manpageify($k);
+            $mstr .= sprintf "%s$l", $mstr?" and ":"";
+        }
+        push @foot, overrides($standalone, "This option overrides $mstr. ");
+    }
+    if($added) {
+        push @foot, added($standalone, $added);
+    }
+    if($foot[0]) {
+        print "\n";
+        print @foot;
+        print "\n";
+    }
+    return 0;
+}
+
+sub getshortlong {
+    my ($f)=@_;
+    open(F, "<$f");
+    my $short;
+    my $long;
+    my $help;
+    my $arg;
+    my $protocols;
+    while(<F>) {
+        if(/^Short: (.)/i) {
+            $short=$1;
+        }
+        elsif(/^Long: (.*)/i) {
+            $long=$1;
+        }
+        elsif(/^Help: (.*)/i) {
+            $help=$1;
+        }
+        elsif(/^Arg: (.*)/i) {
+            $arg=$1;
+        }
+        elsif(/^Protocols: (.*)/i) {
+            $protocols=$1;
+        }
+        elsif(/^---/) {
+            last;
+        }
+    }
+    close(F);
+    if($short) {
+        $optshort{$short}=$long;
+    }
+    if($long) {
+        $optlong{$long}=$short;
+        $helplong{$long}=$help;
+        $arglong{$long}=$arg;
+        $protolong{$long}=$protocols;
+    }
+}
+
+sub indexoptions {
+  foreach my $f (@s) {
+    getshortlong($f);
+  }
+}
+
+sub header {
+    my ($f)=@_;
+    open(F, "<$f");
+    my @d;
+    while(<F>) {
+        push @d, $_;
+    }
+    close(F);
+    printdesc(@d);
+}
+
+sub listhelp {
+    foreach my $f (sort keys %helplong) {
+        my $long = $f;
+        my $short = $optlong{$long};
+        my $opt;
+
+        if(defined($short) && $long) {
+            $opt = "-$short, --$long";
+        }
+        elsif($long && !$short) {
+            $opt = "    --$long";
+        }
+
+        my $arg = $arglong{$long};
+        if($arg) {
+            $opt .= " $arg";
+        }
+
+        my $line = sprintf " %-19s %s\n", $opt, $helplong{$f};
+
+        if(length($line) > 79) {
+            print STDERR "WARN: the --$long line is too long\n";
+        }
+        print $line;
+    }
+}
+
+sub mainpage {
+    # show the page header
+    header("page-header");
+
+    # output docs for all options
+    foreach my $f (sort @s) {
+        single($f, 0);
+    }
+}
+
+sub showonly {
+    my ($f) = @_;
+    if(single($f, 1)) {
+        print STDERR "$f: failed\n";
+    }
+}
+
+sub showprotocols {
+    my %prots;
+    foreach my $f (keys %optlong) {
+        my @p = split(/ /, $protolong{$f});
+        for my $p (@p) {
+            $prots{$p}++;
+        }
+    }
+    for(sort keys %prots) {
+        printf "$_ (%d options)\n", $prots{$_};
+    }
+}
+
+sub getargs {
+    my $f;
+    do {
+        $f = shift @ARGV;
+        if($f eq "mainpage") {
+            mainpage();
+            return;
+        }
+        elsif($f eq "listhelp") {
+            listhelp();
+            return;
+        }
+        elsif($f eq "single") {
+            showonly(shift @ARGV);
+            return;
+        }
+        elsif($f eq "protos") {
+            showprotocols();
+            return;
+        }
+    } while($f);
+
+    print "Usage: gen.pl <mainpage/listhelp/single FILE/protos>\n";
+}
+
+#------------------------------------------------------------------------
+
+# learn all existing options
+indexoptions();
+
+getargs();
+
diff --git a/docs/cmdline-opts/get.d b/docs/cmdline-opts/get.d
new file mode 100644
index 0000000..be7cb25
--- /dev/null
+++ b/docs/cmdline-opts/get.d
@@ -0,0 +1,15 @@
+Long: get
+Short: G
+Help: Put the post data in the URL and use GET
+---
+When used, this option will make all data specified with --data, --data-binary
+or --data-urlencode to be used in an HTTP GET request instead of the POST
+request that otherwise would be used. The data will be appended to the URL
+with a '?' separator.
+
+If used in combination with --head, the POST data will instead be appended to
+the URL with a HEAD request.
+
+If this option is used several times, only the first one is used. This is
+because undoing a GET doesn't make sense, but you should then instead enforce
+the alternative method you prefer.
diff --git a/docs/cmdline-opts/globoff.d b/docs/cmdline-opts/globoff.d
new file mode 100644
index 0000000..fff6516
--- /dev/null
+++ b/docs/cmdline-opts/globoff.d
@@ -0,0 +1,8 @@
+Long: globoff
+Short: g
+Help: Disable URL sequences and ranges using {} and []
+---
+This option switches off the "URL globbing parser". When you set this option,
+you can specify URLs that contain the letters {}[] without having them being
+interpreted by curl itself. Note that these letters are not normal legal URL
+contents but they should be encoded according to the URI standard.
diff --git a/docs/cmdline-opts/head.d b/docs/cmdline-opts/head.d
new file mode 100644
index 0000000..350a100
--- /dev/null
+++ b/docs/cmdline-opts/head.d
@@ -0,0 +1,8 @@
+Long: head
+Short: I
+Help: Show document info only
+Protocols: HTTP FTP FILE
+---
+Fetch the headers only! HTTP-servers feature the command HEAD which this uses
+to get nothing but the header of a document. When used on an FTP or FILE file,
+curl displays the file size and last modification time only.
diff --git a/docs/cmdline-opts/header.d b/docs/cmdline-opts/header.d
new file mode 100644
index 0000000..762334f
--- /dev/null
+++ b/docs/cmdline-opts/header.d
@@ -0,0 +1,39 @@
+Long: header
+Short: H
+Arg: <header>
+Help: Pass custom header LINE to server
+Protocols: HTTP
+---
+
+Extra header to include in the request when sending HTTP to a server. You may
+specify any number of extra headers. Note that if you should add a custom
+header that has the same name as one of the internal ones curl would use, your
+externally set header will be used instead of the internal one. This allows
+you to make even trickier stuff than curl would normally do. You should not
+replace internally set headers without knowing perfectly well what you're
+doing. Remove an internal header by giving a replacement without content on
+the right side of the colon, as in: -H \&"Host:". If you send the custom
+header with no-value then its header must be terminated with a semicolon, such
+as \-H \&"X-Custom-Header;" to send "X-Custom-Header:".
+
+curl will make sure that each header you add/replace is sent with the proper
+end-of-line marker, you should thus \fBnot\fP add that as a part of the header
+content: do not add newlines or carriage returns, they will only mess things up
+for you.
+
+See also the --user-agent and --referer options.
+
+Starting in 7.37.0, you need --proxy-header to send custom headers intended
+for a proxy.
+
+Example:
+
+ curl -H "X-First-Name: Joe" http://example.com/
+
+\fBWARNING\fP: headers set with this option will be set in all requests - even
+after redirects are followed, like when told with \fB-L, --location\fP. This
+can lead to the header being sent to other hosts than the original host, so
+sensitive headers should be used with caution combined with following
+redirects.
+
+This option can be used multiple times to add/replace/remove multiple headers.
diff --git a/docs/cmdline-opts/hostpubmd5.d b/docs/cmdline-opts/hostpubmd5.d
new file mode 100644
index 0000000..a851158
--- /dev/null
+++ b/docs/cmdline-opts/hostpubmd5.d
@@ -0,0 +1,9 @@
+Long: hostpubmd5
+Arg: <md5>
+Help: Acceptable MD5 hash of the host public key
+Protocols: SFTP SCP
+Added: 7.17.1
+---
+Pass a string containing 32 hexadecimal digits. The string should
+be the 128 bit MD5 checksum of the remote host's public key, curl will refuse
+the connection with the host unless the md5sums match.
diff --git a/docs/cmdline-opts/http1.0.d b/docs/cmdline-opts/http1.0.d
new file mode 100644
index 0000000..d9bbd76
--- /dev/null
+++ b/docs/cmdline-opts/http1.0.d
@@ -0,0 +1,10 @@
+Short: 0
+Long: http1.0
+Tags: Versions
+Protocols: HTTP
+Added:
+Mutexed: http1.1 http2
+Help: Use HTTP 1.0
+---
+Tells curl to use HTTP version 1.0 instead of using its internally preferred
+HTTP version.
diff --git a/docs/cmdline-opts/http1.1.d b/docs/cmdline-opts/http1.1.d
new file mode 100644
index 0000000..f1e6b5c
--- /dev/null
+++ b/docs/cmdline-opts/http1.1.d
@@ -0,0 +1,8 @@
+Long: http1.1
+Tags: Versions
+Protocols: HTTP
+Added: 7.33.0
+Mutexed: http1.0 http2
+Help: Use HTTP 1.1
+---
+Tells curl to use HTTP version 1.1.
diff --git a/docs/cmdline-opts/http2-prior-knowledge.d b/docs/cmdline-opts/http2-prior-knowledge.d
new file mode 100644
index 0000000..f793f77
--- /dev/null
+++ b/docs/cmdline-opts/http2-prior-knowledge.d
@@ -0,0 +1,12 @@
+Long: http2-prior-knowledge
+Tags: Versions
+Protocols: HTTP
+Added: 7.49.0
+Mutexed: http1.1 http1.0 http2
+Requires: HTTP/2
+Help: Use HTTP 2 without HTTP/1.1 Upgrade
+---
+Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1
+Upgrade. It requires prior knowledge that the server supports HTTP/2 straight
+away. HTTPS requests will still do HTTP/2 the standard way with negotiated
+protocol version in the TLS handshake.
diff --git a/docs/cmdline-opts/http2.d b/docs/cmdline-opts/http2.d
new file mode 100644
index 0000000..04cff00
--- /dev/null
+++ b/docs/cmdline-opts/http2.d
@@ -0,0 +1,10 @@
+Long: http2
+Tags: Versions
+Protocols: HTTP
+Added: 7.33.0
+Mutexed: http1.1 http1.0 http2-prior-knowledge
+Requires: HTTP/2
+See-also: no-alpn
+Help: Use HTTP 2
+---
+Tells curl to use HTTP version 2.
diff --git a/docs/cmdline-opts/ignore-content-length.d b/docs/cmdline-opts/ignore-content-length.d
new file mode 100644
index 0000000..53524f5
--- /dev/null
+++ b/docs/cmdline-opts/ignore-content-length.d
@@ -0,0 +1,10 @@
+Long: ignore-content-length
+Help: Ignore the size of the remote resource
+Protocols: FTP HTTP
+---
+For HTTP, Ignore the Content-Length header. This is particularly useful for
+servers running Apache 1.x, which will report incorrect Content-Length for
+files larger than 2 gigabytes.
+
+For FTP (since 7.46.0), skip the RETR command to figure out the size before
+downloading a file.
diff --git a/docs/cmdline-opts/include.d b/docs/cmdline-opts/include.d
new file mode 100644
index 0000000..e55d516
--- /dev/null
+++ b/docs/cmdline-opts/include.d
@@ -0,0 +1,7 @@
+Long: include
+Short: i
+Help: Include protocol headers in the output
+See-also: verbose
+---
+Include the HTTP-header in the output. The HTTP-header includes things like
+server-name, date of the document, HTTP-version and more...
diff --git a/docs/cmdline-opts/insecure.d b/docs/cmdline-opts/insecure.d
new file mode 100644
index 0000000..1dd0fa8
--- /dev/null
+++ b/docs/cmdline-opts/insecure.d
@@ -0,0 +1,12 @@
+Long: insecure
+Short: k
+Help: Allow insecure connections when using SSL
+Protocols: TLS
+---
+This option explicitly allows curl to perform "insecure" SSL connections and
+transfers. All SSL connections are attempted to be made secure by using the CA
+certificate bundle installed by default. This makes all connections considered
+\&"insecure" fail unless --insecure is used.
+
+See this online resource for further details:
+ https://curl.haxx.se/docs/sslcerts.html
diff --git a/docs/cmdline-opts/interface.d b/docs/cmdline-opts/interface.d
new file mode 100644
index 0000000..da84cd2
--- /dev/null
+++ b/docs/cmdline-opts/interface.d
@@ -0,0 +1,12 @@
+Long: interface
+Arg: <name>
+Help: Use network INTERFACE (or address)
+See-also: dns-interface
+---
+
+Perform an operation using a specified interface. You can enter interface
+name, IP address or host name. An example could look like:
+
+ curl --interface eth0:1 https://www.example.com/
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/ipv4.d b/docs/cmdline-opts/ipv4.d
new file mode 100644
index 0000000..9c40c8c
--- /dev/null
+++ b/docs/cmdline-opts/ipv4.d
@@ -0,0 +1,12 @@
+Short: 4
+Long: ipv4
+Tags: Versions
+Protocols:
+Added:
+Mutexed: ipv6
+Requires:
+See-also: http1.1 http2
+Help: Resolve names to IPv4 addresses
+---
+This option tells curl to resolve names to IPv4 addresses only, and not for
+example try IPv6.
diff --git a/docs/cmdline-opts/ipv6.d b/docs/cmdline-opts/ipv6.d
new file mode 100644
index 0000000..c2392e7
--- /dev/null
+++ b/docs/cmdline-opts/ipv6.d
@@ -0,0 +1,12 @@
+Short: 6
+Long: ipv6
+Tags: Versions
+Protocols:
+Added:
+Mutexed: ipv6
+Requires:
+See-also: http1.1 http2
+Help: Resolve names to IPv6 addresses
+---
+This option tells curl to resolve names to IPv6 addresses only, and not for
+example try IPv4.
diff --git a/docs/cmdline-opts/junk-session-cookies.d b/docs/cmdline-opts/junk-session-cookies.d
new file mode 100644
index 0000000..40ccd9c
--- /dev/null
+++ b/docs/cmdline-opts/junk-session-cookies.d
@@ -0,0 +1,10 @@
+Long: junk-session-cookies
+Short: j
+Help: Ignore session cookies read from file
+Protocols: HTTP
+See-also: cookie cookie-jar
+---
+When curl is told to read cookies from a given file, this option will make it
+discard all "session cookies". This will basically have the same effect as if
+a new session is started. Typical browsers always discard session cookies when
+they're closed down.
diff --git a/docs/cmdline-opts/keepalive-time.d b/docs/cmdline-opts/keepalive-time.d
new file mode 100644
index 0000000..c816e13
--- /dev/null
+++ b/docs/cmdline-opts/keepalive-time.d
@@ -0,0 +1,13 @@
+Long: keepalive-time
+Arg: <seconds>
+Help: Interval time for keepalive probes
+Added: 7.18.0
+---
+This option sets the time a connection needs to remain idle before sending
+keepalive probes and the time between individual keepalive probes. It is
+currently effective on operating systems offering the TCP_KEEPIDLE and
+TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This
+option has no effect if --no-keepalive is used.
+
+If this option is used several times, the last one will be used. If
+unspecified, the option defaults to 60 seconds.
diff --git a/docs/cmdline-opts/key-type.d b/docs/cmdline-opts/key-type.d
new file mode 100644
index 0000000..bf39bcd
--- /dev/null
+++ b/docs/cmdline-opts/key-type.d
@@ -0,0 +1,9 @@
+Long: key-type
+Arg: <type>
+Help: Private key file type (DER/PEM/ENG)
+Protocols: TLS
+---
+Private key file type. Specify which type your --key provided private key
+is. DER, PEM, and ENG are supported. If not specified, PEM is assumed.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/key.d b/docs/cmdline-opts/key.d
new file mode 100644
index 0000000..fbf583a
--- /dev/null
+++ b/docs/cmdline-opts/key.d
@@ -0,0 +1,10 @@
+Long: key
+Arg: <key>
+Protocols: TLS SSH
+Help: Private key file name
+---
+Private key file name. Allows you to provide your private key in this separate
+file. For SSH, if not specified, curl tries the following candidates in order:
+'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/krb.d b/docs/cmdline-opts/krb.d
new file mode 100644
index 0000000..19547af
--- /dev/null
+++ b/docs/cmdline-opts/krb.d
@@ -0,0 +1,11 @@
+Long: krb
+Arg: <level>
+Help: Enable Kerberos with security <level>
+Protocols: FTP
+Requires: Kerberos
+---
+Enable Kerberos authentication and use. The level must be entered and should
+be one of 'clear', 'safe', 'confidential', or 'private'. Should you use a
+level that is not one of these, 'private' will instead be used.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/krb4.d b/docs/cmdline-opts/krb4.d
new file mode 100644
index 0000000..79bab81
--- /dev/null
+++ b/docs/cmdline-opts/krb4.d
@@ -0,0 +1,2 @@
+Long: krb4
+Redirect: krb
diff --git a/docs/cmdline-opts/libcurl.d b/docs/cmdline-opts/libcurl.d
new file mode 100644
index 0000000..ef132fe
--- /dev/null
+++ b/docs/cmdline-opts/libcurl.d
@@ -0,0 +1,11 @@
+Long: libcurl
+Arg: <file>
+Help: Dump libcurl equivalent code of this command line
+Added: 7.16.1
+---
+Append this option to any ordinary curl command line, and you will get a
+libcurl-using C source code written to the file that does the equivalent
+of what your command-line operation does!
+
+If this option is used several times, the last given file name will be
+used.
diff --git a/docs/cmdline-opts/limit-rate.d b/docs/cmdline-opts/limit-rate.d
new file mode 100644
index 0000000..8784a84
--- /dev/null
+++ b/docs/cmdline-opts/limit-rate.d
@@ -0,0 +1,18 @@
+Long: limit-rate
+Arg: <speed>
+Help: Limit transfer speed to RATE
+---
+Specify the maximum transfer rate you want curl to use - for both downloads
+and uploads. This feature is useful if you have a limited pipe and you'd like
+your transfer not to use your entire bandwidth. To make it slower than it
+otherwise would be.
+
+The given speed is measured in bytes/second, unless a suffix is appended.
+Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
+megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
+
+If you also use the --speed-limit option, that option will take precedence and
+might cripple the rate-limiting slightly, to help keeping the speed-limit
+logic working.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/list-only.d b/docs/cmdline-opts/list-only.d
new file mode 100644
index 0000000..4c56304
--- /dev/null
+++ b/docs/cmdline-opts/list-only.d
@@ -0,0 +1,24 @@
+Long: list-only
+Short: l
+Protocols: FTP POP3
+Help: List only mode
+Added: 7.21.5
+---
+(FTP)
+When listing an FTP directory, this switch forces a name-only view. This is
+especially useful if the user wants to machine-parse the contents of an FTP
+directory since the normal directory view doesn't use a standard look or
+format. When used like this, the option causes a NLST command to be sent to
+the server instead of LIST.
+
+Note: Some FTP servers list only files in their response to NLST; they do not
+include sub-directories and symbolic links.
+
+(POP3)
+When retrieving a specific email from POP3, this switch forces a LIST command
+to be performed instead of RETR. This is particularly useful if the user wants
+to see if a specific message id exists on the server and what size it is.
+
+Note: When combined with --request, this option can be used to send an UIDL
+command instead, so the user may use the email's unique identifier rather than
+it's message id to make the request.
diff --git a/docs/cmdline-opts/local-port.d b/docs/cmdline-opts/local-port.d
new file mode 100644
index 0000000..d96b46e
--- /dev/null
+++ b/docs/cmdline-opts/local-port.d
@@ -0,0 +1,9 @@
+Long: local-port
+Arg: <num/range>
+Help: Force use of RANGE for local port numbers
+Added: 7.15.2
+---
+Set a preferred single number or range (FROM-TO) of local port numbers to use
+for the connection(s).  Note that port numbers by nature are a scarce resource
+that will be busy at times so setting this range to something too narrow might
+cause unnecessary connection setup failures.
diff --git a/docs/cmdline-opts/location-trusted.d b/docs/cmdline-opts/location-trusted.d
new file mode 100644
index 0000000..995a871
--- /dev/null
+++ b/docs/cmdline-opts/location-trusted.d
@@ -0,0 +1,9 @@
+Long: location-trusted
+Help: Like --location, and send auth to other hosts
+Protocols: HTTP
+See-also: user
+---
+Like --location, but will allow sending the name + password to all hosts that
+the site may redirect to. This may or may not introduce a security breach if
+the site redirects you to a site to which you'll send your authentication info
+(which is plaintext in the case of HTTP Basic authentication).
diff --git a/docs/cmdline-opts/location.d b/docs/cmdline-opts/location.d
new file mode 100644
index 0000000..7c70e69
--- /dev/null
+++ b/docs/cmdline-opts/location.d
@@ -0,0 +1,23 @@
+Long: location
+Short: L
+Help: Follow redirects
+Protocols: HTTP
+---
+If the server reports that the requested page has moved to a different
+location (indicated with a Location: header and a 3XX response code), this
+option will make curl redo the request on the new place. If used together with
+--include or --head, headers from all requested pages will be shown. When
+authentication is used, curl only sends its credentials to the initial
+host. If a redirect takes curl to a different host, it won't be able to
+intercept the user+password. See also --location-trusted on how to change
+this. You can limit the amount of redirects to follow by using the
+--max-redirs option.
+
+When curl follows a redirect and the request is not a plain GET (for example
+POST or PUT), it will do the following request with a GET if the HTTP response
+was 301, 302, or 303. If the response code was any other 3xx code, curl will
+re-send the following request using the same unmodified method.
+
+You can tell curl to not change the non-GET request method to GET after a 30x
+response by using the dedicated options for that: --post301, --post302 and
+--post303.
diff --git a/docs/cmdline-opts/login-options.d b/docs/cmdline-opts/login-options.d
new file mode 100644
index 0000000..ea2af08
--- /dev/null
+++ b/docs/cmdline-opts/login-options.d
@@ -0,0 +1,13 @@
+Long: login-options
+Arg: <options>
+Protocols: IMAP POP3 SMTP
+Added: 7.34.0
+---
+Specify the login options to use during server authentication.
+
+You can use the login options to specify protocol specific options that may
+be used during authentication. At present only IMAP, POP3 and SMTP support
+login options. For more information about the login options please see
+RFC 2384, RFC 5092 and IETF draft draft-earhart-url-smtp-00.txt
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/mail-auth.d b/docs/cmdline-opts/mail-auth.d
new file mode 100644
index 0000000..70cf0ed
--- /dev/null
+++ b/docs/cmdline-opts/mail-auth.d
@@ -0,0 +1,10 @@
+Long: mail-auth
+Arg: <address>
+Protocols: SMTP
+Help: Originator address of the original email
+Added: 7.25.0
+See-also: mail-rcpt mail-from
+---
+Specify a single address. This will be used to specify the authentication
+address (identity) of a submitted message that is being relayed to another
+server.
diff --git a/docs/cmdline-opts/mail-from.d b/docs/cmdline-opts/mail-from.d
new file mode 100644
index 0000000..1d93234
--- /dev/null
+++ b/docs/cmdline-opts/mail-from.d
@@ -0,0 +1,8 @@
+Long: mail-from
+Arg: <address>
+Help: Mail from this address
+Protocols: SMTP
+Added: 7.20.0
+See-also: mail-rcpt mail-auth
+---
+Specify a single address that the given mail should get sent from.
diff --git a/docs/cmdline-opts/mail-rcpt.d b/docs/cmdline-opts/mail-rcpt.d
new file mode 100644
index 0000000..d747cea
--- /dev/null
+++ b/docs/cmdline-opts/mail-rcpt.d
@@ -0,0 +1,19 @@
+Long: mail-rcpt
+Arg: <address>
+Help: Mail from this address
+Protocols: SMTP
+Added: 7.20.0
+---
+Specify a single address, user name or mailing list name. Repeat this
+option several times to send to multiple recipients.
+
+When performing a mail transfer, the recipient should specify a valid email
+address to send the mail to.
+
+When performing an address verification (VRFY command), the recipient should be
+specified as the user name or user name and domain (as per Section 3.5 of
+RFC5321). (Added in 7.34.0)
+
+When performing a mailing list expand (EXPN command), the recipient should be
+specified using the mailing list name, such as "Friends" or "London-Office".
+(Added in 7.34.0)
diff --git a/docs/cmdline-opts/max-filesize.d b/docs/cmdline-opts/max-filesize.d
new file mode 100644
index 0000000..e92ef58
--- /dev/null
+++ b/docs/cmdline-opts/max-filesize.d
@@ -0,0 +1,12 @@
+Long: max-filesize
+Arg: <bytes>
+Help: Maximum file size to download
+See-also: limit-rate
+---
+Specify the maximum size (in bytes) of a file to download. If the file
+requested is larger than this value, the transfer will not start and curl will
+return with exit code 63.
+
+\fBNOTE:\fP The file size is not always known prior to download, and for such
+files this option has no effect even if the file transfer ends up being larger
+than this given limit. This concerns both FTP and HTTP transfers.
diff --git a/docs/cmdline-opts/max-redirs.d b/docs/cmdline-opts/max-redirs.d
new file mode 100644
index 0000000..04b824b
--- /dev/null
+++ b/docs/cmdline-opts/max-redirs.d
@@ -0,0 +1,11 @@
+Long: max-redirs
+Arg: <num>
+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.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/max-time.d b/docs/cmdline-opts/max-time.d
new file mode 100644
index 0000000..c22343d
--- /dev/null
+++ b/docs/cmdline-opts/max-time.d
@@ -0,0 +1,13 @@
+Long: max-time
+Short: m
+Arg: <time>
+Help: Maximum time allowed for the transfer
+See-also: connect-timeout
+---
+Maximum time in seconds that you allow the whole operation to take.  This is
+useful for preventing your batch jobs from hanging for hours due to slow
+networks or links going down.  Since 7.32.0, this option accepts decimal
+values, but the actual timeout will decrease in accuracy as the specified
+timeout increases in decimal precision.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/metalink.d b/docs/cmdline-opts/metalink.d
new file mode 100644
index 0000000..8047e9f
--- /dev/null
+++ b/docs/cmdline-opts/metalink.d
@@ -0,0 +1,27 @@
+Long: metalink
+Help: Process given URLs as metalink XML file
+Added: 7.27.0
+Requires: metalink
+---
+This option can tell curl to parse and process a given URI as Metalink file
+(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
+listed within for failover if there are errors (such as the file or server not
+being available). It will also verify the hash of the file after the download
+completes. The Metalink file itself is downloaded and processed in memory and
+not stored in the local file system.
+
+Example to use a remote Metalink file:
+
+ curl --metalink http://www.example.com/example.metalink
+
+To use a Metalink file in the local file system, use FILE protocol (file://):
+
+ curl --metalink file://example.metalink
+
+Please note that if FILE protocol is disabled, there is no way to use a local
+Metalink file at the time of this writing. Also note that if --metalink and
+--include are used together, --include will be ignored. This is because
+including headers in the response will break Metalink parser and if the
+headers are included in the file described in Metalink file, hash check will
+fail.
+
diff --git a/docs/cmdline-opts/negotiate.d b/docs/cmdline-opts/negotiate.d
new file mode 100644
index 0000000..69a6b91
--- /dev/null
+++ b/docs/cmdline-opts/negotiate.d
@@ -0,0 +1,15 @@
+Long: negotiate
+Help: Use HTTP Negotiate (SPNEGO) authentication
+Protocols: HTTP
+See-also: basic ntlm anyauth proxy-negotiate
+---
+Enables Negotiate (SPNEGO) authentication.
+
+This option requires a library built with GSS-API or SSPI support. Use
+--version to see if your curl supports GSS-API/SSPI or SPNEGO.
+
+When using this option, you must also provide a fake --user option to activate
+the authentication code properly. Sending a '-u :' is enough as the user name
+and password from the --user option aren't actually used.
+
+If this option is used several times, only the first one is used.
diff --git a/docs/cmdline-opts/netrc-file.d b/docs/cmdline-opts/netrc-file.d
new file mode 100644
index 0000000..4118b4d
--- /dev/null
+++ b/docs/cmdline-opts/netrc-file.d
@@ -0,0 +1,12 @@
+Long: netrc-file
+Help: Specify FILE for netrc
+Arg: <filemame>
+Added: 7.21.5
+Mutexed: netrc
+---
+This option is similar to --netrc, except that you provide the path (absolute
+or relative) to the netrc file that Curl should use.  You can only specify one
+netrc file per invocation. If several --netrc-file options are provided,
+the last one will be used.
+
+It will abide by --netrc-optional if specified.
diff --git a/docs/cmdline-opts/netrc-optional.d b/docs/cmdline-opts/netrc-optional.d
new file mode 100644
index 0000000..c285403
--- /dev/null
+++ b/docs/cmdline-opts/netrc-optional.d
@@ -0,0 +1,7 @@
+Long: netrc-optional
+Help: Use either .netrc or URL
+Mutexed: netrc
+See-also: netrc-file
+---
+Very similar to --netrc, but this option makes the .netrc usage \fBoptional\fP
+and not mandatory as the --netrc option does.
diff --git a/docs/cmdline-opts/netrc.d b/docs/cmdline-opts/netrc.d
new file mode 100644
index 0000000..2df2678
--- /dev/null
+++ b/docs/cmdline-opts/netrc.d
@@ -0,0 +1,17 @@
+Long: netrc
+Short: n
+Help: Must read .netrc for user name and password
+---
+Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's
+home directory for login name and password. This is typically used for FTP on
+Unix. If used with HTTP, curl will enable user authentication. See
+\fInetrc(5)\fP \fIftp(1)\fP for details on the file format. Curl will not
+complain if that file doesn't have the right permissions (it should not be
+either world- or group-readable). The environment variable "HOME" is used to
+find the home directory.
+
+A quick and very simple example of how to setup a \fI.netrc\fP to allow curl
+to FTP to the machine host.domain.com with user name \&'myself' and password
+\&'secret' should look similar to:
+
+.B "machine host.domain.com login myself password secret"
diff --git a/docs/cmdline-opts/next.d b/docs/cmdline-opts/next.d
new file mode 100644
index 0000000..f368c1b
--- /dev/null
+++ b/docs/cmdline-opts/next.d
@@ -0,0 +1,20 @@
+Short: :
+Long: next
+Tags:
+Protocols:
+Added: 7.36.0
+Magic: divider
+Help: Make next URL use its separate set of options
+---
+Tells curl to use a separate operation for the following URL and associated
+options. This allows you to send several URL requests, each with their own
+specific options, for example, such as different user names or custom requests
+for each.
+
+--next will reset all local options and only global ones will have their
+values survive over to the operation following the --next instruction. Global
+options include --verbose and --fail-early.
+
+For example, you can do both a GET and a POST in a single command line:
+
+ curl www1.example.com --next -d postthis www2.example.com
diff --git a/docs/cmdline-opts/no-alpn.d b/docs/cmdline-opts/no-alpn.d
new file mode 100644
index 0000000..88abb83
--- /dev/null
+++ b/docs/cmdline-opts/no-alpn.d
@@ -0,0 +1,11 @@
+Long: no-alpn
+Tags: HTTP/2
+Protocols: HTTPS
+Added: 7.36.0
+See-also: no-npn http2
+Requires: TLS
+Help: Disable the ALPN TLS extension
+---
+Disable the ALPN TLS extension. ALPN is enabled by default if libcurl was built
+with an SSL library that supports ALPN. ALPN is used by a libcurl that supports
+HTTP/2 to negotiate HTTP/2 support with the server during https sessions.
diff --git a/docs/cmdline-opts/no-buffer.d b/docs/cmdline-opts/no-buffer.d
new file mode 100644
index 0000000..65a6282
--- /dev/null
+++ b/docs/cmdline-opts/no-buffer.d
@@ -0,0 +1,11 @@
+Long: no-buffer
+Short: N
+Help: Disable buffering of the output stream
+---
+Disables the buffering of the output stream. In normal work situations, curl
+will use a standard buffered output stream that will have the effect that it
+will output the data in chunks, not necessarily exactly when the data arrives.
+Using this option will disable that buffering.
+
+Note that this is the negated option name documented. You can thus use
+--buffer to enforce the buffering.
diff --git a/docs/cmdline-opts/no-keepalive.d b/docs/cmdline-opts/no-keepalive.d
new file mode 100644
index 0000000..7eb3d63
--- /dev/null
+++ b/docs/cmdline-opts/no-keepalive.d
@@ -0,0 +1,8 @@
+Long: no-keepalive
+Help: Disable TCP keepalive on the connection
+---
+Disables the use of keepalive messages on the TCP connection. curl otherwis
+enables them by default.
+
+Note that this is the negated option name documented. You can thus use
+--keepalive to enforce keepalive.
diff --git a/docs/cmdline-opts/no-npn.d b/docs/cmdline-opts/no-npn.d
new file mode 100644
index 0000000..ab0f6de
--- /dev/null
+++ b/docs/cmdline-opts/no-npn.d
@@ -0,0 +1,12 @@
+Long: no-npn
+Tags: Versions HTTP/2
+Protocols: HTTPS
+Added: 7.36.0
+Mutexed:
+See-also: no-alpn http2
+Requires: TLS
+Help: Disable the NPN TLS extension
+---
+Disable the NPN TLS extension. NPN is enabled by default if libcurl was built
+with an SSL library that supports NPN. NPN is used by a libcurl that supports
+HTTP/2 to negotiate HTTP/2 support with the server during https sessions.
diff --git a/docs/cmdline-opts/no-sessionid.d b/docs/cmdline-opts/no-sessionid.d
new file mode 100644
index 0000000..397a158
--- /dev/null
+++ b/docs/cmdline-opts/no-sessionid.d
@@ -0,0 +1,13 @@
+Long: no-sessionid
+Help: Disable SSL session-ID reusing
+Protocols: TLS
+Added: 7.16.0
+---
+Disable curl's use of SSL session-ID caching.  By default all transfers are
+done using the cache. Note that while nothing should ever get hurt by
+attempting to reuse SSL session-IDs, there seem to be broken SSL
+implementations in the wild that may require you to disable this in order for
+you to succeed.
+
+Note that this is the negated option name documented. You can thus use
+--sessionid to enforce session-ID caching.
diff --git a/docs/cmdline-opts/noproxy.d b/docs/cmdline-opts/noproxy.d
new file mode 100644
index 0000000..4f06d9f
--- /dev/null
+++ b/docs/cmdline-opts/noproxy.d
@@ -0,0 +1,11 @@
+Long: noproxy
+Arg: <no-proxy-list>
+Help: List of hosts which do not use proxy
+Added: 7.19.4
+---
+Comma-separated list of hosts which do not use a proxy, if one is specified.
+The only wildcard is a single * character, which matches all hosts, and
+effectively disables the proxy. Each name in this list is matched as either
+a domain which contains the hostname, or the hostname itself. For example,
+local.com would match local.com, local.com:80, and www.local.com, but not
+www.notlocal.com.
diff --git a/docs/cmdline-opts/ntlm-wb.d b/docs/cmdline-opts/ntlm-wb.d
new file mode 100644
index 0000000..7b93384
--- /dev/null
+++ b/docs/cmdline-opts/ntlm-wb.d
@@ -0,0 +1,7 @@
+Long: ntlm-wb
+Help: Use HTTP NTLM authentication with winbind
+Protocols: HTTP
+See-also: ntlm proxy-ntlm
+---
+Enables NTLM much in the style --ntlm does, but hand over the authentication
+to the separate binary ntlmauth application that is executed when needed.
diff --git a/docs/cmdline-opts/ntlm.d b/docs/cmdline-opts/ntlm.d
new file mode 100644
index 0000000..d71cd43
--- /dev/null
+++ b/docs/cmdline-opts/ntlm.d
@@ -0,0 +1,18 @@
+Long: ntlm
+Help: Use HTTP NTLM authentication
+Mutexed: basic negotiated digest anyauth
+See-also: proxy-ntlm
+Protocols: HTTP
+Requires: TLS
+---
+Enables NTLM authentication. The NTLM authentication method was designed by
+Microsoft and is used by IIS web servers. It is a proprietary protocol,
+reverse-engineered by clever people and implemented in curl based on their
+efforts. This kind of behavior should not be endorsed, you should encourage
+everyone who uses NTLM to switch to a public and documented authentication
+method instead, such as Digest.
+
+If you want to enable NTLM for your proxy authentication, then use
+--proxy-ntlm.
+
+If this option is used several times, only the first one is used.
diff --git a/docs/cmdline-opts/oauth2-bearer.d b/docs/cmdline-opts/oauth2-bearer.d
new file mode 100644
index 0000000..adad532
--- /dev/null
+++ b/docs/cmdline-opts/oauth2-bearer.d
@@ -0,0 +1,11 @@
+Long: oauth2-bearer
+Help: OAuth 2 Bearer Token
+Protocols: IMAP POP3 SMTP
+---
+Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token
+is used in conjunction with the user name which can be specified as part of
+the --url or --user options.
+
+The Bearer Token and user name are formatted according to RFC 6750.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/output.d b/docs/cmdline-opts/output.d
new file mode 100644
index 0000000..35f52a2
--- /dev/null
+++ b/docs/cmdline-opts/output.d
@@ -0,0 +1,32 @@
+Long: output
+Arg: <file>
+Short: o
+Help: Write to file instead of stdout
+See-also: remote-name remote-name-all remote-header-name
+---
+Write output to <file> instead of stdout. If you are using {} or [] to fetch
+multiple documents, you can use '#' followed by a number in the <file>
+specifier. That variable will be replaced with the current string for the URL
+being fetched. Like in:
+
+ curl http://{one,two}.example.com -o "file_#1.txt"
+
+or use several variables like:
+
+ curl http://{site,host}.host[1-5].com -o "#1_#2"
+
+You may use this option as many times as the number of URLs you have. For
+example, if you specify two URLs on the same command line, you can use it like
+this:
+
+  curl -o aa example.com -o bb example.net
+
+and the order of the -o options and the URLs doesn't matter, just that the
+first -o is for the first URL and so on, so the above command line can also be
+written as
+
+  curl example.com example.net -o aa -o bb
+
+See also the --create-dirs option to create the local directories
+dynamically. Specifying the output as '-' (a single dash) will force the
+output to be done to stdout.
diff --git a/docs/cmdline-opts/page-header b/docs/cmdline-opts/page-header
new file mode 100644
index 0000000..4ba90f9
--- /dev/null
+++ b/docs/cmdline-opts/page-header
@@ -0,0 +1,138 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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 curl 1 "30 Nov 2014" "Curl 7.40.0" "Curl Manual"
+.SH NAME
+curl \- transfer a URL
+.SH SYNOPSIS
+.B curl [options]
+.I [URL...]
+.SH DESCRIPTION
+.B curl
+is a tool to transfer data from or to a server, using one of the supported
+protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP,
+LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET
+and TFTP). The command is designed to work without user interaction.
+
+curl offers a busload of useful tricks like proxy support, user
+authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer
+resume, Metalink, and more. As you will see below, the number of features will
+make your head spin!
+
+curl is powered by libcurl for all transfer-related features. See
+\fIlibcurl(3)\fP for details.
+.SH URL
+The URL syntax is protocol-dependent. You'll find a detailed description in
+RFC 3986.
+
+You can specify multiple URLs or parts of URLs by writing part sets within
+braces as in:
+
+  http://site.{one,two,three}.com
+
+or you can get sequences of alphanumeric series by using [] as in:
+
+  ftp://ftp.example.com/file[1-100].txt
+
+  ftp://ftp.example.com/file[001-100].txt    (with leading zeros)
+
+  ftp://ftp.example.com/file[a-z].txt
+
+Nested sequences are not supported, but you can use several ones next to each
+other:
+
+  http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html
+
+You can specify any amount of URLs on the command line. They will be fetched
+in a sequential manner in the specified order.
+
+You can specify a step counter for the ranges to get every Nth number or
+letter:
+
+  http://example.com/file[1-100:10].txt
+
+  http://example.com/file[a-z:2].txt
+
+When using [] or {} sequences when invoked from a command line prompt, you
+probably have to put the full URL within double quotes to avoid the shell from
+interfering with it. This also goes for other characters treated special, like
+for example '&', '?' and '*'.
+
+Provide the IPv6 zone index in the URL with an escaped percentage sign and the
+interface name. Like in
+
+  http://[fe80::3%25eth0]/
+
+If you specify URL without protocol:// prefix, curl will attempt to guess what
+protocol you might want. It will then default to HTTP but try other protocols
+based on often-used host name prefixes. For example, for host names starting
+with "ftp." curl will assume you want to speak FTP.
+
+curl will do its best to use what you pass to it as a URL. It is not trying to
+validate it as a syntactically correct URL by any means but is instead
+\fBvery\fP liberal with what it accepts.
+
+curl will attempt to re-use connections for multiple file transfers, so that
+getting many files from the same server will not do multiple connects /
+handshakes. This improves speed. Of course this is only done on files
+specified on a single command line and cannot be used between separate curl
+invokes.
+.SH "PROGRESS METER"
+curl normally displays a progress meter during operations, indicating the
+amount of transferred data, transfer speeds and estimated time left, etc. The
+progress meter displays number of bytes and the speeds are in bytes per
+second. The suffixes (k, M, G, T, P) are 1024 based. For example 1k is 1024
+bytes. 1M is 1048576 bytes.
+
+curl displays this data to the terminal by default, so if you invoke curl to
+do an operation and it is about to write data to the terminal, it
+\fIdisables\fP the progress meter as otherwise it would mess up the output
+mixing progress meter and response data.
+
+If you want a progress meter for HTTP POST or PUT requests, you need to
+redirect the response output to a file, using shell redirect (>), -o [file] or
+similar.
+
+It is not the same case for FTP upload as that operation does not spit out
+any response data to the terminal.
+
+If you prefer a progress "bar" instead of the regular meter, --progress-bar is
+your friend.
+.SH OPTIONS
+Options start with one or two dashes. Many of the options require an
+additional value next to them.
+
+The short "single-dash" form of the options, -d for example, may be used with
+or without a space between it and its value, although a space is a recommended
+separator. The long "double-dash" form, --data for example, requires a space
+between it and its value.
+
+Short version options that don't need any additional values can be used
+immediately next to each other, like for example you can specify all the
+options -O, -L and -v at once as -OLv.
+
+In general, all boolean options are enabled with --\fBoption\fP and yet again
+disabled with --\fBno-\fPoption. That is, you use the exact same option name
+but prefix it with "no-". However, in this list we mostly only list and show
+the --option version of them. (This concept with --no options was added in
+7.19.0. Previously most options were toggled on/off on repeated use of the
+same command line option.)
diff --git a/docs/cmdline-opts/pass.d b/docs/cmdline-opts/pass.d
new file mode 100644
index 0000000..2639cb9
--- /dev/null
+++ b/docs/cmdline-opts/pass.d
@@ -0,0 +1,8 @@
+Long: pass
+Arg: <phrase>
+Help: Pass phrase for the private key
+Protocols: SSH TLS
+---
+Passphrase for the private key
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/path-as-is.d b/docs/cmdline-opts/path-as-is.d
new file mode 100644
index 0000000..946e2f0
--- /dev/null
+++ b/docs/cmdline-opts/path-as-is.d
@@ -0,0 +1,7 @@
+Long: path-as-is
+Help: Do not squash .. sequences in URL path
+Added: 7.42.0
+---
+Tell curl to not handle sequences of /../ or /./ in the given URL
+path. Normally curl will squash or merge them according to standards but with
+this option set you tell it not to do that.
diff --git a/docs/cmdline-opts/pinnedpubkey.d b/docs/cmdline-opts/pinnedpubkey.d
new file mode 100644
index 0000000..0657e6e
--- /dev/null
+++ b/docs/cmdline-opts/pinnedpubkey.d
@@ -0,0 +1,27 @@
+Long: pinnedpubkey
+Arg: <hashes>
+Help: FILE/HASHES Public key to verify peer against
+Protocols: TLS
+---
+Tells curl to use the specified public key file (or hashes) to verify the
+peer. This can be a path to a file which contains a single public key in PEM
+or DER format, or any number of base64 encoded sha256 hashes preceded by
+\'sha256//\' and separated by \';\'
+
+When negotiating a TLS or SSL connection, the server sends a certificate
+indicating its identity. A public key is extracted from this certificate and
+if it does not exactly match the public key provided to this option, curl will
+abort the connection before sending or receiving any data.
+
+PEM/DER support:
+  7.39.0: OpenSSL, GnuTLS and GSKit
+  7.43.0: NSS and wolfSSL/CyaSSL
+  7.47.0: mbedtls
+  7.49.0: PolarSSL
+sha256 support:
+  7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL.
+  7.47.0: mbedtls
+  7.49.0: PolarSSL
+Other SSL backends not supported.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/post301.d b/docs/cmdline-opts/post301.d
new file mode 100644
index 0000000..edcaf87
--- /dev/null
+++ b/docs/cmdline-opts/post301.d
@@ -0,0 +1,11 @@
+Long: post301
+Help: Do not switch to GET after following a 301
+Protocols: HTTP
+See-also: post302 post303 location
+Added: 7.17.1
+---
+Tells curl to respect RFC 7230/6.4.2 and not convert POST requests into GET
+requests when following a 301 redirection. The non-RFC behaviour is ubiquitous
+in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using --location.
diff --git a/docs/cmdline-opts/post302.d b/docs/cmdline-opts/post302.d
new file mode 100644
index 0000000..6ea5f09
--- /dev/null
+++ b/docs/cmdline-opts/post302.d
@@ -0,0 +1,11 @@
+Long: post302
+Help: Do not switch to GET after following a 302
+Protocols: HTTP
+See-also: post301 post303 location
+Added: 7.19.1
+---
+Tells curl to respect RFC 7230/6.4.2 and not convert POST requests into GET
+requests when following a 302 redirection. The non-RFC behaviour is ubiquitous
+in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using --location.
diff --git a/docs/cmdline-opts/post303.d b/docs/cmdline-opts/post303.d
new file mode 100644
index 0000000..8b36c82
--- /dev/null
+++ b/docs/cmdline-opts/post303.d
@@ -0,0 +1,11 @@
+Long: post303
+Help: Do not switch to GET after following a 303
+Protocols: HTTP
+See-also: post302 post301 location
+Added: 7.26.0
+---
+Tells curl to respect RFC 7230/6.4.2 and not convert POST requests into GET
+requests when following a 303 redirection. The non-RFC behaviour is ubiquitous
+in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using --location.
diff --git a/docs/cmdline-opts/progress-bar.d b/docs/cmdline-opts/progress-bar.d
new file mode 100644
index 0000000..360690c
--- /dev/null
+++ b/docs/cmdline-opts/progress-bar.d
@@ -0,0 +1,11 @@
+Short: #
+Long: progress-bar
+Help: Disable the ALPN TLS extension
+---
+Make curl display transfer progress as a simple progress bar instead of the
+standard, more informational, meter.
+
+This progress bar draws a single line of '#' characters across the screen and
+shows a percentage if the transfer size is known. For transfers without a
+known size, it will instead output one '#' character for every 1024 bytes
+transferred.
diff --git a/docs/cmdline-opts/proto-default.d b/docs/cmdline-opts/proto-default.d
new file mode 100644
index 0000000..ccc3b85
--- /dev/null
+++ b/docs/cmdline-opts/proto-default.d
@@ -0,0 +1,18 @@
+Long: proto-default
+Help: Use PROTOCOL for any URL missing a scheme
+Arg: <protocol>
+Added: 7.45.0
+---
+Tells curl to use \fIprotocol\fP for any URL missing a scheme name.
+
+Example:
+
+ curl --proto-default https ftp.mozilla.org
+
+An unknown or unsupported protocol causes error
+\fICURLE_UNSUPPORTED_PROTOCOL\fP (1).
+
+This option does not change the default proxy protocol (http).
+
+Without this option curl would make a guess based on the host, see --url for
+details.
diff --git a/docs/cmdline-opts/proto-redir.d b/docs/cmdline-opts/proto-redir.d
new file mode 100644
index 0000000..c9eeeab
--- /dev/null
+++ b/docs/cmdline-opts/proto-redir.d
@@ -0,0 +1,17 @@
+Long: proto-redir
+Arg: <protocols>
+Help: Enable/disable PROTOCOLS on redirect
+Added: 7.20.2
+---
+Tells curl to limit what protocols it may use on redirect. Protocols denied by
+--proto are not overridden by this option. See --proto for how protocols are
+represented.
+
+Example, allow only HTTP and HTTPS on redirect:
+
+ curl --proto-redir -all,http,https http://example.com
+
+By default curl will allow all protocols on redirect except several disabled
+for security reasons: Since 7.19.4 FILE and SCP are disabled, and since 7.40.0
+SMB and SMBS are also disabled. Specifying \fIall\fP or \fI+all\fP enables all
+protocols on redirect, including those disabled for security.
diff --git a/docs/cmdline-opts/proto.d b/docs/cmdline-opts/proto.d
new file mode 100644
index 0000000..1513fdc
--- /dev/null
+++ b/docs/cmdline-opts/proto.d
@@ -0,0 +1,43 @@
+Long: proto
+Arg: <protocols>
+Help: Enable/disable PROTOCOLS
+See-also: proto-redir proto-default
+Added: 7.20.2
+---
+Tells curl to limit what protocols it may use in the transfer. Protocols are
+evaluated left to right, are comma separated, and are each a protocol name or
+'all', optionally prefixed by zero or more modifiers. Available modifiers are:
+.RS
+.TP 3
+.B +
+Permit this protocol in addition to protocols already permitted (this is
+the default if no modifier is used).
+.TP
+.B -
+Deny this protocol, removing it from the list of protocols already permitted.
+.TP
+.B =
+Permit only this protocol (ignoring the list already permitted), though
+subject to later modification by subsequent entries in the comma separated
+list.
+.RE
+.IP
+For example:
+.RS
+.TP 15
+.B --proto -ftps
+uses the default protocols, but disables ftps
+.TP
+.B  --proto -all,https,+http
+only enables http and https
+.TP
+.B --proto =http,https
+also only enables http and https
+.RE
+
+Unknown protocols produce a warning. This allows scripts to safely rely on
+being able to disable potentially dangerous protocols, without relying upon
+support for that protocol being built into curl to avoid an error.
+
+This option can be used multiple times, in which case the effect is the same
+as concatenating the protocols into one instance of the option.
diff --git a/docs/cmdline-opts/proxy-header.d b/docs/cmdline-opts/proxy-header.d
new file mode 100644
index 0000000..1ef696b
--- /dev/null
+++ b/docs/cmdline-opts/proxy-header.d
@@ -0,0 +1,20 @@
+Long: proxy-header
+Arg: <header>
+Help: Pass custom header LINE to proxy
+Protocols: HTTP
+Added: 7.37.0
+---
+Extra header to include in the request when sending HTTP to a proxy. You may
+specify any number of extra headers. This is the equivalent option to --header
+but is for proxy communication only like in CONNECT requests when you want a
+separate header sent to the proxy to what is sent to the actual remote host.
+
+curl will make sure that each header you add/replace is sent with the proper
+end-of-line marker, you should thus \fBnot\fP add that as a part of the header
+content: do not add newlines or carriage returns, they will only mess things
+up for you.
+
+Headers specified with this option will not be included in requests that curl
+knows will not be sent to a proxy.
+
+This option can be used multiple times to add/replace/remove multiple headers.
diff --git a/docs/cmdline-opts/proxytunnel.d b/docs/cmdline-opts/proxytunnel.d
new file mode 100644
index 0000000..3328dab
--- /dev/null
+++ b/docs/cmdline-opts/proxytunnel.d
@@ -0,0 +1,9 @@
+Long: proxytunnel
+Help: Operate through a 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.
diff --git a/docs/cmdline-opts/referer.d b/docs/cmdline-opts/referer.d
new file mode 100644
index 0000000..dbecd78
--- /dev/null
+++ b/docs/cmdline-opts/referer.d
@@ -0,0 +1,12 @@
+Long: referer
+Protocols: HTTP
+Help: Referer URL
+See-also: user-agent header
+---
+Sends the "Referrer Page" information to the HTTP server. This can also be set
+with the --header flag of course.  When used with --location you can append
+";auto" to the --referer URL to make curl automatically set the previous URL
+when it follows a Location: header. The \&";auto" string can be used alone,
+even if you don't set an initial --referer.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/remote-header-name.d b/docs/cmdline-opts/remote-header-name.d
new file mode 100644
index 0000000..771b6d4
--- /dev/null
+++ b/docs/cmdline-opts/remote-header-name.d
@@ -0,0 +1,19 @@
+Long: remote-header-name
+Short: J
+Protocols: HTTP
+Help: Use the header-provided filename
+---
+This option tells the --remote-name option to use the server-specified
+Content-Disposition filename instead of extracting a filename from the URL.
+
+If the server specifies a file name and a file with that name already exists
+in the current working directory it will not be overwritten and an error will
+occur. If the server doesn't specify a file name then this option has no
+effect.
+
+There's no attempt to decode %-sequences (yet) in the provided file name, so
+this option may provide you with rather unexpected file names.
+
+\fBWARNING\fP: Exercise judicious use of this option, especially on Windows. A
+rogue server could send you the name of a DLL or other file that could possibly
+be loaded automatically by Windows or some third party software.
diff --git a/docs/cmdline-opts/remote-name.d b/docs/cmdline-opts/remote-name.d
new file mode 100644
index 0000000..9fed64b
--- /dev/null
+++ b/docs/cmdline-opts/remote-name.d
@@ -0,0 +1,21 @@
+Long: remote-name
+Short: O
+Help: Write output to a file named as the remote file
+---
+Write output to a local file named like the remote file we get. (Only the file
+part of the remote file is used, the path is cut off.)
+
+The file will be saved in the current working directory. If you want the file
+saved in a different directory, make sure you change the current working
+directory before invoking curl with this option.
+
+The remote file name to use for saving is extracted from the given URL,
+nothing else, and if it already exists it will be overwritten. If you want the
+server to be able to choose the file name refer to --remote-header-name which
+can be used in addition to this option. If the server chooses a file name and
+that name already exists it will not be overwritten.
+
+There is no URL decoding done on the file name. If it has %20 or other URL
+encoded parts of the name, they will end up as-is as file name.
+
+You may use this option as many times as the number of URLs you have.
diff --git a/docs/cmdline-opts/sslv2.d b/docs/cmdline-opts/sslv2.d
new file mode 100644
index 0000000..67d2b85
--- /dev/null
+++ b/docs/cmdline-opts/sslv2.d
@@ -0,0 +1,13 @@
+Short: 2
+Long: sslv2
+Tags: Versions
+Protocols: SSL
+Added:
+Mutexed: sslv3 tlsv1 tlsv1.1 tlsv1.2
+Requires: TLS
+See-also: http1.1 http2
+Help: Use SSLv2
+---
+Forces curl to use SSL version 2 when negotiating with a remote SSL
+server. Sometimes curl is built without SSLv2 support. SSLv2 is widely
+considered insecure (see RFC 6176).
diff --git a/docs/cmdline-opts/sslv3.d b/docs/cmdline-opts/sslv3.d
new file mode 100644
index 0000000..101ad10
--- /dev/null
+++ b/docs/cmdline-opts/sslv3.d
@@ -0,0 +1,13 @@
+Short: 3
+Long: sslv3
+Tags: Versions
+Protocols: SSL
+Added:
+Mutexed: sslv2 tlsv1 tlsv1.1 tlsv1.2
+Requires: TLS
+See-also: http1.1 http2
+Help: Use SSLv3
+---
+Forces curl to use SSL version 3 when negotiating with a remote SSL
+server. Sometimes curl is built without SSLv3 support. SSLv3 is widely
+considered insecure (see RFC 7568).
diff --git a/docs/cmdline-opts/tlsv1.d b/docs/cmdline-opts/tlsv1.d
new file mode 100644
index 0000000..d96fd1c
--- /dev/null
+++ b/docs/cmdline-opts/tlsv1.d
@@ -0,0 +1,14 @@
+Short: 1
+Long: tlsv1
+Tags: Versions
+Protocols: SSL
+Added:
+Mutexed: tlsv1.1 tlsv1.2
+Requires: TLS
+See-also: http1.1 http2
+Help: Use TLSv1.0 or greater
+---
+Forces curl to use TLS version 1.x when negotiating with a remote TLS server.
+You can use options --tlsv1.0, --tlsv1.1, --tlsv1.2, and --tlsv1.3 to control
+the TLS version more precisely (if the SSL backend in use supports such a
+level of control).
diff --git a/docs/cmdline-opts/use-ascii.d b/docs/cmdline-opts/use-ascii.d
new file mode 100644
index 0000000..da307dc
--- /dev/null
+++ b/docs/cmdline-opts/use-ascii.d
@@ -0,0 +1,8 @@
+Short: B
+Long: use-ascii
+Help: Use ASCII/text transfer
+Protocols: FTP LDAP
+---
+Enable ASCII transfer. For FTP, this can also be enforced by using an URL that
+ends with ";type=A". This option causes data sent to stdout to be in text mode
+for win32 systems.
diff --git a/docs/cmdline-opts/user-agent.d b/docs/cmdline-opts/user-agent.d
new file mode 100644
index 0000000..c98619d
--- /dev/null
+++ b/docs/cmdline-opts/user-agent.d
@@ -0,0 +1,12 @@
+Short: A
+Long: user-agent
+Arg: <name>
+Help: Send User-Agent <name> to server
+Protocols: HTTP
+---
+
+Specify the User-Agent string to send to the HTTP server. To encode blanks in
+the string, surround the string with single quote marks. This can also be set
+with the --header option of course.
+
+If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/verbose.d b/docs/cmdline-opts/verbose.d
new file mode 100644
index 0000000..5d33521
--- /dev/null
+++ b/docs/cmdline-opts/verbose.d
@@ -0,0 +1,19 @@
+Short: v
+Long: verbose
+Mutexed: trace trace-ascii
+Help: Make the operation more talkative
+See-also: include
+---
+Makes curl verbose during the operation. Useful for debugging and seeing
+what's going on "under the hood". A line starting with '>' means "header data"
+sent by curl, '<' means "header data" received by curl that is hidden in
+normal cases, and a line starting with '*' means additional info provided by
+curl.
+
+If you only want HTTP headers in the output, --include might be the option
+you're looking for.
+
+If you think this option still doesn't give you enough details, consider using
+--trace or --trace-ascii instead.
+
+Use --silent to make curl really quiet.
diff --git a/docs/curl.1 b/docs/curl.1
index c573ff9..5168031 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -176,9 +176,9 @@
 .IP "-1, --tlsv1"
 (SSL)
 Forces curl to use TLS version 1.x when negotiating with a remote TLS server.
-You can use options \fI--tlsv1.0\fP, \fI--tlsv1.1\fP, and \fI--tlsv1.2\fP to
-control the TLS version more precisely (if the SSL backend in use supports such
-a level of control).
+You can use options \fI--tlsv1.0\fP, \fI--tlsv1.1\fP, \fI--tlsv1.2\fP, and
+\fI--tlsv1.3\fP to control the TLS version more precisely (if the SSL backend
+in use supports such a level of control).
 .IP "-2, --sslv2"
 (SSL) Forces curl to use SSL version 2 when negotiating with a remote SSL
 server. Sometimes curl is built without SSLv2 support. SSLv2 is widely
@@ -356,7 +356,7 @@
 stripped out. If you don't want the @ character to have a special
 interpretation use \fI--data-raw\fP instead.
 .IP "-D, --dump-header <file>"
-Write the protocol headers to the specified file.
+Write the received protocol headers to the specified file.
 
 This option is handy to use when you want to store the headers that an HTTP
 site sends to you. Cookies from the headers could then be read in a second
@@ -520,7 +520,7 @@
 recognized as password delimiter.  If the nickname contains "\\", it needs to
 be escaped as "\\\\" so that it is not recognized as an escape character.
 
-(iOS and Mac OS X only) If curl is built against Secure Transport, then the
+(iOS and macOS only) If curl is built against Secure Transport, then the
 certificate string can either be the name of a certificate/private key in the
 system or user keychain, or the path to a PKCS#12-encoded certificate and
 private key. If you want to use a file from the current directory, please
@@ -569,6 +569,12 @@
 If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
 (libnsspem.so) needs to be available for this option to work properly.
 
+(iOS and macOS only) If curl is built against Secure Transport, then this
+option is supported for backward compatibility with other SSL engines, but it
+should not be set. If the option is not set, then curl will use the
+certificates in the system and user Keychain to verify the peer, which is the
+preferred method of verifying the peer's certificate chain.
+
 If this option is used several times, the last one will be used.
 .IP "--capath <CA certificate directory>"
 (SSL) Tells curl to use the specified certificate directory to verify the
@@ -614,6 +620,23 @@
 
 This is currently only implemented in the OpenSSL, GnuTLS and NSS backends.
 (Added in 7.41.0)
+.IP "--fail-early"
+Fail and exit on first detected error.
+
+When curl is used to do multiple transfers on the command line, it will
+attempt to operate on each given URL, one by one. By default, it will ignore
+errors if there are more URLs given and the last URL's success will determine
+the error code curl returns. So early failures will be "hidden" by subsequent
+successful transfers.
+
+Using this option, curl will instead return an error on the first transfers
+that fails, independent on the amount of more URLs that are given on the
+command line. This way, no transfer failures go undetected by scripts and
+similar.
+
+This option will apply for all given URLs even if you use \fI--next\fP.
+
+(Added in 7.52.0)
 .IP "--false-start"
 
 (SSL) Tells curl to use false start during the TLS handshake. False start is a
@@ -1018,10 +1041,6 @@
 Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
 megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
 
-The given rate is the average speed counted during the entire transfer. It
-means that curl might use higher transfer speeds in short bursts, but over
-time it uses no more than the given rate.
-
 If you also use the \fI-Y, --speed-limit\fP option, that option will take
 precedence and might cripple the rate-limiting slightly, to help keeping the
 speed-limit logic working.
@@ -1237,7 +1256,17 @@
 
   curl http://{site,host}.host[1-5].com -o "#1_#2"
 
-You may use this option as many times as the number of URLs you have.
+You may use this option as many times as the number of URLs you have. For
+example, if you specify two URLs on the same command line, you can use it like
+this:
+
+  curl -o aa example.com -o bb example.net
+
+and the order of the -o options and the URLs doesn't matter, just that the
+first -o is for the first URL and so on, so the above command line can also be
+written as
+
+  curl example.com example.net -o aa -o bb
 
 See also the \fI--create-dirs\fP option to create the local directories
 dynamically. Specifying the output as '-' (a single dash) will force the
@@ -1352,10 +1381,9 @@
 a redirection. This option is meaningful only when using \fI-L, --location\fP
 (Added in 7.26.0)
 .IP "--proto <protocols>"
-Tells curl to use the listed protocols for its initial retrieval. Protocols
-are evaluated left to right, are comma separated, and are each a protocol
-name or 'all', optionally prefixed by zero or more modifiers. Available
-modifiers are:
+Tells curl to limit what protocols it may use in the transfer. Protocols are
+evaluated left to right, are comma separated, and are each a protocol name or
+'all', optionally prefixed by zero or more modifiers. Available modifiers are:
 .RS
 .TP 3
 .B +
@@ -1412,8 +1440,9 @@
 
 (Added in 7.45.0)
 .IP "--proto-redir <protocols>"
-Tells curl to use the listed protocols on redirect. See --proto for how
-protocols are represented.
+Tells curl to limit what protocols it may use on redirect. Protocols denied by
+--proto are not overridden by this option. See \fI--proto\fP for how protocols
+are represented.
 
 Example:
 
@@ -1439,6 +1468,33 @@
 .IP "--proxy-digest"
 Tells curl to use HTTP Digest authentication when communicating with the given
 proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
+.IP "--proxy-cacert <CA certificate>"
+(SSL) Same as --cacert but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-capath <CA certificate directory>"
+(SSL) Same as --capath but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-cert <certificate[:password]>"
+(SSL) Same as \fI--cert\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-cert-type <type>"
+(SSL) Same as \fI--cert-type\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-ciphers <list of ciphers>"
+(SSL) Same as \fI--ciphers\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-crlfile <file>"
+(HTTPS) Same as \fI--crlfile\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-insecure"
+(SSL) Same as \fI--insecure\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-key <key>"
+(SSL) Same as \fI--key\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-key-type <type>"
+(SSL) Same as \fI--key-type\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
 .IP "--proxy-negotiate"
 Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating
 with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate (SPNEGO)
@@ -1446,11 +1502,35 @@
 .IP "--proxy-ntlm"
 Tells curl to use HTTP NTLM authentication when communicating with the given
 proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host.
+.IP "--proxy-pass <phrase>"
+(SSL) Same as \fI--pass\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
 .IP "--proxy-service-name <servicename>"
 This option allows you to change the service name for proxy negotiation.
 
 Examples: --proxy-negotiate proxy-name \fI--proxy-service-name\fP sockd would use
 sockd/proxy-name.  (Added in 7.43.0).
+.IP "--proxy-ssl-allow-beast"
+(SSL) Same as \fI--ssl-allow-beast\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-sslv2"
+(SSL) Same as \fI--sslv2\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-sslv3"
+(SSL) Same as \fI--sslv3\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-tlsauthtype <authtype>"
+Same as \fI--tlsauthtype\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-tlspassword <password>"
+Same as \fI--tlspassword\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-tlsuser <user>"
+Same as \fI--tlsuser\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
+.IP "--proxy-tlsv1"
+(SSL) Same as \fI--tlsv1\fP but used in HTTPS proxy context.
+(Added in 7.52.0)
 .IP "--proxy1.0 <proxyhost[:port]>"
 Use the specified HTTP 1.0 proxy. If the port number is not specified, it is
 assumed at port 1080.
@@ -1608,6 +1688,10 @@
 retries. (Added in 7.12.3)
 
 If this option is used several times, the last one will be used.
+.IP "--retry-connrefused"
+In addition to the other conditions, consider ECONNREFUSED as a transient
+error too for \fI--retry\fP. This option is used together with
+\fI--retry\fP. (Added in 7.52.0)
 .IP "--retry-delay <seconds>"
 Make curl sleep this amount of time before each retry when a transfer has
 failed with a transient error (it changes the default backoff time algorithm
@@ -1762,6 +1846,11 @@
 or even
 
 curl -T "img[1-1000].png" ftp://ftp.example.com/upload/
+
+When uploading to an SMTP server: the uploaded data is assumed to be RFC 5322
+formatted. It has to feature the necessary set of headers and mail body
+formatted correctly by the user as curl will not transcode nor encode it
+further in any way.
 .IP "--tcp-nodelay"
 Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
 details about this option. (Added in 7.11.2)
@@ -1808,6 +1897,10 @@
 (SSL)
 Forces curl to use TLS version 1.2 when negotiating with a remote TLS server.
 (Added in 7.34.0)
+.IP "--tlsv1.3"
+(SSL)
+Forces curl to use TLS version 1.3 when negotiating with a remote TLS server.
+(Added in 7.52.0)
 .IP "--tr-encoding"
 (HTTP) Request a compressed Transfer-Encoding response using one of the
 algorithms curl supports, and uncompress the data while receiving it.
@@ -1816,7 +1909,8 @@
 .IP "--trace <file>"
 Enables a full trace dump of all incoming and outgoing data, including
 descriptive information, to the given output file. Use "-" as filename to have
-the output sent to stdout.
+the output sent to stdout. Use "%" as filename to have the output sent to
+stderr.
 
 This option overrides previous uses of \fI-v, --verbose\fP or
 \fI--trace-ascii\fP.
@@ -1974,6 +2068,9 @@
 .B remote_port
 The remote port number of the most recently done connection (Added in 7.29.0)
 .TP
+.B scheme
+The URL scheme (sometimes called protocol) that was effectively used (Added in 7.52.0)
+.TP
 .B size_download
 The total amount of bytes that were downloaded.
 .TP
@@ -2252,7 +2349,7 @@
 .IP 7
 Failed to connect to host.
 .IP 8
-FTP weird server reply. The server sent data curl couldn't parse.
+Weird server reply. The server sent data curl couldn't parse.
 .IP 9
 FTP access denied. The server denied login or denied access to the particular
 resource or directory you wanted to reach. Most often you tried to change to a
diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c
index aa1862e..4555291 100644
--- a/docs/examples/10-at-a-time.c
+++ b/docs/examples/10-at-a-time.c
@@ -86,7 +86,7 @@
 };
 
 #define MAX 10 /* number of simultaneous transfers */
-#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
+#define CNT sizeof(urls)/sizeof(char *) /* total number of transfers to do */
 
 static size_t cb(char *d, size_t n, size_t l, void *p)
 {
diff --git a/docs/examples/Makefile.netware b/docs/examples/Makefile.netware
index 2d85e73..9fe9db4 100644
--- a/docs/examples/Makefile.netware
+++ b/docs/examples/Makefile.netware
@@ -60,7 +60,7 @@
 TARGET  = examples
 VERSION	= $(LIBCURL_VERSION)
 COPYR	= Copyright (C) $(LIBCURL_COPYRIGHT_STR)
-DESCR	= cURL ($(LIBARCH))
+DESCR	= curl ($(LIBARCH))
 MTSAFE	= YES
 STACK	= 8192
 SCREEN	= Example Program
diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c
index b1367de..1c9f965 100644
--- a/docs/examples/anyauthput.c
+++ b/docs/examples/anyauthput.c
@@ -147,13 +147,13 @@
     curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
 
     /* which file to upload */
-    curl_easy_setopt(curl, CURLOPT_READDATA, (void*)&hd);
+    curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&hd);
 
     /* set the ioctl function */
     curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
 
     /* pass the file descriptor to the ioctl callback as well */
-    curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)&hd);
+    curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void *)&hd);
 
     /* enable "uploading" (which means PUT when doing HTTP) */
     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c
index bba8c72..ace58e4 100644
--- a/docs/examples/cacertinmem.c
+++ b/docs/examples/cacertinmem.c
@@ -34,12 +34,12 @@
   return (nmemb*size);
 }
 
-static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
+static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
 {
-  X509_STORE * store;
-  X509 * cert=NULL;
-  BIO * bio;
-  char * mypem = /* www.cacert.org */
+  X509_STORE *store;
+  X509 *cert=NULL;
+  BIO *bio;
+  char *mypem = /* www.cacert.org */
     "-----BEGIN CERTIFICATE-----\n"\
     "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
     "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
@@ -107,7 +107,7 @@
 
 int main(void)
 {
-  CURL * ch;
+  CURL *ch;
   CURLcode rv;
 
   rv=curl_global_init(CURL_GLOBAL_ALL);
diff --git a/docs/examples/curlx.c b/docs/examples/curlx.c
index 155da23..e0d7099 100644
--- a/docs/examples/curlx.c
+++ b/docs/examples/curlx.c
@@ -133,14 +133,14 @@
 /* This is a context that we pass to all callbacks */
 
 typedef struct sslctxparm_st {
-  unsigned char * p12file;
-  const char * pst;
-  PKCS12 * p12;
-  EVP_PKEY * pkey;
-  X509 * usercert;
+  unsigned char *p12file;
+  const char *pst;
+  PKCS12 *p12;
+  EVP_PKEY *pkey;
+  X509 *usercert;
   STACK_OF(X509) * ca;
-  CURL * curl;
-  BIO * errorbio;
+  CURL *curl;
+  BIO *errorbio;
   int accesstype;
   int verbose;
 
@@ -196,7 +196,7 @@
     BIO_printf(p->errorbio, "entering ssl_app_verify_callback\n");
 
   if((ok= X509_verify_cert(ctx)) && ctx->cert) {
-    unsigned char * accessinfo;
+    unsigned char *accessinfo;
     if(p->verbose > 1)
       X509_print_ex(p->errorbio, ctx->cert, 0, 0);
 
@@ -228,10 +228,10 @@
    - an application verification callback (the function above)
 */
 
-static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm)
+static CURLcode sslctxfun(CURL *curl, void *sslctx, void *parm)
 {
-  sslctxparm * p = (sslctxparm *) parm;
-  SSL_CTX * ctx = (SSL_CTX *) sslctx;
+  sslctxparm *p = (sslctxparm *) parm;
+  SSL_CTX *ctx = (SSL_CTX *) sslctx;
 
   if(!SSL_CTX_use_certificate(ctx, p->usercert)) {
     BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n");
@@ -270,24 +270,24 @@
   BIO* in=NULL;
   BIO* out=NULL;
 
-  char * outfile = NULL;
-  char * infile = NULL;
+  char *outfile = NULL;
+  char *infile = NULL;
 
   int tabLength=100;
   char *binaryptr;
-  char* mimetype;
-  char* mimetypeaccept=NULL;
-  char* contenttype;
-  const char** pp;
-  unsigned char* hostporturl = NULL;
-  BIO * p12bio;
+  char *mimetype;
+  char *mimetypeaccept=NULL;
+  char *contenttype;
+  const char **pp;
+  unsigned char *hostporturl = NULL;
+  BIO *p12bio;
   char **args = argv + 1;
-  unsigned char * serverurl;
+  unsigned char *serverurl;
   sslctxparm p;
   char *response;
 
   CURLcode res;
-  struct curl_slist * headers=NULL;
+  struct curl_slist *headers=NULL;
   int badarg=0;
 
   binaryptr = malloc(tabLength);
diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c
index 118f152..52f6828 100644
--- a/docs/examples/evhiperfifo.c
+++ b/docs/examples/evhiperfifo.c
@@ -86,7 +86,7 @@
   struct ev_timer timer_event;
   CURLM *multi;
   int still_running;
-  FILE* input;
+  FILE *input;
 } GlobalInfo;
 
 
@@ -243,7 +243,8 @@
 
 
 /* Assign information to a SockInfo structure */
-static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
+                    GlobalInfo *g)
 {
   printf("%s  \n", __PRETTY_FUNCTION__);
 
diff --git a/docs/examples/fileupload.c b/docs/examples/fileupload.c
index 363fae6..6b05c4c 100644
--- a/docs/examples/fileupload.c
+++ b/docs/examples/fileupload.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,16 +37,12 @@
   FILE *fd;
 
   fd = fopen("debugit", "rb"); /* open file to upload */
-  if(!fd) {
-
+  if(!fd)
     return 1; /* can't continue */
-  }
 
   /* to get the file size */
-  if(fstat(fileno(fd), &file_info) != 0) {
-
+  if(fstat(fileno(fd), &file_info) != 0)
     return 1; /* can't continue */
-  }
 
   curl = curl_easy_init();
   if(curl) {
@@ -86,5 +82,6 @@
     /* always cleanup */
     curl_easy_cleanup(curl);
   }
+  fclose(fd);
   return 0;
 }
diff --git a/docs/examples/fopen.c b/docs/examples/fopen.c
index 71be178..7435264 100644
--- a/docs/examples/fopen.c
+++ b/docs/examples/fopen.c
@@ -84,7 +84,7 @@
 int url_fclose(URL_FILE *file);
 int url_feof(URL_FILE *file);
 size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
-char * url_fgets(char *ptr, size_t size, URL_FILE *file);
+char *url_fgets(char *ptr, size_t size, URL_FILE *file);
 void url_rewind(URL_FILE *file);
 
 /* we use a global one for convenience */
diff --git a/docs/examples/ftpuploadresume.c b/docs/examples/ftpuploadresume.c
index 6415634..8f7f45d 100644
--- a/docs/examples/ftpuploadresume.c
+++ b/docs/examples/ftpuploadresume.c
@@ -36,8 +36,8 @@
 /* The MinGW headers are missing a few Win32 function definitions,
    you shouldn't need this if you use VC++ */
 #if defined(__MINGW32__) && !defined(__MINGW64__)
-int __cdecl _snscanf(const char * input, size_t length,
-                     const char * format, ...);
+int __cdecl _snscanf(const char *input, size_t length,
+                     const char *format, ...);
 #endif
 
 
@@ -77,7 +77,7 @@
 }
 
 
-int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
+int upload(CURL *curlhandle, const char *remotepath, const char *localpath,
            long timeout, long tries)
 {
   FILE *f;
diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c
index 7317a63..c0fbd82 100644
--- a/docs/examples/ghiper.c
+++ b/docs/examples/ghiper.c
@@ -94,7 +94,8 @@
 } SockInfo;
 
 /* Die if we get a bad CURLMcode somewhere */
-static void mcode_or_die(const char *where, CURLMcode code) {
+static void mcode_or_die(const char *where, CURLMcode code)
+{
   if(CURLM_OK != code) {
     const char *s;
     switch (code) {
@@ -206,7 +207,8 @@
 }
 
 /* Assign information to a SockInfo structure */
-static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
+                    GlobalInfo *g)
 {
   GIOCondition kind =
     (act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c
index 98bcafe..dce009c 100644
--- a/docs/examples/hiperfifo.c
+++ b/docs/examples/hiperfifo.c
@@ -82,7 +82,7 @@
   struct event *timer_event;
   CURLM *multi;
   int still_running;
-  FILE* input;
+  FILE *input;
 } GlobalInfo;
 
 
@@ -230,7 +230,8 @@
 
 
 /* Assign information to a SockInfo structure */
-static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
+                    GlobalInfo *g)
 {
   int kind =
      (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
diff --git a/docs/examples/imap-append.c b/docs/examples/imap-append.c
index 3f83289..bbf9fe4 100644
--- a/docs/examples/imap-append.c
+++ b/docs/examples/imap-append.c
@@ -85,6 +85,8 @@
 {
   CURL *curl;
   CURLcode res = CURLE_OK;
+  const char **p;
+  long infilesize;
   struct upload_status upload_ctx;
 
   upload_ctx.lines_read = 0;
@@ -107,6 +109,12 @@
     curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
 
+    infilesize = 0;
+    for(p = payload_text; *p; ++p) {
+      infilesize += (long)strlen(*p);
+    }
+    curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
+
     /* Perform the append */
     res = curl_easy_perform(curl);
 
diff --git a/docs/examples/multi-uv.c b/docs/examples/multi-uv.c
index 51526c8..c022894 100644
--- a/docs/examples/multi-uv.c
+++ b/docs/examples/multi-uv.c
@@ -24,18 +24,12 @@
  * multi_socket API using libuv
  * </DESC>
  */
-/* Example application code using the multi socket interface to download
-   multiple files at once, but instead of using curl_multi_perform and
-   curl_multi_wait, which uses select(), we use libuv.
-   It supports epoll, kqueue, etc. on unixes and fast IO completion ports on
-   Windows, which means, it should be very fast on all platforms..
-
-   Written by Clemens Gruber, based on an outdated example from uvbook and
-   some tests from libuv.
+/* Example application using the multi socket interface to download multiple
+   files in parallel, powered by libuv.
 
    Requires libuv and (of course) libcurl.
 
-   See http://nikhilm.github.com/uvbook/ for more information on libuv.
+   See https://nikhilm.github.com/uvbook/ for more information on libuv.
 */
 
 #include <stdio.h>
@@ -77,7 +71,6 @@
   uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb);
 }
 
-
 void add_download(const char *url, int num)
 {
   char filename[50];
@@ -102,22 +95,28 @@
 
 static void check_multi_info(void)
 {
-  int running_handles;
   char *done_url;
   CURLMsg *message;
   int pending;
+  CURL *easy_handle;
   FILE *file;
 
   while((message = curl_multi_info_read(curl_handle, &pending))) {
     switch(message->msg) {
     case CURLMSG_DONE:
-      curl_easy_getinfo(message->easy_handle, CURLINFO_EFFECTIVE_URL,
-                        &done_url);
-      curl_easy_getinfo(message->easy_handle, CURLINFO_PRIVATE, &file);
+      /* Do not use message data after calling curl_multi_remove_handle() and
+         curl_easy_cleanup(). As per curl_multi_info_read() docs:
+         "WARNING: The data the returned pointer points to will not survive
+         calling curl_multi_cleanup, curl_multi_remove_handle or
+         curl_easy_cleanup." */
+      easy_handle = message->easy_handle;
+
+      curl_easy_getinfo(easy_handle, CURLINFO_EFFECTIVE_URL, &done_url);
+      curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &file);
       printf("%s DONE\n", done_url);
 
-      curl_multi_remove_handle(curl_handle, message->easy_handle);
-      curl_easy_cleanup(message->easy_handle);
+      curl_multi_remove_handle(curl_handle, easy_handle);
+      curl_easy_cleanup(easy_handle);
       if(file) {
         fclose(file);
       }
@@ -135,9 +134,6 @@
   int running_handles;
   int flags = 0;
   curl_context_t *context;
-  char *done_url;
-  CURLMsg *message;
-  int pending;
 
   uv_timer_stop(&timeout);
 
@@ -146,7 +142,7 @@
   if(events & UV_WRITABLE)
     flags |= CURL_CSELECT_OUT;
 
-  context = (curl_context_t *) req;
+  context = (curl_context_t *) req->data;
 
   curl_multi_socket_action(curl_handle, context->sockfd, flags,
                            &running_handles);
@@ -174,22 +170,23 @@
                   void *socketp)
 {
   curl_context_t *curl_context;
-  if(action == CURL_POLL_IN || action == CURL_POLL_OUT) {
-    if(socketp) {
-      curl_context = (curl_context_t *) socketp;
-    }
-    else {
-      curl_context = create_curl_context(s);
-    }
-    curl_multi_assign(curl_handle, s, (void *) curl_context);
-  }
+  int events = 0;
 
   switch(action) {
   case CURL_POLL_IN:
-    uv_poll_start(&curl_context->poll_handle, UV_READABLE, curl_perform);
-    break;
   case CURL_POLL_OUT:
-    uv_poll_start(&curl_context->poll_handle, UV_WRITABLE, curl_perform);
+  case CURL_POLL_INOUT:
+    curl_context = socketp ?
+      (curl_context_t *) socketp : create_curl_context(s);
+
+    curl_multi_assign(curl_handle, s, (void *) curl_context);
+
+    if(action != CURL_POLL_IN)
+      events |= UV_WRITABLE;
+    if(action != CURL_POLL_OUT)
+      events |= UV_READABLE;
+
+    uv_poll_start(&curl_context->poll_handle, events, curl_perform);
     break;
   case CURL_POLL_REMOVE:
     if(socketp) {
@@ -213,7 +210,7 @@
     return 0;
 
   if(curl_global_init(CURL_GLOBAL_ALL)) {
-    fprintf(stderr, "Could not init cURL\n");
+    fprintf(stderr, "Could not init curl\n");
     return 1;
   }
 
diff --git a/docs/examples/opensslthreadlock.c b/docs/examples/opensslthreadlock.c
index eebc42e..6f86c7f 100644
--- a/docs/examples/opensslthreadlock.c
+++ b/docs/examples/opensslthreadlock.c
@@ -52,7 +52,7 @@
 /* This array will store all of the mutexes available to OpenSSL. */
 static MUTEX_TYPE *mutex_buf= NULL;
 
-static void locking_function(int mode, int n, const char * file, int line)
+static void locking_function(int mode, int n, const char *file, int line)
 {
   if(mode & CRYPTO_LOCK)
     MUTEX_LOCK(mutex_buf[n]);
diff --git a/docs/examples/rtsp.c b/docs/examples/rtsp.c
index 63c46e1..bdab395 100644
--- a/docs/examples/rtsp.c
+++ b/docs/examples/rtsp.c
@@ -188,7 +188,7 @@
 
   printf("\nRTSP request %s\n", VERSION_STR);
   printf("    Project web site: http://code.google.com/p/rtsprequest/\n");
-  printf("    Requires cURL V7.20 or greater\n\n");
+  printf("    Requires curl V7.20 or greater\n\n");
 
   /* check command line */
   if((argc != 2) && (argc != 3)) {
@@ -226,7 +226,7 @@
     if(res == CURLE_OK) {
       curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
       CURL *curl;
-      fprintf(stderr, "    cURL V%s loaded\n", data->version);
+      fprintf(stderr, "    curl V%s loaded\n", data->version);
 
       /* initialize this curl session */
       curl = curl_easy_init();
diff --git a/docs/examples/sessioninfo.c b/docs/examples/sessioninfo.c
index 11c87cd..024a0e1 100644
--- a/docs/examples/sessioninfo.c
+++ b/docs/examples/sessioninfo.c
@@ -24,7 +24,7 @@
  * </DESC>
  */
 
-/* Note that this example currently requires cURL to be linked against
+/* Note that this example currently requires curl to be linked against
    GnuTLS (and this program must also be linked against -lgnutls). */
 
 #include <stdio.h>
diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am
index 49acd97..2d51b46 100644
--- a/docs/libcurl/Makefile.am
+++ b/docs/libcurl/Makefile.am
@@ -90,8 +90,8 @@
 
 CLEANFILES = $(HTMLPAGES) $(PDFPAGES) $(TESTS) libcurl-symbols.3
 
-EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) ABI \
-  symbols-in-versions symbols.pl mksymbolsmanpage.pl
+EXTRA_DIST = $(man_MANS) index.html ABI symbols-in-versions symbols.pl  \
+  mksymbolsmanpage.pl
 MAN2HTML= roffit --mandir=. $< >$@
 
 SUFFIXES = .3 .html
diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3
index 9ffcd14..fabc7e9 100644
--- a/docs/libcurl/curl_easy_getinfo.3
+++ b/docs/libcurl/curl_easy_getinfo.3
@@ -104,6 +104,9 @@
 .IP CURLINFO_SSL_VERIFYRESULT
 Certificate verification result.
 See \fICURLINFO_SSL_VERIFYRESULT(3)\fP
+.IP CURLINFO_PROXY_SSL_VERIFYRESULT
+Proxy certificate verification result.
+See \fICURLINFO_PROXY_SSL_VERIFYRESULT(3)\fP
 .IP CURLINFO_SSL_ENGINES
 A list of OpenSSL crypto engines.
 See \fICURLINFO_SSL_ENGINES(3)\fP
@@ -180,6 +183,12 @@
 .IP CURLINFO_RTSP_CSEQ_RECV
 RTSP CSeq last received.
 See \fICURLINFO_RTSP_CSEQ_RECV(3)\fP
+.IP CURLINFO_PROTOCOL
+The protocol used for the connection. (Added in 7.52.0)
+See \fICURLINFO_PROTOCOL(3)\fP
+.IP CURLINFO_SCHEME
+The scheme used for the connection. (Added in 7.52.0)
+See \fICURLINFO_SCHEME(3)\fP
 .SH TIMES
 .nf
 An overview of the six time values available from curl_easy_getinfo()
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 75f1ce4..590a47f 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -144,6 +144,8 @@
 stderr replacement stream. See \fICURLOPT_STDERR(3)\fP
 .IP CURLOPT_FAILONERROR
 Fail on HTTP 4xx errors. \fICURLOPT_FAILONERROR(3)\fP
+.IP CURLOPT_KEEP_SENDING_ON_ERROR
+Keep sending on HTTP >= 300 errors. \fICURLOPT_KEEP_SENDING_ON_ERROR(3)\fP
 .SH NETWORK OPTIONS
 .IP CURLOPT_URL
 URL to work on. See \fICURLOPT_URL(3)\fP
@@ -157,10 +159,14 @@
 Default protocol. See \fICURLOPT_DEFAULT_PROTOCOL(3)\fP
 .IP CURLOPT_PROXY
 Proxy to use. See \fICURLOPT_PROXY(3)\fP
+.IP CURLOPT_SOCKS_PROXY
+Socks proxy to use. See \fICURLOPT_SOCKS_PROXY(3)\fP
 .IP CURLOPT_PROXYPORT
 Proxy port to use. See \fICURLOPT_PROXYPORT(3)\fP
 .IP CURLOPT_PROXYTYPE
 Proxy type. See \fICURLOPT_PROXYTYPE(3)\fP
+.IP CURLOPT_SOCKS_PROXYTYPE
+Socks proxy type. See \fICURLOPT_SOCKS_PROXYTYPE(3)\fP
 .IP CURLOPT_NOPROXY
 Filter out hosts from proxy use. \fICURLOPT_NOPROXY(3)\fP
 .IP CURLOPT_HTTPPROXYTUNNEL
@@ -226,10 +232,16 @@
 HTTP server authentication methods. See \fICURLOPT_HTTPAUTH(3)\fP
 .IP CURLOPT_TLSAUTH_USERNAME
 TLS authentication user name. See \fICURLOPT_TLSAUTH_USERNAME(3)\fP
+.IP CURLOPT_PROXY_TLSAUTH_USERNAME
+Proxy TLS authentication user name. See \fICURLOPT_PROXY_TLSAUTH_USERNAME(3)\fP
 .IP CURLOPT_TLSAUTH_PASSWORD
 TLS authentication password. See \fICURLOPT_TLSAUTH_PASSWORD(3)\fP
+.IP CURLOPT_PROXY_TLSAUTH_PASSWORD
+Proxy TLS authentication password. See \fICURLOPT_PROXY_TLSAUTH_PASSWORD(3)\fP
 .IP CURLOPT_TLSAUTH_TYPE
 TLS authentication methods. See \fICURLOPT_TLSAUTH_TYPE(3)\fP
+.IP CURLOPT_PROXY_TLSAUTH_TYPE
+Proxy TLS authentication methods. See \fICURLOPT_PROXY_TLSAUTH_TYPE(3)\fP
 .IP CURLOPT_PROXYAUTH
 HTTP proxy authentication methods. See \fICURLOPT_PROXYAUTH(3)\fP
 .IP CURLOPT_SASL_IR
@@ -445,14 +457,24 @@
 .SH SSL and SECURITY OPTIONS
 .IP CURLOPT_SSLCERT
 Client cert. See \fICURLOPT_SSLCERT(3)\fP
+.IP CURLOPT_PROXY_SSLCERT
+Proxy client cert. See \fICURLOPT_PROXY_SSLCERT(3)\fP
 .IP CURLOPT_SSLCERTTYPE
 Client cert type.  See \fICURLOPT_SSLCERTTYPE(3)\fP
+.IP CURLOPT_PROXY_SSLCERTTYPE
+Proxy client cert type.  See \fICURLOPT_PROXY_SSLCERTTYPE(3)\fP
 .IP CURLOPT_SSLKEY
 Client key. See \fICURLOPT_SSLKEY(3)\fP
+.IP CURLOPT_PROXY_SSLKEY
+Proxy client key. See \fICURLOPT_PROXY_SSLKEY(3)\fP
 .IP CURLOPT_SSLKEYTYPE
 Client key type. See \fICURLOPT_SSLKEYTYPE(3)\fP
+.IP CURLOPT_PROXY_SSLKEYTYPE
+Proxy client key type. See \fICURLOPT_PROXY_SSLKEYTYPE(3)\fP
 .IP CURLOPT_KEYPASSWD
 Client key password. See \fICURLOPT_KEYPASSWD(3)\fP
+.IP CURLOPT_PROXY_KEYPASSWD
+Proxy client key password. See \fICURLOPT_PROXY_KEYPASSWD(3)\fP
 .IP CURLOPT_SSL_ENABLE_ALPN
 Enable use of ALPN. See \fICURLOPT_SSL_ENABLE_ALPN(3)\fP
 .IP CURLOPT_SSL_ENABLE_NPN
@@ -465,20 +487,32 @@
 Enable TLS False Start. See \fICURLOPT_SSL_FALSESTART(3)\fP
 .IP CURLOPT_SSLVERSION
 SSL version to use. See \fICURLOPT_SSLVERSION(3)\fP
+.IP CURLOPT_PROXY_SSLVERSION
+Proxy SSL version to use. See \fICURLOPT_PROXY_SSLVERSION(3)\fP
 .IP CURLOPT_SSL_VERIFYHOST
 Verify the host name in the SSL certificate. See \fICURLOPT_SSL_VERIFYHOST(3)\fP
+.IP CURLOPT_PROXY_SSL_VERIFYHOST
+Verify the host name in the proxy SSL certificate. See \fICURLOPT_PROXY_SSL_VERIFYHOST(3)\fP
 .IP CURLOPT_SSL_VERIFYPEER
 Verify the SSL certificate. See \fICURLOPT_SSL_VERIFYPEER(3)\fP
+.IP CURLOPT_PROXY_SSL_VERIFYPEER
+Verify the proxy SSL certificate. See \fICURLOPT_PROXY_SSL_VERIFYPEER(3)\fP
 .IP CURLOPT_SSL_VERIFYSTATUS
 Verify the SSL certificate's status. See \fICURLOPT_SSL_VERIFYSTATUS(3)\fP
 .IP CURLOPT_CAINFO
 CA cert bundle. See \fICURLOPT_CAINFO(3)\fP
+.IP CURLOPT_PROXY_CAINFO
+Proxy CA cert bundle. See \fICURLOPT_PROXY_CAINFO(3)\fP
 .IP CURLOPT_ISSUERCERT
 Issuer certificate. See \fICURLOPT_ISSUERCERT(3)\fP
 .IP CURLOPT_CAPATH
 Path to CA cert bundle. See \fICURLOPT_CAPATH(3)\fP
+.IP CURLOPT_PROXY_CAPATH
+Path to proxy CA cert bundle. See \fICURLOPT_PROXY_CAPATH(3)\fP
 .IP CURLOPT_CRLFILE
 Certificate Revocation List. See \fICURLOPT_CRLFILE(3)\fP
+.IP CURLOPT_PROXY_CRLFILE
+Proxy Certificate Revocation List. See \fICURLOPT_PROXY_CRLFILE(3)\fP
 .IP CURLOPT_CERTINFO
 Extract certificate info. See \fICURLOPT_CERTINFO(3)\fP
 .IP CURLOPT_PINNEDPUBLICKEY
@@ -489,10 +523,14 @@
 Identify EGD socket for entropy. See \fICURLOPT_EGDSOCKET(3)\fP
 .IP CURLOPT_SSL_CIPHER_LIST
 Ciphers to use. See \fICURLOPT_SSL_CIPHER_LIST(3)\fP
+.IP CURLOPT_PROXY_SSL_CIPHER_LIST
+Proxy ciphers to use. See \fICURLOPT_PROXY_SSL_CIPHER_LIST(3)\fP
 .IP CURLOPT_SSL_SESSIONID_CACHE
 Disable SSL session-id cache. See \fICURLOPT_SSL_SESSIONID_CACHE(3)\fP
 .IP CURLOPT_SSL_OPTIONS
 Control SSL behavior. See \fICURLOPT_SSL_OPTIONS(3)\fP
+.IP CURLOPT_PROXY_SSL_OPTIONS
+Control proxy SSL behavior. See \fICURLOPT_PROXY_SSL_OPTIONS(3)\fP
 .IP CURLOPT_KRBLEVEL
 Kerberos security level. See \fICURLOPT_KRBLEVEL(3)\fP
 .IP CURLOPT_GSSAPI_DELEGATION
diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3
index 06fd6fc..50ce97d 100644
--- a/docs/libcurl/curl_easy_unescape.3
+++ b/docs/libcurl/curl_easy_unescape.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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
@@ -40,7 +40,10 @@
 
 If \fBoutlength\fP is non-NULL, the function will write the length of the
 returned string in the integer it points to. This allows an escaped string
-containing %00 to still get used properly after unescaping.
+containing %00 to still get used properly after unescaping. Since this is a
+pointer to an \fIint\fP type, it can only return a value up to INT_MAX so no
+longer string can be unescaped if the string length is returned in this
+parameter.
 
 You must \fIcurl_free(3)\fP the returned string when you're done with it.
 .SH AVAILABILITY
diff --git a/docs/libcurl/curl_formadd.3 b/docs/libcurl/curl_formadd.3
index 6923913..bf1b11e 100644
--- a/docs/libcurl/curl_formadd.3
+++ b/docs/libcurl/curl_formadd.3
@@ -105,6 +105,8 @@
 followed by a filename, causes that file to be read and its contents used
 as data in this part. This part does \fInot\fP automatically become a file
 upload part simply because its data was read from a file.
+
+The specified file needs to kept around until the associated transfer is done.
 .IP CURLFORM_FILE
 followed by a filename, makes this part a file upload part. It sets the
 \fIfilename\fP field to the basename of the provided filename, it reads the
@@ -117,6 +119,8 @@
 
 The given upload file has to exist in its full in the file system already when
 the upload starts, as libcurl needs to read the correct file size beforehand.
+
+The specified file needs to kept around until the associated transfer is done.
 .IP CURLFORM_CONTENTTYPE
 is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
 string which provides the content-type for this part, possibly instead of an
diff --git a/docs/libcurl/curl_global_cleanup.3 b/docs/libcurl/curl_global_cleanup.3
index 2e3ff03..04ab043 100644
--- a/docs/libcurl/curl_global_cleanup.3
+++ b/docs/libcurl/curl_global_cleanup.3
@@ -42,8 +42,14 @@
 
 See the description in \fIlibcurl(3)\fP of global environment requirements for
 details of how to use this function.
-
+.SH CAUTION
+\fIcurl_global_cleanup(3)\fP does not block waiting for any libcurl-created
+threads to terminate (such as threads used for name resolving). If a module
+containing libcurl is dynamically unloaded while libcurl-created threads are
+still running then your program may crash or other corruption may occur. We
+recommend you do not run libcurl from any module that may be unloaded
+dynamically. This behavior may be addressed in the future.
 .SH "SEE ALSO"
 .BR curl_global_init "(3), "
 .BR libcurl "(3), "
-
+.BR libcurl-thread "(3), "
diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3
index 0a21a75..1b6e34f 100644
--- a/docs/libcurl/libcurl-errors.3
+++ b/docs/libcurl/libcurl-errors.3
@@ -60,9 +60,8 @@
 .IP "CURLE_COULDNT_CONNECT (7)"
 Failed to connect() to host or proxy.
 .IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
-After connecting to a FTP server, libcurl expects to get a certain reply
-back. This error code implies that it got a strange or bad reply. The given
-remote server is probably not an OK FTP server.
+The server sent data libcurl couldn't parse. This error code is used for more
+than just FTP and is aliased as \fICURLE_WEIRD_SERVER_REPLY\fP since 7.51.0.
 .IP "CURLE_REMOTE_ACCESS_DENIED (9)"
 We were denied access to the resource given in the URL.  For FTP, this occurs
 while trying to change to the remote directory.
diff --git a/docs/libcurl/opts/CURLINFO_COOKIELIST.3 b/docs/libcurl/opts/CURLINFO_COOKIELIST.3
index 961fd98..b9f75f4 100644
--- a/docs/libcurl/opts/CURLINFO_COOKIELIST.3
+++ b/docs/libcurl/opts/CURLINFO_COOKIELIST.3
@@ -30,7 +30,7 @@
                            struct curl_slist **cookies);
 .SH DESCRIPTION
 Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all
-cookies cURL knows (expired ones, too). Don't forget to call
+cookies curl knows (expired ones, too). Don't forget to call
 \fIcurl_slist_free_all(3)\fP on the list after it has been used.  If there are
 no cookies (cookies for the handle have not been enabled or simply none have
 been received) 'struct curl_slist *' will be set to point to NULL.
diff --git a/docs/libcurl/opts/CURLINFO_PROTOCOL.3 b/docs/libcurl/opts/CURLINFO_PROTOCOL.3
new file mode 100644
index 0000000..b821118
--- /dev/null
+++ b/docs/libcurl/opts/CURLINFO_PROTOCOL.3
@@ -0,0 +1,55 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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 CURLINFO_PROTOCOL 3 "23 November 2016" "libcurl 7.52.0" "curl_easy_getinfo options"
+.SH NAME
+CURLINFO_PROTOCOL \- get the protocol used in the connection
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_PROTOCOL, long *p);
+.SH DESCRIPTION
+Pass a pointer to a long to receive the version used in the last http connection.
+The returned value will be one of the CURLPROTO_* values.
+.SH PROTOCOLS
+All
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  CURLcode res;
+  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+  res = curl_easy_perform(curl);
+  if(res == CURLE_OK) {
+    long protocol;
+    curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol);
+  }
+  curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.52.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLINFO_RESPONSE_CODE "(3), "
+.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
diff --git a/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 b/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3
new file mode 100644
index 0000000..34892f5
--- /dev/null
+++ b/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3
@@ -0,0 +1,44 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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 CURLINFO_PROXY_SSL_VERIFYRESULT 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_getinfo options"
+.SH NAME
+CURLINFO_PROXY_SSL_VERIFYRESULT \- get the result of the proxy certification verification
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_PROXY_SSL_VERIFYRESULT, long *result);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a long to receive the result of the certification
+verification that was requested (using the \fICURLOPT_SSL_VERIFYPEER(3)\fP
+option.
+.SH PROTOCOLS
+All using TLS
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+Added in 7.5
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
diff --git a/docs/libcurl/opts/CURLINFO_SCHEME.3 b/docs/libcurl/opts/CURLINFO_SCHEME.3
new file mode 100644
index 0000000..78c3d68
--- /dev/null
+++ b/docs/libcurl/opts/CURLINFO_SCHEME.3
@@ -0,0 +1,59 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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 CURLINFO_SCHEME 3 "23 November 2016" "libcurl 7.52.0" "curl_easy_getinfo options"
+.SH NAME
+CURLINFO_SCHEME \- get the URL scheme (sometimes called protocol) used in the connection
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_SCHEME, long *p);
+.SH DESCRIPTION
+Pass a pointer to a char pointer to receive the pointer to a zero-terminated
+string holding the URL scheme used for the most recent connection done with this
+\fBcurl\fP handle.
+
+The \fBid\fP pointer will be NULL or pointing to private read-only memory you
+MUST NOT free or modify.
+.SH PROTOCOLS
+All
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  CURLcode res;
+  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+  res = curl_easy_perform(curl);
+  if(res == CURLE_OK) {
+    char * scheme;
+    curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme);
+  }
+  curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.52.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLINFO_RESPONSE_CODE "(3), "
+.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
diff --git a/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 b/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3
index cac3c71..1204a0f 100644
--- a/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3
+++ b/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3
@@ -29,8 +29,8 @@
 CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_MAX_PIPELINE_LENGTH, long max);
 .SH DESCRIPTION
 Pass a long. The set \fBmax\fP number will be used as the maximum amount of
-outstanding requests in a pipelined connection. Only used if pipelining is
-enabled.
+outstanding requests in an HTTP/1.1 pipelined connection. This option is only
+used for HTTP/1.1 pipelining, not for HTTP/2 multiplexing.
 
 When this limit is reached, libcurl will use another connection to the same
 host (see \fICURLMOPT_MAX_HOST_CONNECTIONS(3)\fP), or queue the request until
diff --git a/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 b/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3
index 835c2bd..ea53bff 100644
--- a/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3
+++ b/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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
@@ -34,7 +34,7 @@
 limit set by \fICURLMOPT_MAX_TOTAL_CONNECTIONS(3)\fP. When the limit is
 reached, the sessions will be pending until there are available
 connections. If \fICURLMOPT_PIPELINING(3)\fP is enabled, libcurl will try to
-pipeline if the host is capable of it.
+pipeline or use multiplexing if the host is capable of it.
 .SH DEFAULT
 The default value is 0, which means that there is no limit. It is then simply
 controlled by the number of easy handles added.
diff --git a/docs/libcurl/opts/CURLMOPT_PIPELINING.3 b/docs/libcurl/opts/CURLMOPT_PIPELINING.3
index 4c79b1b..1a40476 100644
--- a/docs/libcurl/opts/CURLMOPT_PIPELINING.3
+++ b/docs/libcurl/opts/CURLMOPT_PIPELINING.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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,24 +22,36 @@
 .\"
 .TH CURLMOPT_PIPELINING 3 "17 Jun 2014" "libcurl 7.37.0" "curl_multi_setopt options"
 .SH NAME
-CURLMOPT_PIPELINING \- enable/disable HTTP pipelining
+CURLMOPT_PIPELINING \- enable HTTP pipelining and multiplexing
 .SH SYNOPSIS
 #include <curl/curl.h>
 
-CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PIPELINING, long bits);
+CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PIPELINING, long bitmask);
 .SH DESCRIPTION
-Set the \fBbits\fP parameter to 1 to make libcurl use HTTP pipelining for
-HTTP/1.1 transfers done using this multi handle, as far as possible. This
-means that if you add a second request that can use an already existing
-connection, the second request will be \&"piped" on the same connection rather
-than being executed in parallel.
+Pass in the \fBbitmask\fP parameter to instruct libcurl to enable HTTP
+pipelining and/or HTTP/2 multiplexing for this multi handle.
 
-When using pipelining, there are also several other related options that are
-interesting to tweak and adjust to alter how libcurl spreads out requests on
-different connections or not etc.
+When enabled, libcurl will attempt to use those protocol features when doing
+parallel requests to the same hosts.
 
-Starting in 7.43.0, the \fBbits\fP parameter's bit 1 also has a meaning and
-libcurl is now offering symbol names for the bits:
+For pipelining, this means that if you add a second request that can use an
+already existing connection, the second request will be \&"piped" on the same
+connection rather than being executed in parallel.
+
+For multiplexing, this means that follow-up requests can re-use an existing
+connection and send the new request multiplexed over that at the same time as
+other transfers are already using that single connection.
+
+There are several other related options that are interesting to tweak and
+adjust to alter how libcurl spreads out requests on different connections or
+not etc.
+
+Before 7.43.0, this option was set to 1 and 0 to enable and disable HTTP/1.1
+pipelining.
+
+Starting in 7.43.0, \fBbitmask\fP's second bit also has a meaning, and you can
+ask for pipelining and multiplexing independently of each other by toggling
+the correct bits.
 .IP CURLPIPE_NOTHING (0)
 Default, which means doing no attempts at pipelining or multiplexing.
 .IP CURLPIPE_HTTP1 (1)
@@ -49,7 +61,7 @@
 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
-0 (off)
+0 (both pipeline and multiplexing are off)
 .SH PROTOCOLS
 HTTP(S)
 .SH EXAMPLE
diff --git a/docs/libcurl/opts/CURLOPT_CAINFO.3 b/docs/libcurl/opts/CURLOPT_CAINFO.3
index a05f5c0..7db50a8 100644
--- a/docs/libcurl/opts/CURLOPT_CAINFO.3
+++ b/docs/libcurl/opts/CURLOPT_CAINFO.3
@@ -40,6 +40,12 @@
 
 If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
 (libnsspem.so) needs to be available for this option to work properly.
+
+(iOS and macOS only) If curl is built against Secure Transport, then this
+option is supported for backward compatibility with other SSL engines, but it
+should not be set. If the option is not set, then curl will use the
+certificates in the system and user Keychain to verify the peer, which is the
+preferred method of verifying the peer's certificate chain.
 .SH DEFAULT
 Built-in system specific
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
index bf07499..535c530 100644
--- a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
+++ b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
@@ -119,6 +119,7 @@
 {
   const char *text;
   (void)handle; /* prevent compiler warning */
+  (void)userp;
 
   switch (type) {
   case CURLINFO_TEXT:
diff --git a/docs/libcurl/opts/CURLOPT_FAILONERROR.3 b/docs/libcurl/opts/CURLOPT_FAILONERROR.3
index 79474ce..93d8ba6 100644
--- a/docs/libcurl/opts/CURLOPT_FAILONERROR.3
+++ b/docs/libcurl/opts/CURLOPT_FAILONERROR.3
@@ -53,4 +53,4 @@
 .SH RETURN VALUE
 Returns CURLE_OK if HTTP is enabled, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"
-.BR CURLOPT_HTTP200ALIASES "(3), "
+.BR CURLOPT_HTTP200ALIASES "(3), " CURLOPT_KEEP_SENDING_ON_ERROR "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 b/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3
new file mode 100644
index 0000000..277125b
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3
@@ -0,0 +1,52 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_KEEP_SENDING_ON_ERROR 3 "22 Sep 2016" "libcurl 7.51.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_KEEP_SENDING_ON_ERROR \- keep sending on early HTTP response >= 300
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_KEEP_SENDING_ON_ERROR,
+                          long keep_sending);
+.SH DESCRIPTION
+A long parameter set to 1 tells the library to keep sending the request body
+if the HTTP code returned is equal to or larger than 300. The default action
+would be to stop sending and close the stream or connection.
+
+This option is suitable for manual NTLM authentication, i.e. if an application
+does not use \fICURLOPT_HTTPAUTH(3)\fP, but instead sets "Authorization: NTLM ..."
+headers manually using \fICURLOPT_HTTPHEADER(3)\fP.
+
+Most applications do not need this option.
+.SH DEFAULT
+0, stop sending on error
+.SH PROTOCOLS
+HTTP
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+Along with HTTP. Added in 7.51.0.
+.SH RETURN VALUE
+Returns CURLE_OK if HTTP is enabled, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_FAILONERROR "(3), " CURLOPT_HTTPHEADER "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 b/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3
index 031f2cd..c99ff61 100644
--- a/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3
+++ b/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3
@@ -31,9 +31,8 @@
                           curl_off_t speed);
 .SH DESCRIPTION
 Pass a curl_off_t as parameter.  If a download exceeds this \fIspeed\fP
-(counted in bytes per second) on cumulative average during the transfer, the
-transfer will pause to keep the average rate less than or equal to the
-parameter value. Defaults to unlimited speed.
+(counted in bytes per second) the transfer will pause to keep the speed less
+than or equal to the parameter value. Defaults to unlimited speed.
 
 This option doesn't affect transfer speeds done with FILE:// URLs.
 .SH DEFAULT
diff --git a/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 b/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3
index c2c6336..7f3efe5 100644
--- a/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3
+++ b/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3
@@ -31,9 +31,9 @@
                           curl_off_t maxspeed);
 .SH DESCRIPTION
 Pass a curl_off_t as parameter with the \fImaxspeed\fP.  If an upload exceeds
-this speed (counted in bytes per second) on cumulative average during the
-transfer, the transfer will pause to keep the average rate less than or equal
-to the parameter value.  Defaults to unlimited speed.
+this speed (counted in bytes per second) the transfer will pause to keep the
+speed less than or equal to the parameter value.  Defaults to unlimited
+speed.
 
 This option doesn't affect transfer speeds done with FILE:// URLs.
 .SH DEFAULT
diff --git a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
index 4e673bd..33d201d 100644
--- a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
+++ b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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,14 +91,23 @@
 .fi
 .SH AVAILABILITY
 PEM/DER support:
+
   7.39.0: OpenSSL, GnuTLS and GSKit
+
   7.43.0: NSS and wolfSSL/CyaSSL
+
   7.47.0: mbedtls
+
   7.49.0: PolarSSL
+
 sha256 support:
-  7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL.
+
+  7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL
+
   7.47.0: mbedtls
+
   7.49.0: PolarSSL
+
 Other SSL backends not supported.
 .SH RETURN VALUE
 Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
diff --git a/docs/libcurl/opts/CURLOPT_PROXY.3 b/docs/libcurl/opts/CURLOPT_PROXY.3
index f6975bb..64b74fa 100644
--- a/docs/libcurl/opts/CURLOPT_PROXY.3
+++ b/docs/libcurl/opts/CURLOPT_PROXY.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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,8 +41,7 @@
 proxy is used. Use socks4://, socks4a://, socks5:// or socks5h:// (the last
 one to enable socks5 and asking the proxy to do the resolving, also known as
 \fICURLPROXY_SOCKS5_HOSTNAME\fP type) to request the specific SOCKS version to
-be used. No protocol specified, http:// and all others will be treated as HTTP
-proxies.
+be used. No scheme specified or http://, will be treated as HTTP proxies.
 
 Without a scheme prefix, \fICURLOPT_PROXYTYPE(3)\fP can be used to specify
 which kind of proxy the string identifies.
@@ -77,6 +76,9 @@
 scheme.
 
 Since 7.21.7 the proxy string supports the socks protocols as "schemes".
+
+Since 7.50.2, unsupported schemes in proxy strings cause libcurl to return
+error.
 .SH RETURN VALUE
 Returns CURLE_OK if proxies are supported, CURLE_UNKNOWN_OPTION if not, or
 CURLE_OUT_OF_MEMORY if there was insufficient heap space.
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3
new file mode 100644
index 0000000..d240b37
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3
@@ -0,0 +1,64 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_CAINFO 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_CAINFO \- path to proxy Certificate Authority (CA) bundle
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_CAINFO, char *path);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char * to a zero terminated string naming a file holding one or more
+certificates to verify the peer with.
+
+If \fICURLOPT_SSL_VERIFYPEER(3)\fP is zero and you avoid verifying the
+server's certificate, \fICURLOPT_CAINFO(3)\fP need not even indicate an
+accessible file.
+
+This option is by default set to the system path where libcurl's cacert bundle
+is assumed to be stored, as established at build time.
+
+If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
+(libnsspem.so) needs to be available for this option to work properly.
+
+(iOS and macOS only) If curl is built against Secure Transport, then this
+option is supported for backward compatibility with other SSL engines, but it
+should not be set. If the option is not set, then curl will use the
+certificates in the system and user Keychain to verify the peer, which is the
+preferred method of verifying the peer's certificate chain.
+.SH DEFAULT
+Built-in system specific
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+For SSL engines that don't support certificate files the CURLOPT_PROXY_CAINFO option
+is ignored. Refer to https://curl.haxx.se/docs/ssl-compared.html
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_CAPATH "(3), "
+.BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_SSL_VERIFYHOST "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3
new file mode 100644
index 0000000..d1dfb06
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3
@@ -0,0 +1,54 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_CAPATH 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_CAPATH \- specify directory holding proxy CA certificates
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_CAPATH, char *capath);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char * to a zero terminated string naming a directory holding multiple
+CA certificates to verify the peer with. If libcurl is built against OpenSSL,
+the certificate directory must be prepared using the openssl c_rehash utility.
+This makes sense only when used in combination with the
+\fICURLOPT_SSL_VERIFYPEER(3)\fP option.
+
+The \fICURLOPT_CAPATH(3)\fP function apparently does not work in Windows due
+to some limitation in openssl.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+This option is supported by the OpenSSL, GnuTLS and PolarSSL backends. The NSS
+backend provides the option only for backward compatibility.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS enabled, and CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_CAINFO "(3), "
+.BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3
new file mode 100644
index 0000000..1d0dc63
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3
@@ -0,0 +1,59 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_CRLFILE 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_CRLFILE \- specify a proxy Certificate Revocation List file
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_CRLFILE, char *file);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char * to a zero terminated string naming a \fIfile\fP with the
+concatenation of CRL (in PEM format) to use in the certificate validation that
+occurs during the SSL exchange.
+
+When curl is built to use NSS or GnuTLS, there is no way to influence the use
+of CRL passed to help in the verification process. When libcurl is built with
+OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both
+set, requiring CRL check against all the elements of the certificate chain if
+a CRL file is passed.
+
+This option makes sense only when used in combination with the
+\fICURLOPT_SSL_VERIFYPEER(3)\fP option.
+
+A specific error code (\fICURLE_SSL_CRL_BADFILE\fP) is defined with the
+option. It is returned when the SSL exchange fails because the CRL file cannot
+be loaded.  A failure in certificate verification due to a revocation
+information found in the CRL does not trigger this specific error.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS-based protocols
+.SH EXAMPLE
+TODO
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_SSL_VERIFYHOST "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3
new file mode 100644
index 0000000..1abd329
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3
@@ -0,0 +1,46 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_KEYPASSWD 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_KEYPASSWD \- set passphrase to proxy private key
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_KEYPASSWD, char *pwd);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. It will be used as
+the password required to use the \fICURLOPT_SSLKEY(3)\fP or
+\fICURLOPT_SSH_PRIVATE_KEYFILE(3)\fP private key.  You never needed a pass
+phrase to load a certificate but you need one to load your private key.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH RETURN VALUE
+Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLKEY "(3), " CURLOPT_SSH_PRIVATE_KEYFILE "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3
new file mode 100644
index 0000000..d69f6e6
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3
@@ -0,0 +1,56 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSLCERT 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSLCERT \- set SSL proxy client certificate
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSLCERT, char *cert);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. The string should be
+the file name of your client certificate. The default format is "P12" on
+Secure Transport and "PEM" on other engines, and can be changed with
+\fICURLOPT_SSLCERTTYPE(3)\fP.
+
+With NSS or Secure Transport, this can also be the nickname of the certificate
+you wish to authenticate with as it is named in the security database. If you
+want to use a file from the current directory, please precede it with "./"
+prefix, in order to avoid confusion with a nickname.
+
+When using a client certificate, you most likely also need to provide a
+private key with \fICURLOPT_SSLKEY(3)\fP.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLCERTTYPE "(3), " CURLOPT_SSLKEY "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3
new file mode 100644
index 0000000..326330c
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3
@@ -0,0 +1,49 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSLCERTTYPE 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSLCERTTYPE \- specify type of the proxy client SSL certificate
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSLCERTTYPE, char *type);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. The string should be
+the format of your certificate. Supported formats are "PEM" and "DER", except
+with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport
+(on iOS 5 or later, or OS X 10.7 or later) also support "P12" for
+PKCS#12-encoded files.
+.SH DEFAULT
+"PEM"
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLCERT "(3), " CURLOPT_SSLKEY "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3
new file mode 100644
index 0000000..e5c7369
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSLKEY 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSLKEY \- specify private keyfile for TLS and SSL proxy client cert
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSLKEY, char *keyfile);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. The string should be
+the file name of your private key. The default format is "PEM" and can be
+changed with \fICURLOPT_SSLKEYTYPE(3)\fP.
+
+(iOS and Mac OS X only) This option is ignored if curl was built against
+Secure Transport. Secure Transport expects the private key to be already
+present in the keychain or PKCS#12 file containing the certificate.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLKEYTYPE "(3), " CURLOPT_SSLCERT "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3
new file mode 100644
index 0000000..97454f9
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSLKEYTYPE 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSLKEYTYPE \- set type of the proxy private key file
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSLKEYTYPE, char *type);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. The string should be
+the format of your private key. Supported formats are "PEM", "DER" and "ENG".
+
+The format "ENG" enables you to load the private key from a crypto engine. In
+this case \fICURLOPT_SSLKEY(3)\fP is used as an identifier passed to the
+engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE(3)\fP.
+\&"DER" format key file currently does not work because of a bug in OpenSSL.
+.SH DEFAULT
+"PEM"
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLKEY "(3), " CURLOPT_SSLCERT "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3
new file mode 100644
index 0000000..0e91be9
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3
@@ -0,0 +1,81 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSLVERSION 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSLVERSION \- set proxy preferred TLS/SSL version
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSLVERSION, long version);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a long as parameter to control which version of SSL/TLS to attempt to
+use.
+
+Use one of the available defines for this purpose. The available options are:
+.RS
+.IP CURL_SSLVERSION_DEFAULT
+The default action. This will attempt to figure out the remote SSL protocol
+version.
+.IP CURL_SSLVERSION_TLSv1
+TLSv1.x
+.IP CURL_SSLVERSION_SSLv2
+SSLv2
+.IP CURL_SSLVERSION_SSLv3
+SSLv3
+.IP CURL_SSLVERSION_TLSv1_0
+TLSv1.0 (Added in 7.34.0)
+.IP CURL_SSLVERSION_TLSv1_1
+TLSv1.1 (Added in 7.34.0)
+.IP CURL_SSLVERSION_TLSv1_2
+TLSv1.2 (Added in 7.34.0)
+.IP CURL_SSLVERSION_TLSv1_3
+TLSv1.3 (Added in 7.52.0)
+.RE
+.SH DEFAULT
+CURL_SSLVERSION_DEFAULT
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+  /* ask libcurl to use TLS version 1.0 or later */
+  curl_easy_setopt(curl, CURLOPT_PROXY_SSLVERSION, CURL_SSLVERSION_TLSv1);
+
+  /* Perform the request */
+  curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+SSLv2 is disabled by default since 7.18.1. Other SSL versions availability may
+vary depending on which backend libcurl has been built to use.
+
+SSLv3 is disabled by default since 7.39.0.
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_USE_SSL "(3), " CURLOPT_HTTP_VERSION "(3), "
+.BR CURLOPT_IPRESOLVE "(3) "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3
new file mode 100644
index 0000000..f872952
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3
@@ -0,0 +1,66 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSL_CIPHER_LIST 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSL_CIPHER_LIST \- specify ciphers to use for proxy TLS
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSL_CIPHER_LIST, char *list);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char *, pointing to a zero terminated string holding the list of
+ciphers to use for the SSL connection. The list must be syntactically correct,
+it consists of one or more cipher strings separated by colons. Commas or
+spaces are also acceptable separators but colons are normally used, \&!, \&-
+and \&+ can be used as operators.
+
+For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA',
+\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
+compile OpenSSL.
+
+You'll find more details about cipher lists on this URL:
+
+ https://www.openssl.org/docs/apps/ciphers.html
+
+For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
+\'rsa_aes_128_sha\', etc. With NSS you don't add/remove ciphers. If one uses
+this option then all known ciphers are disabled and only those passed in are
+enabled.
+
+You'll find more details about the NSS cipher lists on this URL:
+
+ http://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives
+.SH DEFAULT
+NULL, use internal default
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLVERSION "(3), " CURLOPT_USE_SSL "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3
new file mode 100644
index 0000000..45402df
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3
@@ -0,0 +1,62 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSL_OPTIONS 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSL_OPTIONS \- set proxy SSL behavior options
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSL_OPTIONS, long bitmask);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a long with a bitmask to tell libcurl about specific SSL behaviors.
+
+\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any
+workarounds for a security flaw in the SSL3 and TLS1.0 protocols.  If this
+option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a
+work-around for this flaw although it might cause interoperability problems
+with some (older) SSL implementations. WARNING: avoiding this work-around
+lessens the security, and by setting this option to 1 you ask for exactly that.
+This option is only supported for DarwinSSL, NSS and OpenSSL.
+
+Added in 7.44.0:
+
+\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation
+checks for those SSL backends where such behavior is present. \fBCurrently this
+option is only supported for WinSSL (the native Windows SSL library), with an
+exception in the case of Windows' Untrusted Publishers blacklist which it seems
+can't be bypassed.\fP This option may have broader support to accommodate other
+SSL backends in the future.
+https://curl.haxx.se/docs/ssl-compared.html
+
+
+.SH DEFAULT
+0
+.SH PROTOCOLS
+All TLS-based protocols
+.SH EXAMPLE
+TODO
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLVERSION "(3), " CURLOPT_SSL_CIPHER_LIST "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3
new file mode 100644
index 0000000..e72027a
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3
@@ -0,0 +1,88 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSL_VERIFYHOST 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSL_VERIFYHOST \- verify the proxy certificate's name against host
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSL_VERIFYHOST, long verify);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a long as parameter specifying what to \fIverify\fP.
+
+This option determines whether libcurl verifies that the server cert is for
+the server it is known as.
+
+When negotiating TLS and SSL connections, the server sends a certificate
+indicating its identity.
+
+When \fICURLOPT_SSL_VERIFYHOST(3)\fP is 2, that certificate must indicate that
+the server is the server to which you meant to connect, or the connection
+fails. Simply put, it means it has to have the same name in the certificate as
+is in the URL you operate against.
+
+Curl considers the server the intended one when the Common Name field or a
+Subject Alternate Name field in the certificate matches the host name in the
+URL to which you told Curl to connect.
+
+When the \fIverify\fP value is 1, \fIcurl_easy_setopt\fP will return an error
+and the option value will not be changed.  It was previously (in 7.28.0 and
+earlier) a debug option of some sorts, but it is no longer supported due to
+frequently leading to programmer mistakes. Future versions will stop returning
+an error for 1 and just treat 1 and 2 the same.
+
+When the \fIverify\fP value is 0, the connection succeeds regardless of the
+names in the certificate. Use that ability with caution!
+
+The default value for this option is 2.
+
+This option controls checking the server's certificate's claimed identity.
+The server could be lying.  To control lying, see
+\fICURLOPT_SSL_VERIFYPEER(3)\fP.  If libcurl is built against NSS and
+\fICURLOPT_SSL_VERIFYPEER(3)\fP is zero, \fICURLOPT_SSL_VERIFYHOST(3)\fP is
+also set to zero and cannot be overridden.
+.SH DEFAULT
+2
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+  /* Set the default value: strict name check please */
+  curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 2L);
+
+  curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if TLS is supported, and CURLE_UNKNOWN_OPTION if not.
+
+If 1 is set as argument, \fICURLE_BAD_FUNCTION_ARGUMENT\fP is returned.
+.SH "SEE ALSO"
+.BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_CAINFO "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3
new file mode 100644
index 0000000..0eb902b
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3
@@ -0,0 +1,82 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_SSL_VERIFYPEER 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_SSL_VERIFYPEER \- verify the proxy peer's SSL certificate
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSL_VERIFYPEER, long verify);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a long as parameter to enable or disable.
+
+This option determines whether curl verifies the authenticity of the peer's
+certificate. A value of 1 means curl verifies; 0 (zero) means it doesn't.
+
+When negotiating a TLS or SSL connection, the server sends a certificate
+indicating its identity.  Curl verifies whether the certificate is authentic,
+i.e. that you can trust that the server is who the certificate says it is.
+This trust is based on a chain of digital signatures, rooted in certification
+authority (CA) certificates you supply.  curl uses a default bundle of CA
+certificates (the path for that is determined at build time) and you can
+specify alternate certificates with the \fICURLOPT_CAINFO(3)\fP option or the
+\fICURLOPT_CAPATH(3)\fP option.
+
+When \fICURLOPT_SSL_VERIFYPEER(3)\fP is enabled, and the verification fails to
+prove that the certificate is authentic, the connection fails.  When the
+option is zero, the peer certificate verification succeeds regardless.
+
+Authenticating the certificate is not enough to be sure about the server. You
+typically also want to ensure that the server is the server you mean to be
+talking to.  Use \fICURLOPT_SSL_VERIFYHOST(3)\fP for that. The check that the
+host name in the certificate is valid for the host name you're connecting to
+is done independently of the \fICURLOPT_SSL_VERIFYPEER(3)\fP option.
+
+WARNING: disabling verification of the certificate allows bad guys to
+man-in-the-middle the communication without you knowing it. Disabling
+verification makes the communication insecure. Just having encryption on a
+transfer is not enough as you cannot be sure that you are communicating with
+the correct end-point.
+.SH DEFAULT
+By default, curl assumes a value of 1.
+.SH PROTOCOLS
+All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+  /* Set the default value: strict certificate check please */
+  curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+
+  curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+If built TLS enabled.
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_SSL_VERIFYHOST "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3
new file mode 100644
index 0000000..1d824fe
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3
@@ -0,0 +1,48 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_TLSAUTH_PASSWORD 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_TLSAUTH_PASSWORD \- password to use for proxy TLS authentication
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_TLSAUTH_PASSWORD, char *pwd);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char * as parameter, which should point to the zero terminated password
+to use for the TLS authentication method specified with the
+\fICURLOPT_TLSAUTH_TYPE(3)\fP option. Requires that the
+\fICURLOPT_TLSAUTH_USERNAME(3)\fP option also be set.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS-based protocols
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+Added in 7.21.4
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_TLSAUTH_TYPE "(3), " CURLOPT_TLSAUTH_USERNAME "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3
new file mode 100644
index 0000000..228a42e
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3
@@ -0,0 +1,53 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_TLSAUTH_TYPE 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_TLSAUTH_TYPE \- set proxy TLS authentication methods
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_TLSAUTH_TYPE, char *type);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a pointer to a zero terminated string as parameter. The string
+should be the method of the TLS authentication. Supported method is "SRP".
+
+.IP SRP
+TLS-SRP authentication. Secure Remote Password authentication for TLS is
+defined in RFC5054 and provides mutual authentication if both sides have a
+shared secret. To use TLS-SRP, you must also set the
+\fICURLOPT_TLSAUTH_USERNAME(3)\fP and \fICURLOPT_TLSAUTH_PASSWORD(3)\fP
+options.
+.SH DEFAULT
+blank
+.SH PROTOCOLS
+All TLS-based protocols
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+You need to build libcurl with GnuTLS or OpenSSL with TLS-SRP support for this
+to work.
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_TLSAUTH_USERNAME "(3), " CURLOPT_TLSAUTH_PASSWORD "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3
new file mode 100644
index 0000000..e8d4e4d
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3
@@ -0,0 +1,46 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_PROXY_TLSAUTH_USERNAME 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_PROXY_TLSAUTH_USERNAME \- user name to use for proxy TLS authentication
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_TLSAUTH_USERNAME, char *user);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a char * as parameter, which should point to the zero terminated username
+to use for the TLS authentication method specified with the
+\fICURLOPT_TLSAUTH_TYPE(3)\fP option. Requires that the
+\fICURLOPT_TLSAUTH_PASSWORD(3)\fP option also be set.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+All TLS-based protocols
+.SH EXAMPLE
+TODO
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_TLSAUTH_TYPE "(3), " CURLOPT_TLSAUTH_PASSWORD "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3
index 8bd76f6..3a5c3fc 100644
--- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3
+++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3
@@ -34,6 +34,9 @@
 limit specific transfers to only be allowed to use a subset of protocols in
 redirections.
 
+Protocols denied by \fICURLOPT_PROTOCOLS(3)\fP are not overridden by this
+option.
+
 By default libcurl will allow all protocols on redirect except several disabled
 for security reasons: Since 7.19.4 FILE and SCP are disabled, and since 7.40.0
 SMB and SMBS are also disabled. \fICURLPROTO_ALL\fP enables all protocols on
diff --git a/docs/libcurl/opts/CURLOPT_SOCKS_PROXY.3 b/docs/libcurl/opts/CURLOPT_SOCKS_PROXY.3
new file mode 100644
index 0000000..aad3d40
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_SOCKS_PROXY.3
@@ -0,0 +1,88 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_SOCKS_PROXY 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_SOCKS_PROXY \- set socks proxy to use
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SOCKS_PROXY, char *proxy);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Set the \fIproxy\fP to use for the upcoming request. The parameter should be a
+char * to a zero terminated string holding the host name or dotted numerical
+IP address. A numerical IPv6 address must be written within [brackets].
+
+To specify port number in this string, append :[port] to the end of the host
+name. The proxy's port number may optionally be specified with the separate
+option \fICURLOPT_PROXYPORT(3)\fP. If not specified, libcurl will default to
+using port 1080 for proxies.
+
+The proxy string may be prefixed with [scheme]:// to specify which kind of
+proxy is used. Use socks4://, socks4a://, socks5:// or socks5h:// (the last
+one to enable socks5 and asking the proxy to do the resolving, also known as
+\fICURLPROXY_SOCKS5_HOSTNAME\fP type) to request the specific SOCKS version to
+be used. No scheme specified or http://, will be treated as HTTP proxies.
+
+Without a scheme prefix, \fICURLOPT_PROXYTYPE(3)\fP can be used to specify
+which kind of proxy the string identifies.
+
+When you tell the library to use a HTTP proxy, libcurl will transparently
+convert operations to HTTP even if you specify an FTP URL etc. This may have
+an impact on what other features of the library you can use, such as
+\fICURLOPT_QUOTE(3)\fP and similar FTP specifics that don't work unless you
+tunnel through the HTTP proxy. Such tunneling is activated with
+\fICURLOPT_HTTPPROXYTUNNEL(3)\fP.
+
+libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP,
+\fBall_proxy\fP etc, if any of those are set. The \fICURLOPT_PROXY(3)\fP
+option does however override any possibly set environment variables.
+
+Setting the proxy string to "" (an empty string) will explicitly disable the
+use of a proxy, even if there is an environment variable set for it.
+
+A proxy host string can also include protocol scheme (http://) and embedded
+user + password.
+.SH DEFAULT
+Default is NULL, meaning no proxy is used.
+
+When you set a host name to use, do not assume that there's any particular
+single port number used widely for proxies. Specify it!
+.SH PROTOCOLS
+All except file://. Note that some protocols don't do very well over proxy.
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+Since 7.14.1 the proxy environment variable names can include the protocol
+scheme.
+
+Since 7.21.7 the proxy string supports the socks protocols as "schemes".
+
+Since 7.50.2, unsupported schemes in proxy strings cause libcurl to return
+error.
+.SH RETURN VALUE
+Returns CURLE_OK if proxies are supported, CURLE_UNKNOWN_OPTION if not, or
+CURLE_OUT_OF_MEMORY if there was insufficient heap space.
+.SH "SEE ALSO"
+.BR CURLOPT_PROXYPORT "(3), " CURLOPT_HTTPPROXYTUNNEL "(3), "
+.BR CURLOPT_PROXYTYPE "(3)"
diff --git a/docs/libcurl/opts/CURLOPT_SOCKS_PROXYTYPE.3 b/docs/libcurl/opts/CURLOPT_SOCKS_PROXYTYPE.3
new file mode 100644
index 0000000..2100240
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_SOCKS_PROXYTYPE.3
@@ -0,0 +1,55 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, 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_SOCKS_PROXYTYPE 3 "16 Nov 2016" "libcurl 7.52.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_SOCKS_PROXYTYPE \- socks proxy protocol type
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SOCKS_PROXYTYPE, long type);
+.SH DESCRIPTION
+TODO: Make this text specific to HTTPS proxy. (Added in 7.XXX)
+Pass a long with this option to set type of the proxy. Available options for
+this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP
+\fICURLPROXY_SOCKS4\fP, \fICURLPROXY_SOCKS5\fP, \fICURLPROXY_SOCKS4A\fP and
+\fICURLPROXY_SOCKS5_HOSTNAME\fP. The HTTP type is default.
+
+If you set \fICURLOPT_PROXYTYPE(3)\fP to \fICURLPROXY_HTTP_1_0\fP, it will
+only affect how libcurl speaks to a proxy when CONNECT is used. The HTTP
+version used for "regular" HTTP requests is instead controlled with
+\fICURLOPT_HTTP_VERSION(3)\fP.
+
+Often it is more convenient to specify the proxy type with the scheme part of
+the \fICURLOPT_PROXY(3)\fP string.
+.SH DEFAULT
+CURLPROXY_HTTP
+.SH PROTOCOLS
+Most
+.SH EXAMPLE
+TODO
+.SH AVAILABILITY
+Always
+.SH RETURN VALUE
+Returns CURLE_OK
+.SH "SEE ALSO"
+.BR CURLOPT_PROXY "(3), " CURLOPT_PROXYPORT "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_SSLVERSION.3 b/docs/libcurl/opts/CURLOPT_SSLVERSION.3
index 2f40e46..77dfcd4 100644
--- a/docs/libcurl/opts/CURLOPT_SSLVERSION.3
+++ b/docs/libcurl/opts/CURLOPT_SSLVERSION.3
@@ -48,6 +48,8 @@
 TLSv1.1 (Added in 7.34.0)
 .IP CURL_SSLVERSION_TLSv1_2
 TLSv1.2 (Added in 7.34.0)
+.IP CURL_SSLVERSION_TLSv1_3
+TLSv1.3 (Added in 7.52.0)
 .RE
 .SH DEFAULT
 CURL_SSLVERSION_DEFAULT
diff --git a/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 b/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3
index efb2586..bd19fba 100644
--- a/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3
+++ b/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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,7 +20,7 @@
 .\" *
 .\" **************************************************************************
 .\"
-.TH CURLOPT_TCP_NODELAY 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
+.TH CURLOPT_TCP_NODELAY 3 "30 Jun 2016" "libcurl 7.50.0" "curl_easy_setopt options"
 .SH NAME
 CURLOPT_TCP_NODELAY \- set the TCP_NODELAY option
 .SH SYNOPSIS
@@ -29,8 +29,8 @@
 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TCP_NODELAY, long nodelay);
 .SH DESCRIPTION
 Pass a long specifying whether the TCP_NODELAY option is to be set or cleared
-(1 = set, 0 = clear). The option is cleared by default. This will have no
-effect after the connection has been established.
+(1 = set, 0 = clear). The option is set by default. This will have no effect
+after the connection has been established.
 
 Setting this option will disable TCP's Nagle algorithm. The purpose of this
 algorithm is to try to minimize the number of small packets on the network
@@ -43,13 +43,13 @@
 amounts of data at a time, and can contribute to congestion on the network if
 overdone.
 .SH DEFAULT
-0
+1
 .SH PROTOCOLS
 All
 .SH EXAMPLE
 TODO
 .SH AVAILABILITY
-Always
+Always. The default was changed to 1 from 0 in 7.50.2.
 .SH RETURN VALUE
 Returns CURLE_OK
 .SH "SEE ALSO"
diff --git a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3
index 299c3cc..ed2b91b 100644
--- a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3
+++ b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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,9 +33,9 @@
 empty string will result in an error at some point, it will not disable use of
 Unix domain sockets.
 
-When enabled, cURL will connect to the Unix domain socket instead of
+When enabled, curl will connect to the Unix domain socket instead of
 establishing a TCP connection to a host. Since no TCP connection is created,
-cURL does not need to resolve the DNS hostname in the URL.
+curl does not need to resolve the DNS hostname in the URL.
 
 The maximum path length on Cygwin, Linux and Solaris is 107. On other platforms
 it might be even less.
diff --git a/docs/libcurl/opts/Makefile.am b/docs/libcurl/opts/Makefile.am
index a3fc064..1ef4f2b 100644
--- a/docs/libcurl/opts/Makefile.am
+++ b/docs/libcurl/opts/Makefile.am
@@ -49,6 +49,7 @@
  CURLINFO_PRIMARY_IP.3                          \
  CURLINFO_PRIMARY_PORT.3                        \
  CURLINFO_PRIVATE.3                             \
+ CURLINFO_PROXY_SSL_VERIFYRESULT.3              \
  CURLINFO_PROXYAUTH_AVAIL.3                     \
  CURLINFO_REDIRECT_COUNT.3                      \
  CURLINFO_REDIRECT_TIME.3                       \
@@ -170,6 +171,7 @@
  CURLOPT_IOCTLFUNCTION.3                        \
  CURLOPT_IPRESOLVE.3                            \
  CURLOPT_ISSUERCERT.3                           \
+ CURLOPT_KEEP_SENDING_ON_ERROR.3                \
  CURLOPT_KEYPASSWD.3                            \
  CURLOPT_KRBLEVEL.3                             \
  CURLOPT_LOCALPORT.3                            \
@@ -222,6 +224,24 @@
  CURLOPT_PROXYUSERPWD.3                         \
  CURLOPT_PROXY_SERVICE_NAME.3                   \
  CURLOPT_PROXY_TRANSFER_MODE.3                  \
+ CURLOPT_PROXY_CAINFO.3                         \
+ CURLOPT_PROXY_CAPATH.3                         \
+ CURLOPT_PROXY_CRLFILE.3                        \
+ CURLOPT_PROXY_KEYPASSWD.3                      \
+ CURLOPT_PROXY_SSLCERT.3                        \
+ CURLOPT_PROXY_SSLCERTTYPE.3                    \
+ CURLOPT_PROXY_SSLKEY.3                         \
+ CURLOPT_PROXY_SSLKEYTYPE.3                     \
+ CURLOPT_PROXY_SSLVERSION.3                     \
+ CURLOPT_PROXY_SSL_CIPHER_LIST.3                \
+ CURLOPT_PROXY_SSL_OPTIONS.3                    \
+ CURLOPT_PROXY_SSL_VERIFYHOST.3                 \
+ CURLOPT_PROXY_SSL_VERIFYPEER.3                 \
+ CURLOPT_PROXY_TLSAUTH_PASSWORD.3               \
+ CURLOPT_PROXY_TLSAUTH_TYPE.3                   \
+ CURLOPT_PROXY_TLSAUTH_USERNAME.3               \
+ CURLOPT_SOCKS_PROXY.3                          \
+ CURLOPT_SOCKS_PROXYTYPE.3                      \
  CURLOPT_PUT.3                                  \
  CURLOPT_QUOTE.3                                \
  CURLOPT_RANDOM_FILE.3                          \
@@ -457,6 +477,7 @@
  CURLOPT_IOCTLFUNCTION.html                     \
  CURLOPT_IPRESOLVE.html                         \
  CURLOPT_ISSUERCERT.html                        \
+ CURLOPT_KEEP_SENDING_ON_ERROR.html             \
  CURLOPT_KEYPASSWD.html                         \
  CURLOPT_KRBLEVEL.html                          \
  CURLOPT_LOCALPORT.html                         \
@@ -744,6 +765,7 @@
  CURLOPT_IOCTLFUNCTION.pdf                      \
  CURLOPT_IPRESOLVE.pdf                          \
  CURLOPT_ISSUERCERT.pdf                         \
+ CURLOPT_KEEP_SENDING_ON_ERROR.pdf              \
  CURLOPT_KEYPASSWD.pdf                          \
  CURLOPT_KRBLEVEL.pdf                           \
  CURLOPT_LOCALPORT.pdf                          \
@@ -886,7 +908,7 @@
 
 CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
 
-EXTRA_DIST = $(man_MANS) $(HTMLPAGES) $(PDFPAGES)
+EXTRA_DIST = $(man_MANS)
 MAN2HTML= roffit --mandir=. $< >$@
 
 SUFFIXES = .3 .html
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index d05a469..0831775 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -140,6 +140,7 @@
 CURLE_URL_MALFORMAT             7.1
 CURLE_URL_MALFORMAT_USER        7.1           7.17.0
 CURLE_USE_SSL_FAILED            7.17.0
+CURLE_WEIRD_SERVER_REPLY        7.51.0
 CURLE_WRITE_ERROR               7.1
 CURLFILETYPE_DEVICE_BLOCK       7.21.0
 CURLFILETYPE_DEVICE_CHAR        7.21.0
@@ -238,7 +239,9 @@
 CURLINFO_PRIMARY_IP             7.19.0
 CURLINFO_PRIMARY_PORT           7.21.0
 CURLINFO_PRIVATE                7.10.3
+CURLINFO_PROTOCOL               7.52.0
 CURLINFO_PROXYAUTH_AVAIL        7.10.8
+CURLINFO_PROXY_SSL_VERIFYRESULT 7.52.0
 CURLINFO_REDIRECT_COUNT         7.9.7
 CURLINFO_REDIRECT_TIME          7.9.7
 CURLINFO_REDIRECT_URL           7.18.2
@@ -248,6 +251,7 @@
 CURLINFO_RTSP_CSEQ_RECV         7.20.0
 CURLINFO_RTSP_SERVER_CSEQ       7.20.0
 CURLINFO_RTSP_SESSION_ID        7.20.0
+CURLINFO_SCHEME                 7.52.0
 CURLINFO_SIZE_DOWNLOAD          7.4.1
 CURLINFO_SIZE_UPLOAD            7.4.1
 CURLINFO_SLIST                  7.12.3
@@ -410,6 +414,7 @@
 CURLOPT_IPRESOLVE               7.10.8
 CURLOPT_ISSUERCERT              7.19.0
 CURLOPT_KEYPASSWD               7.17.0
+CURLOPT_KEEP_SENDING_ON_ERROR   7.51.0
 CURLOPT_KRB4LEVEL               7.3           7.17.0
 CURLOPT_KRBLEVEL                7.16.4
 CURLOPT_LOCALPORT               7.15.2
@@ -466,7 +471,23 @@
 CURLOPT_PROXYTYPE               7.10
 CURLOPT_PROXYUSERNAME           7.19.1
 CURLOPT_PROXYUSERPWD            7.1
+CURLOPT_PROXY_CAINFO            7.52.0
+CURLOPT_PROXY_CAPATH            7.52.0
+CURLOPT_PROXY_CRLFILE           7.52.0
+CURLOPT_PROXY_KEYPASSWD         7.52.0
 CURLOPT_PROXY_SERVICE_NAME      7.43.0
+CURLOPT_PROXY_SSLCERT           7.52.0
+CURLOPT_PROXY_SSLCERTTYPE       7.52.0
+CURLOPT_PROXY_SSLKEY            7.52.0
+CURLOPT_PROXY_SSLKEYTYPE        7.52.0
+CURLOPT_PROXY_SSLVERSION        7.52.0
+CURLOPT_PROXY_SSL_CIPHER_LIST   7.52.0
+CURLOPT_PROXY_SSL_OPTIONS       7.52.0
+CURLOPT_PROXY_SSL_VERIFYHOST    7.52.0
+CURLOPT_PROXY_SSL_VERIFYPEER    7.52.0
+CURLOPT_PROXY_TLSAUTH_PASSWORD  7.52.0
+CURLOPT_PROXY_TLSAUTH_TYPE      7.52.0
+CURLOPT_PROXY_TLSAUTH_USERNAME  7.52.0
 CURLOPT_PROXY_TRANSFER_MODE     7.18.0
 CURLOPT_PUT                     7.1
 CURLOPT_QUOTE                   7.1
@@ -496,6 +517,8 @@
 CURLOPT_SOCKOPTFUNCTION         7.16.0
 CURLOPT_SOCKS5_GSSAPI_NEC       7.19.4
 CURLOPT_SOCKS5_GSSAPI_SERVICE   7.19.4        7.49.0
+CURLOPT_SOCKS_PROXY             7.52.0
+CURLOPT_SOCKS_PROXYTYPE         7.52.0
 CURLOPT_SOURCE_HOST             7.12.1        -           7.15.5
 CURLOPT_SOURCE_PATH             7.12.1        -           7.15.5
 CURLOPT_SOURCE_PORT             7.12.1        -           7.15.5
@@ -609,6 +632,7 @@
 CURLPROTO_TFTP                  7.19.4
 CURLPROXY_HTTP                  7.10
 CURLPROXY_HTTP_1_0              7.19.4
+CURLPROXY_HTTPS                 7.52.0
 CURLPROXY_SOCKS4                7.10
 CURLPROXY_SOCKS4A               7.18.0
 CURLPROXY_SOCKS5                7.10
@@ -763,6 +787,7 @@
 CURL_SOCKOPT_ALREADY_CONNECTED  7.21.5
 CURL_SOCKOPT_ERROR              7.21.5
 CURL_SOCKOPT_OK                 7.21.5
+CURL_STRICTER                   7.50.2
 CURL_SSLVERSION_DEFAULT         7.9.2
 CURL_SSLVERSION_SSLv2           7.9.2
 CURL_SSLVERSION_SSLv3           7.9.2
@@ -770,6 +795,7 @@
 CURL_SSLVERSION_TLSv1_0         7.34.0
 CURL_SSLVERSION_TLSv1_1         7.34.0
 CURL_SSLVERSION_TLSv1_2         7.34.0
+CURL_SSLVERSION_TLSv1_3         7.52.0
 CURL_TIMECOND_IFMODSINCE        7.9.7
 CURL_TIMECOND_IFUNMODSINCE      7.9.7
 CURL_TIMECOND_LASTMOD           7.9.7
diff --git a/docs/mk-ca-bundle.1 b/docs/mk-ca-bundle.1
index 017bb82..c8f5177 100644
--- a/docs/mk-ca-bundle.1
+++ b/docs/mk-ca-bundle.1
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 2008 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 2008 - 2016, 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,18 +20,18 @@
 .\" *
 .\" **************************************************************************
 .\"
-.TH mk-ca-bundle 1 "5 Jan 2013" "version 1.20" "mk-ca-bundle manual"
+.TH mk-ca-bundle 1 "24 Oct 2016" "version 1.27" "mk-ca-bundle manual"
 .SH NAME
 mk-ca-bundle \- convert mozilla's certdata.txt to PEM format
 .SH SYNOPSIS
-mk-ca-bundle [bilnpqstuv]
+mk-ca-bundle [options]
 .I [outputfile]
 .SH DESCRIPTION
 The mk-ca-bundle tool downloads the certdata.txt file from Mozilla's source
-tree over HTTP, then parses certdata.txt and extracts certificates
-into PEM format.  By default, only CA root certificates trusted to issue SSL
-server authentication certificates are extracted. These are then processed with
-the OpenSSL commandline tool to produce the final ca-bundle file.
+tree over HTTPS, then parses certdata.txt and extracts certificates into PEM
+format. By default, only CA root certificates trusted to issue SSL server
+authentication certificates are extracted. These are then processed with the
+OpenSSL commandline tool to produce the final ca-bundle file.
 
 The default \fIoutputfile\fP name is \fBca-bundle.crt\fP. By setting it to '-'
 (a single dash) you will get the output sent to STDOUT instead of a file.
@@ -51,8 +51,17 @@
 force rebuild even if certdata.txt is current (Added in version 1.17)
 .IP -i
 print version info about used modules
+.IP -k
+Allow insecure data transfer. By default (since 1.27) this command will fail
+if the HTTPS transfer fails. This overrides that decision (and opens for
+man-in-the-middle attacks).
 .IP -l
 print license info about certdata.txt
+.IP -m
+(Added in 1.26) Include meta data comments in the output. The meta data is
+specific information about each certificate that is stored in the original
+file as comments and using this option will make those comments get passed on
+to the output file. The meta data is not parsed in any way by mk-ca-bundle.
 .IP -n
 no download of certdata.txt (to use existing)
 .IP "-p [purposes]:[levels]"
diff --git a/include/README b/include/README
index 3e52a1d..6eb73b2 100644
--- a/include/README
+++ b/include/README
@@ -37,7 +37,7 @@
   also distribute along with it the generated curl/curlbuild.h which has been
   used to compile it. Otherwise the library will be of no use for the users of
   the library that you have built. It is _your_ responsibility to provide this
-  file. No one at the cURL project can know how you have built the library.
+  file. No one at the curl project can know how you have built the library.
 
 * File curl/curlbuild.h includes platform and configuration dependent info,
   and must not be modified by anyone. Configure script generates it for you.
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 7fd6d1f..df2914e 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -30,6 +30,10 @@
  *   https://cool.haxx.se/mailman/listinfo/curl-library/
  */
 
+#ifdef CURL_NO_OLDIES
+#define CURL_STRICTER
+#endif
+
 #include "curlver.h"         /* libcurl version defines   */
 #include "curlbuild.h"       /* libcurl build definitions */
 #include "curlrules.h"       /* libcurl rules enforcement */
@@ -139,7 +143,7 @@
   char *buffer;                     /* pointer to allocated buffer contents */
   long bufferlength;                /* length of buffer field */
   char *contenttype;                /* Content-Type */
-  struct curl_slist* contentheader; /* list of extra headers for this form */
+  struct curl_slist *contentheader; /* list of extra headers for this form */
   struct curl_httppost *more;       /* if one field name has more than one
                                        file, this link should link to following
                                        files */
@@ -266,7 +270,7 @@
   unsigned int flags;
 
   /* used internally */
-  char * b_data;
+  char *b_data;
   size_t b_size;
   size_t b_used;
 };
@@ -431,7 +435,7 @@
   CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
   CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
   CURLE_COULDNT_CONNECT,         /* 7 */
-  CURLE_FTP_WEIRD_SERVER_REPLY,  /* 8 */
+  CURLE_WEIRD_SERVER_REPLY,      /* 8 */
   CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
                                     due to lack of access - when login fails
                                     this is not returned. */
@@ -562,6 +566,7 @@
 
 /*  compatibility with older names */
 #define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
 
 /* The following were added in 7.21.5, April 2011 */
 #define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
@@ -635,6 +640,7 @@
                            CONNECT HTTP/1.1 */
   CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
                                HTTP/1.0  */
+  CURLPROXY_HTTPS = 2, /* added in TBD */
   CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
                            in 7.10 */
   CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
@@ -1201,7 +1207,8 @@
   CINIT(SHARE, OBJECTPOINT, 100),
 
   /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
-     CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+     CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
+     CURLPROXY_SOCKS5. */
   CINIT(PROXYTYPE, LONG, 101),
 
   /* Set the Accept-Encoding string. Use this to tell a server you would like
@@ -1695,6 +1702,74 @@
   /* Set TCP Fast Open */
   CINIT(TCP_FASTOPEN, LONG, 244),
 
+  /* Continue to send data if the server responds early with an
+   * HTTP status code >= 300 */
+  CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
+
+  /* The CApath or CAfile used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAINFO, STRINGPOINT, 246),
+
+  /* The CApath directory used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAPATH, STRINGPOINT, 247),
+
+  /* Set if we should verify the proxy in ssl handshake,
+     set 1 to verify. */
+  CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
+
+  /* Set if we should verify the Common name from the proxy certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches
+   * the provided hostname. */
+  CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
+
+  /* What version to specifically try to use for proxy.
+     See CURL_SSLVERSION defines below. */
+  CINIT(PROXY_SSLVERSION, LONG, 250),
+
+  /* Set a username for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
+
+  /* Set a password for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
+
+  /* Set authentication type for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
+
+  /* name of the file keeping your private SSL-certificate for proxy */
+  CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
+
+  /* name of the file keeping your private SSL-key for proxy */
+  CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
+
+  /* password for the SSL private key for proxy */
+  CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
+
+  /* Specify which SSL ciphers to use for proxy */
+  CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
+
+  /* CRL file for proxy */
+  CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
+
+  /* Enable/disable specific SSL features with a bitmask for proxy, see
+     CURLSSLOPT_* */
+  CINIT(PROXY_SSL_OPTIONS, LONG, 261),
+
+  /* Name of socks proxy to use. */
+  CINIT(SOCKS_PROXY, STRINGPOINT, 262),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_SOCKS4,
+     CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+  CINIT(SOCKS_PROXYTYPE, LONG, 263),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -1796,6 +1871,7 @@
   CURL_SSLVERSION_TLSv1_0,
   CURL_SSLVERSION_TLSv1_1,
   CURL_SSLVERSION_TLSv1_2,
+  CURL_SSLVERSION_TLSv1_3,
 
   CURL_SSLVERSION_LAST /* never use, keep last */
 };
@@ -2200,9 +2276,12 @@
   CURLINFO_ACTIVESOCKET     = CURLINFO_SOCKET + 44,
   CURLINFO_TLS_SSL_PTR      = CURLINFO_SLIST  + 45,
   CURLINFO_HTTP_VERSION     = CURLINFO_LONG   + 46,
+  CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
+  CURLINFO_PROTOCOL         = CURLINFO_LONG   + 48,
+  CURLINFO_SCHEME           = CURLINFO_STRING + 49,
   /* Fill in new entries below here! */
 
-  CURLINFO_LASTONE          = 46
+  CURLINFO_LASTONE          = 49
 } CURLINFO;
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
diff --git a/include/curl/curlver.h b/include/curl/curlver.h
index 81563f2..10f07d9 100644
--- a/include/curl/curlver.h
+++ b/include/curl/curlver.h
@@ -30,13 +30,13 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.50.1-DEV"
+#define LIBCURL_VERSION "7.52.0-DEV"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 50
-#define LIBCURL_VERSION_PATCH 1
+#define LIBCURL_VERSION_MINOR 52
+#define LIBCURL_VERSION_PATCH 0
 
 /* 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 0x073201
+#define LIBCURL_VERSION_NUM 0x073400
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/include/curl/easy.h b/include/curl/easy.h
index afc766c..752c504 100644
--- a/include/curl/easy.h
+++ b/include/curl/easy.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -58,7 +58,7 @@
  * curl_easy_duphandle() for each new thread to avoid a series of identical
  * curl_easy_setopt() invokes in every thread.
  */
-CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
 
 /*
  * NAME curl_easy_reset()
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index 6ec8bcf..d20c192 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -151,7 +151,7 @@
   "curl_easy_setopt expects a curl_off_t argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_string,
               "curl_easy_setopt expects a "
-              "string (char* or char[]) argument for this option"
+              "string ('char *' or char[]) argument for this option"
   )
 _CURL_WARNING(_curl_easy_setopt_err_write_callback,
   "curl_easy_setopt expects a curl_write_callback argument for this option")
@@ -182,24 +182,25 @@
               "curl_easy_setopt expects a "
               "char buffer of CURL_ERROR_SIZE as argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_FILE,
-  "curl_easy_setopt expects a FILE* argument for this option")
+  "curl_easy_setopt expects a 'FILE *' argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_postfields,
-  "curl_easy_setopt expects a void* or char* argument for this option")
+  "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
-  "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+              "curl_easy_setopt expects a 'struct curl_httppost *' "
+              "argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_curl_slist,
-  "curl_easy_setopt expects a struct curl_slist* argument for this option")
+  "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
 _CURL_WARNING(_curl_easy_setopt_err_CURLSH,
   "curl_easy_setopt expects a CURLSH* argument for this option")
 
 _CURL_WARNING(_curl_easy_getinfo_err_string,
-  "curl_easy_getinfo expects a pointer to char * for this info")
+  "curl_easy_getinfo expects a pointer to 'char *' for this info")
 _CURL_WARNING(_curl_easy_getinfo_err_long,
   "curl_easy_getinfo expects a pointer to long for this info")
 _CURL_WARNING(_curl_easy_getinfo_err_double,
   "curl_easy_getinfo expects a pointer to double for this info")
 _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
-  "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+  "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
 
 /* groups of curl_easy_setops options that take the same type of argument */
 
@@ -363,7 +364,7 @@
 
 /* XXX: should evaluate to true iff expr is a pointer */
 #define _curl_is_any_ptr(expr)                                                \
-  (sizeof(expr) == sizeof(void*))
+  (sizeof(expr) == sizeof(void *))
 
 /* evaluates to true if expr is NULL */
 /* XXX: must not evaluate expr, so this check is not accurate */
@@ -455,12 +456,12 @@
    _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
    _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
    _curl_callback_compatible((expr), _curl_read_callback6))
-typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
-typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
-typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
-typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
-typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
-typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_write_callback or "similar" */
 #define _curl_is_write_cb(expr)                                               \
@@ -473,14 +474,14 @@
    _curl_callback_compatible((expr), _curl_write_callback4) ||                \
    _curl_callback_compatible((expr), _curl_write_callback5) ||                \
    _curl_callback_compatible((expr), _curl_write_callback6))
-typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *);
 typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
-                                       const void*);
-typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
-typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+                                       const void *);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *);
 typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
-                                       const void*);
-typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+                                       const void *);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
 #define _curl_is_ioctl_cb(expr)                                         \
@@ -490,10 +491,10 @@
    _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
    _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
    _curl_callback_compatible((expr), _curl_ioctl_callback4))
-typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
-typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
-typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
-typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
 
 /* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
 #define _curl_is_sockopt_cb(expr)                                       \
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 49a3409..eb2de6d 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -87,6 +87,11 @@
 
 set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
 
+if(HIDES_CURL_PRIVATE_SYMBOLS)
+  set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
+  set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
+endif()
+
 # Remove the "lib" prefix since the library is already named "libcurl".
 set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 0ed998c..19f5800 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -40,31 +40,31 @@
 LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
   cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c       \
   ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c         \
-  getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c      \
+  getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c       \
   fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
   strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c  \
   http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
   strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
   inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
-  ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c            \
+  ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c            \
   curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
   pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
   openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
   http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c      \
-  http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c               \
+  http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.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
 
 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         \
   speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h        \
-  strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h         \
+  strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h          \
   wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h      \
   hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
   http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h         \
   inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h    \
   easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h     \
-  socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h      \
+  socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h      \
   slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h     \
   rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h              \
   curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h           \
@@ -72,7 +72,7 @@
   curl_sasl.h curl_multibyte.h hostcheck.h conncache.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
+  curl_printf.h system_win32.h rand.h
 
 LIB_RCFILES = libcurl.rc
 
diff --git a/lib/Makefile.netware b/lib/Makefile.netware
index ee7e87c..f689a36 100644
--- a/lib/Makefile.netware
+++ b/lib/Makefile.netware
@@ -87,7 +87,7 @@
 TARGET  = libcurl
 VERSION	= $(LIBCURL_VERSION)
 COPYR	= Copyright (C) $(LIBCURL_COPYRIGHT_STR)
-DESCR	= cURL libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
+DESCR	= curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
 MTSAFE	= YES
 STACK	= 64000
 SCREEN	= none
diff --git a/lib/Makefile.vc6 b/lib/Makefile.vc6
index e783e3a..d028428 100644
--- a/lib/Makefile.vc6
+++ b/lib/Makefile.vc6
@@ -601,7 +601,8 @@
 	$(DIROBJ)\polarssl_threadlock.obj \

 	$(DIROBJ)\pop3.obj \

 	$(DIROBJ)\progress.obj \

-	$(DIROBJ)\rawstr.obj \

+	$(DIROBJ)\strcase.obj \

+	$(DIROBJ)\rand.obj \

 	$(DIROBJ)\rtsp.obj \

 	$(DIROBJ)\schannel.obj \

 	$(DIROBJ)\security.obj \

@@ -633,7 +634,6 @@
 	$(DIROBJ)\vtls.obj \

 	$(DIROBJ)\openssl.obj \

 	$(DIROBJ)\strdup.obj \

-	$(DIROBJ)\strequal.obj \

 	$(DIROBJ)\strerror.obj \

 	$(DIROBJ)\strtok.obj \

 	$(DIROBJ)\strtoofft.obj \

diff --git a/lib/amigaos.c b/lib/amigaos.c
index 5591d22..4f55b30 100644
--- a/lib/amigaos.c
+++ b/lib/amigaos.c
@@ -57,7 +57,7 @@
   }
 
   if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
-                    SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
+                    SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
                     TAG_DONE)) {
     __request("SocketBaseTags ERROR");
     return FALSE;
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 7cce01a..da444f0 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -155,8 +155,8 @@
   curl_mutex_t * mtx;
   int done;
 
-  char * hostname;        /* hostname to resolve, Curl_async.hostname
-                             duplicate */
+  char *hostname;        /* hostname to resolve, Curl_async.hostname
+                            duplicate */
   int port;
   int sock_error;
   Curl_addrinfo *res;
@@ -169,7 +169,7 @@
 struct thread_data {
   curl_thread_t thread_hnd;
   unsigned int poll_interval;
-  long interval_end;
+  time_t interval_end;
   struct thread_sync_data tsd;
 };
 
@@ -200,7 +200,7 @@
 /* Initialize resolver thread synchronization data */
 static
 int init_thread_sync_data(struct thread_data * td,
-                           const char * hostname,
+                           const char *hostname,
                            int port,
                            const struct addrinfo *hints)
 {
@@ -382,7 +382,7 @@
   struct thread_data *td = calloc(1, sizeof(struct thread_data));
   int err = RESOLVER_ENOMEM;
 
-  conn->async.os_specific = (void*) td;
+  conn->async.os_specific = (void *)td;
   if(!td)
     goto err_exit;
 
@@ -525,7 +525,7 @@
   }
   else {
     /* poll for name lookup done with exponential backoff up to 250ms */
-    long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+    time_t elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
     if(elapsed < 0)
       elapsed = 0;
 
diff --git a/lib/base64.c b/lib/base64.c
index ad25459..204a227 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -190,6 +190,11 @@
   if(!insize)
     insize = strlen(indata);
 
+#if SIZEOF_SIZE_T == 4
+  if(insize > UINT_MAX/4)
+    return CURLE_OUT_OF_MEMORY;
+#endif
+
   base64data = output = malloc(insize * 4 / 3 + 4);
   if(!output)
     return CURLE_OUT_OF_MEMORY;
diff --git a/lib/checksrc.pl b/lib/checksrc.pl
index f31083a..479a5db 100755
--- a/lib/checksrc.pl
+++ b/lib/checksrc.pl
@@ -55,7 +55,9 @@
     'COPYRIGHT'        => 'file missing a copyright statement',
     'BADCOMMAND'       => 'bad !checksrc! instruction',
     'UNUSEDIGNORE'     => 'a warning ignore was not used',
-    'OPENCOMMENT'      => 'file ended with a /* comment still "open"'
+    'OPENCOMMENT'      => 'file ended with a /* comment still "open"',
+    'ASTERISKSPACE'    => 'pointer declared with space after asterisk',
+    'ASTERISKNOSPACE'  => 'pointer declared without space before asterisk'
     );
 
 sub readwhitelist {
@@ -423,6 +425,7 @@
         # scan for use of banned functions
         if($l =~ /^(.*\W)
                    (gets|
+	            strtok|
                     v?sprintf|
                     (str|_mbs|_tcs|_wcs)n?cat|
                     LoadLibrary(Ex)?(A|W)?)
@@ -470,6 +473,31 @@
             }
         }
 
+        # check for 'char * name'
+        if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) {
+            checkwarn("ASTERISKNOSPACE",
+                      $line, length($1), $file, $ol,
+                      "no space after declarative asterisk");
+        }
+        # check for 'char*'
+        if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
+            checkwarn("ASTERISKNOSPACE",
+                      $line, length($1)-1, $file, $ol,
+                      "no space before asterisk");
+        }
+
+        # check for 'void func() {', but avoid false positives by requiring
+        # both an open and closed parentheses before the open brace
+        if($l =~ /^((\w).*){\z/) {
+            my $k = $1;
+            $k =~ s/const *//;
+            $k =~ s/static *//;
+            if($k =~ /\(.*\)/) {
+                checkwarn("BRACEPOS",
+                          $line, length($l)-1, $file, $ol,
+                          "wrongly placed open brace");
+            }
+        }
         $line++;
         $prevl = $ol;
     }
diff --git a/lib/config-symbian.h b/lib/config-symbian.h
index 2603a46..92983d2 100644
--- a/lib/config-symbian.h
+++ b/lib/config-symbian.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -676,7 +676,7 @@
 /*#define RANDOM_FILE "/dev/urandom"*/
 
 #define RECV_TYPE_ARG1 int
-#define RECV_TYPE_ARG2 void*
+#define RECV_TYPE_ARG2 void *
 #define RECV_TYPE_ARG3 size_t
 #define RECV_TYPE_ARG4 int
 #define RECV_TYPE_RETV ssize_t
@@ -692,7 +692,7 @@
 
 #define SEND_TYPE_ARG1 int
 #define SEND_QUAL_ARG2 const
-#define SEND_TYPE_ARG2 void*
+#define SEND_TYPE_ARG2 void *
 #define SEND_TYPE_ARG3 size_t
 #define SEND_TYPE_ARG4 int
 #define SEND_TYPE_RETV ssize_t
diff --git a/lib/conncache.c b/lib/conncache.c
index 32a7030..d8ef9a5 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -30,7 +30,6 @@
 #include "progress.h"
 #include "multiif.h"
 #include "sendf.h"
-#include "rawstr.h"
 #include "conncache.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -133,8 +132,10 @@
 {
   const char *hostname;
 
-  if(conn->bits.proxy)
-    hostname = conn->proxy.name;
+  if(conn->bits.socksproxy)
+    hostname = conn->socks_proxy.host.name;
+  else if(conn->bits.httpproxy)
+    hostname = conn->http_proxy.host.name;
   else if(conn->bits.conn_to_host)
     hostname = conn->conn_to_host.name;
   else
diff --git a/lib/connect.c b/lib/connect.c
index 0047f9a..c78d3da 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -179,12 +179,12 @@
  *
  * @unittest: 1303
  */
-long Curl_timeleft(struct Curl_easy *data,
-                   struct timeval *nowp,
-                   bool duringconnect)
+time_t Curl_timeleft(struct Curl_easy *data,
+                     struct timeval *nowp,
+                     bool duringconnect)
 {
   int timeout_set = 0;
-  long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
+  time_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
   struct timeval now;
 
   /* if a timeout is set, use the most restrictive one */
@@ -601,26 +601,28 @@
 {
   memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
   memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
+  conn->data->info.conn_scheme = conn->handler->scheme;
+  conn->data->info.conn_protocol = conn->handler->protocol;
   conn->data->info.conn_primary_port = conn->primary_port;
   conn->data->info.conn_local_port = conn->local_port;
 }
 
 /* retrieves ip address and port from a sockaddr structure */
-static bool getaddressinfo(struct sockaddr* sa, char* addr,
-                           long* port)
+static bool getaddressinfo(struct sockaddr *sa, char *addr,
+                           long *port)
 {
   unsigned short us_port;
-  struct sockaddr_in* si = NULL;
+  struct sockaddr_in *si = NULL;
 #ifdef ENABLE_IPV6
-  struct sockaddr_in6* si6 = NULL;
+  struct sockaddr_in6 *si6 = NULL;
 #endif
 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
-  struct sockaddr_un* su = NULL;
+  struct sockaddr_un *su = NULL;
 #endif
 
   switch (sa->sa_family) {
     case AF_INET:
-      si = (struct sockaddr_in*)(void*) sa;
+      si = (struct sockaddr_in *)(void *) sa;
       if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
                         addr, MAX_IPADR_LEN)) {
         us_port = ntohs(si->sin_port);
@@ -630,7 +632,7 @@
       break;
 #ifdef ENABLE_IPV6
     case AF_INET6:
-      si6 = (struct sockaddr_in6*)(void*) sa;
+      si6 = (struct sockaddr_in6 *)(void *) sa;
       if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
                         addr, MAX_IPADR_LEN)) {
         us_port = ntohs(si6->sin6_port);
@@ -722,7 +724,7 @@
 {
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
-  long allow;
+  time_t allow;
   int error = 0;
   struct timeval now;
   int rc;
@@ -762,7 +764,7 @@
 #endif
 
     /* check socket for connect */
-    rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
+    rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
 
     if(rc == 0) { /* no connection yet */
       error = 0;
@@ -843,7 +845,7 @@
   if(result) {
     /* no more addresses to try */
 
-    const char* hostname;
+    const char *hostname;
 
     /* if the first address family runs out of addresses to try before
        the happy eyeball timeout, go ahead and try the next family now */
@@ -853,8 +855,10 @@
         return result;
     }
 
-    if(conn->bits.proxy)
-      hostname = conn->proxy.name;
+    if(conn->bits.socksproxy)
+      hostname = conn->socks_proxy.host.name;
+    else if(conn->bits.httpproxy)
+      hostname = conn->http_proxy.host.name;
     else if(conn->bits.conn_to_host)
       hostname = conn->conn_to_host.name;
     else
@@ -1153,7 +1157,7 @@
   struct timeval before = Curl_tvnow();
   CURLcode result = CURLE_COULDNT_CONNECT;
 
-  long timeout_ms = Curl_timeleft(data, &before, TRUE);
+  time_t timeout_ms = Curl_timeleft(data, &before, TRUE);
 
   if(timeout_ms < 0) {
     /* a precaution, no need to continue if time already is up */
@@ -1368,25 +1372,26 @@
 
 }
 
-#ifdef CURLDEBUG
 /*
- * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
- * MUST be called with the connclose() or connkeep() macros with a stated
- * reason. The reason is only shown in debug builds but helps to figure out
- * decision paths when connections are or aren't re-used as expected.
+ * Curl_conncontrol() marks streams or connection for closure.
  */
-void Curl_conncontrol(struct connectdata *conn, bool closeit,
-                      const char *reason)
-{
-#if defined(CURL_DISABLE_VERBOSE_STRINGS)
-  (void) reason;
+void Curl_conncontrol(struct connectdata *conn,
+                      int ctrl /* see defines in header */
+#ifdef DEBUGBUILD
+                      , const char *reason
 #endif
-  if(closeit != conn->bits.close) {
-    infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
-          reason);
-
+  )
+{
+  /* close if a connection, or a stream that isn't multiplexed */
+  bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
+    ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
+  if((ctrl == CONNCTRL_STREAM) &&
+     (conn->handler->flags & PROTOPT_STREAM))
+    DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
+  else if(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
                                    should assign this bit */
   }
 }
-#endif
diff --git a/lib/connect.h b/lib/connect.h
index 6d60e0d..5e48eb6 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,9 +35,9 @@
 
 /* generic function that returns how much time there's left to run, according
    to the timeouts set */
-long Curl_timeleft(struct Curl_easy *data,
-                   struct timeval *nowp,
-                   bool duringconnect);
+time_t Curl_timeleft(struct Curl_easy *data,
+                     struct timeval *nowp,
+                     bool duringconnect);
 
 #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
 #define HAPPY_EYEBALLS_TIMEOUT     200 /* milliseconds to wait between
@@ -104,21 +104,37 @@
 
 void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
 
-#ifdef CURLDEBUG
 /*
- * Curl_connclose() sets the bit.close bit to TRUE with an explanation.
- * Nothing else.
+ * Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
+ * argument specifies if it is the end of a connection or a stream.
+ *
+ * For stream-based protocols (such as HTTP/2), a stream close will not cause
+ * a connection close. Other protocols will close the connection for both
+ * cases.
+ *
+ * It sets the bit.close bit to TRUE (with an explanation for debug builds),
+ * when the connection will close.
  */
+
+#define CONNCTRL_KEEP 0 /* undo a marked closure */
+#define CONNCTRL_CONNECTION 1
+#define CONNCTRL_STREAM 2
+
 void Curl_conncontrol(struct connectdata *conn,
-                      bool closeit,
-                      const char *reason);
-#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
-#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
+                      int closeit
+#ifdef DEBUGBUILD
+                      , const char *reason
+#endif
+  );
+
+#ifdef DEBUGBUILD
+#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
+#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
+#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
 #else /* if !CURLDEBUG */
-
-#define connclose(x,y) (x)->bits.close = TRUE
-#define connkeep(x,y) (x)->bits.close = FALSE
-
+#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
+#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
+#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
 #endif
 
 #endif /* HEADER_CURL_CONNECT_H */
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index fa36aca..5a5824d 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,8 +28,8 @@
 #include <curl/curl.h>
 #include "sendf.h"
 #include "content_encoding.h"
+#include "strdup.h"
 #include "curl_memory.h"
-
 #include "memdebug.h"
 
 /* Comment this out if zlib is always going to be at least ver. 1.2.0.4
@@ -371,12 +371,9 @@
   {
     /* Need more gzip header data state */
     ssize_t hlen;
-    unsigned char *oldblock = z->next_in;
-
     z->avail_in += (uInt)nread;
-    z->next_in = realloc(z->next_in, z->avail_in);
+    z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
     if(z->next_in == NULL) {
-      free(oldblock);
       return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
     }
     /* Append the new block of data to the previous one */
diff --git a/lib/cookie.c b/lib/cookie.c
index b06a139..3123851 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -89,13 +89,12 @@
 
 #include "urldata.h"
 #include "cookie.h"
-#include "strequal.h"
 #include "strtok.h"
 #include "sendf.h"
 #include "slist.h"
 #include "share.h"
 #include "strtoofft.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
 
@@ -125,7 +124,7 @@
   if(hostname_len < cookie_domain_len)
     return FALSE;
 
-  if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
+  if(!strcasecompare(cooke_domain, hostname+hostname_len-cookie_domain_len))
     return FALSE;
 
   /* A lead char of cookie_domain is not '.'.
@@ -146,12 +145,12 @@
  * matching cookie path and url path
  * RFC6265 5.1.4 Paths and Path-Match
  */
-static bool pathmatch(const char* cookie_path, const char* request_uri)
+static bool pathmatch(const char *cookie_path, const char *request_uri)
 {
   size_t cookie_path_len;
   size_t uri_path_len;
-  char* uri_path = NULL;
-  char* pos;
+  char *uri_path = NULL;
+  char *pos;
   bool ret = FALSE;
 
   /* cookie_path must not have last '/' separator. ex: /sample */
@@ -468,9 +467,9 @@
           /* this was a "<name>=" with no content, and we must allow
              'secure' and 'httponly' specified this weirdly */
           done = TRUE;
-          if(Curl_raw_equal("secure", name))
+          if(strcasecompare("secure", name))
             co->secure = TRUE;
-          else if(Curl_raw_equal("httponly", name))
+          else if(strcasecompare("httponly", name))
             co->httponly = TRUE;
           else if(sep)
             /* there was a '=' so we're not done parsing this field */
@@ -478,7 +477,7 @@
         }
         if(done)
           ;
-        else if(Curl_raw_equal("path", name)) {
+        else if(strcasecompare("path", name)) {
           strstore(&co->path, whatptr);
           if(!co->path) {
             badcookie = TRUE; /* out of memory bad */
@@ -490,7 +489,7 @@
             break;
           }
         }
-        else if(Curl_raw_equal("domain", name)) {
+        else if(strcasecompare("domain", name)) {
           bool is_ip;
           const char *dotp;
 
@@ -528,14 +527,14 @@
                   whatptr);
           }
         }
-        else if(Curl_raw_equal("version", name)) {
+        else if(strcasecompare("version", name)) {
           strstore(&co->version, whatptr);
           if(!co->version) {
             badcookie = TRUE;
             break;
           }
         }
-        else if(Curl_raw_equal("max-age", name)) {
+        else if(strcasecompare("max-age", name)) {
           /* Defined in RFC2109:
 
              Optional.  The Max-Age attribute defines the lifetime of the
@@ -551,7 +550,7 @@
             break;
           }
         }
-        else if(Curl_raw_equal("expires", name)) {
+        else if(strcasecompare("expires", name)) {
           strstore(&co->expirestr, whatptr);
           if(!co->expirestr) {
             badcookie = TRUE;
@@ -712,7 +711,7 @@
            As far as I can see, it is set to true when the cookie says
            .domain.com and to false when the domain is complete www.domain.com
         */
-        co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+        co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 2:
         /* It turns out, that sometimes the file format allows the path
@@ -741,7 +740,7 @@
         fields++; /* add a field and fall down to secure */
         /* FALLTHROUGH */
       case 3:
-        co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+        co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 4:
         co->expires = curlx_strtoofft(ptr, NULL, 10);
@@ -812,11 +811,12 @@
   clist = c->cookies;
   replace_old = FALSE;
   while(clist) {
-    if(Curl_raw_equal(clist->name, co->name)) {
+    if(strcasecompare(clist->name, co->name)) {
       /* the names are identical */
 
       if(clist->domain && co->domain) {
-        if(Curl_raw_equal(clist->domain, co->domain))
+        if(strcasecompare(clist->domain, co->domain) &&
+          (clist->tailmatch == co->tailmatch))
           /* The domains are identical */
           replace_old=TRUE;
       }
@@ -827,7 +827,7 @@
         /* the domains were identical */
 
         if(clist->spath && co->spath) {
-          if(Curl_raw_equal(clist->spath, co->spath)) {
+          if(strcasecompare(clist->spath, co->spath)) {
             replace_old = TRUE;
           }
           else
@@ -901,6 +901,35 @@
   return co;
 }
 
+/*
+ * 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)
+{
+  bool partial = FALSE;
+  while(1) {
+    char *b = fgets(buf, len, input);
+    if(b) {
+      size_t rlen = strlen(b);
+      if(rlen && (b[rlen-1] == '\n')) {
+        if(partial) {
+          partial = FALSE;
+          continue;
+        }
+        return b;
+      }
+      else
+        /* read a partial, discard the next piece that ends with newline */
+        partial = TRUE;
+    }
+    else
+      break;
+  }
+  return NULL;
+}
+
+
 /*****************************************************************************
  *
  * Curl_cookie_init()
@@ -937,7 +966,7 @@
   }
   c->running = FALSE; /* this is not running, this is init */
 
-  if(file && strequal(file, "-")) {
+  if(file && !strcmp(file, "-")) {
     fp = stdin;
     fromfile=FALSE;
   }
@@ -957,7 +986,7 @@
     line = malloc(MAX_COOKIE_LINE);
     if(!line)
       goto fail;
-    while(fgets(line, MAX_COOKIE_LINE, fp)) {
+    while(get_line(line, MAX_COOKIE_LINE, fp)) {
       if(checkprefix("Set-Cookie:", line)) {
         /* This is a cookie line, get it! */
         lineptr=&line[11];
@@ -1022,6 +1051,40 @@
   return 0;
 }
 
+#define CLONE(field)                     \
+  do {                                   \
+    if(src->field) {                     \
+      dup->field = strdup(src->field);   \
+      if(!dup->field)                    \
+        goto fail;                       \
+    }                                    \
+  } while(0)
+
+static struct Cookie *dup_cookie(struct Cookie *src)
+{
+  struct Cookie *dup = calloc(sizeof(struct Cookie), 1);
+  if(dup) {
+    CLONE(expirestr);
+    CLONE(domain);
+    CLONE(path);
+    CLONE(spath);
+    CLONE(name);
+    CLONE(value);
+    CLONE(maxage);
+    CLONE(version);
+    dup->expires = src->expires;
+    dup->tailmatch = src->tailmatch;
+    dup->secure = src->secure;
+    dup->livecookie = src->livecookie;
+    dup->httponly = src->httponly;
+  }
+  return dup;
+
+  fail:
+  freecookie(dup);
+  return NULL;
+}
+
 /*****************************************************************************
  *
  * Curl_cookie_getlist()
@@ -1066,7 +1129,7 @@
       /* now check if the domain is correct */
       if(!co->domain ||
          (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
-         ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
+         ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
         /* the right part of the host matches the domain stuff in the
            cookie data */
 
@@ -1077,11 +1140,8 @@
           /* and now, we know this is a match and we should create an
              entry for the return-linked-list */
 
-          newco = malloc(sizeof(struct Cookie));
+          newco = dup_cookie(co);
           if(newco) {
-            /* first, copy the whole source cookie: */
-            memcpy(newco, co, sizeof(struct Cookie));
-
             /* then modify our next */
             newco->next = mainco;
 
@@ -1093,12 +1153,7 @@
           else {
             fail:
             /* failure, clear up the allocated chain and return NULL */
-            while(mainco) {
-              co = mainco->next;
-              free(mainco);
-              mainco = co;
-            }
-
+            Curl_cookie_freelist(mainco);
             return NULL;
           }
         }
@@ -1150,7 +1205,7 @@
 void Curl_cookie_clearall(struct CookieInfo *cookies)
 {
   if(cookies) {
-    Curl_cookie_freelist(cookies->cookies, TRUE);
+    Curl_cookie_freelist(cookies->cookies);
     cookies->cookies = NULL;
     cookies->numcookies = 0;
   }
@@ -1162,21 +1217,14 @@
  *
  * Free a list of cookies previously returned by Curl_cookie_getlist();
  *
- * The 'cookiestoo' argument tells this function whether to just free the
- * list or actually also free all cookies within the list as well.
- *
  ****************************************************************************/
 
-void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
+void Curl_cookie_freelist(struct Cookie *co)
 {
   struct Cookie *next;
   while(co) {
     next = co->next;
-    if(cookiestoo)
-      freecookie(co);
-    else
-      free(co); /* we only free the struct since the "members" are all just
-                   pointed out in the main cookie list! */
+    freecookie(co);
     co = next;
   }
 }
@@ -1231,7 +1279,7 @@
 {
   if(c) {
     free(c->filename);
-    Curl_cookie_freelist(c->cookies, TRUE);
+    Curl_cookie_freelist(c->cookies);
     free(c); /* free the base struct as well */
   }
 }
@@ -1289,7 +1337,7 @@
   /* at first, remove expired cookies */
   remove_expired(c);
 
-  if(strequal("-", dumphere)) {
+  if(!strcmp("-", dumphere)) {
     /* use stdout */
     out = stdout;
     use_stdout=TRUE;
diff --git a/lib/cookie.h b/lib/cookie.h
index cd7c54a..a9a4578 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 @@
 
 struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
                                    const char *, bool);
-void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
+void Curl_cookie_freelist(struct Cookie *cookies);
 void Curl_cookie_clearall(struct CookieInfo *cookies);
 void Curl_cookie_clearsess(struct CookieInfo *cookies);
 
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index 65a414b..33c15cb 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -67,7 +67,7 @@
 #cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
 
 /* to make a symbol visible */
-#cmakedefine CURL_EXTERN_SYMBOL 1
+#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
 /* Ensure using CURL_EXTERN_SYMBOL is possible */
 #ifndef CURL_EXTERN_SYMBOL
 #define CURL_EXTERN_SYMBOL
@@ -906,6 +906,9 @@
 /* Define if you want to enable POSIX threaded DNS lookup */
 #cmakedefine USE_THREADS_POSIX 1
 
+/* Define if you want to enable WIN32 threaded DNS lookup */
+#cmakedefine USE_THREADS_WIN32 1
+
 /* Define to disable non-blocking sockets. */
 #cmakedefine USE_BLOCKING_SOCKETS 1
 
@@ -933,11 +936,13 @@
 /* if OpenSSL is in use */
 #cmakedefine USE_OPENSSL 1
 
+/* to enable NGHTTP2  */
+#cmakedefine USE_NGHTTP2 1
+
 /* if Unix domain sockets are enabled  */
 #cmakedefine USE_UNIX_SOCKETS
 
-/* Define to 1 if you are building a Windows target without large file
-   support. */
+/* Define to 1 if you are building a Windows target with large file support. */
 #cmakedefine USE_WIN32_LARGE_FILES 1
 
 /* to enable SSPI support */
diff --git a/lib/curl_endian.c b/lib/curl_endian.c
index 76deca6..c2d21de 100644
--- a/lib/curl_endian.c
+++ b/lib/curl_endian.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +37,7 @@
  *
  * Returns the integer.
  */
-unsigned short Curl_read16_le(unsigned char *buf)
+unsigned short Curl_read16_le(const unsigned char *buf)
 {
   return (unsigned short)(((unsigned short)buf[0]) |
                           ((unsigned short)buf[1] << 8));
@@ -56,7 +56,7 @@
  *
  * Returns the integer.
  */
-unsigned int Curl_read32_le(unsigned char *buf)
+unsigned int Curl_read32_le(const unsigned char *buf)
 {
   return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
          ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
@@ -77,7 +77,7 @@
  * Returns the integer.
  */
 #if defined(HAVE_LONGLONG)
-unsigned long long Curl_read64_le(unsigned char *buf)
+unsigned long long Curl_read64_le(const unsigned char *buf)
 {
   return ((unsigned long long)buf[0]) |
          ((unsigned long long)buf[1] << 8) |
@@ -89,7 +89,7 @@
          ((unsigned long long)buf[7] << 56);
 }
 #else
-unsigned __int64 Curl_read64_le(unsigned char *buf)
+unsigned __int64 Curl_read64_le(const unsigned char *buf)
 {
   return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
          ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
@@ -113,7 +113,7 @@
  *
  * Returns the integer.
  */
-unsigned short Curl_read16_be(unsigned char *buf)
+unsigned short Curl_read16_be(const unsigned char *buf)
 {
   return (unsigned short)(((unsigned short)buf[0] << 8) |
                           ((unsigned short)buf[1]));
@@ -132,7 +132,7 @@
  *
  * Returns the integer.
  */
-unsigned int Curl_read32_be(unsigned char *buf)
+unsigned int Curl_read32_be(const unsigned char *buf)
 {
   return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
          ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
@@ -153,7 +153,7 @@
  * Returns the integer.
  */
 #if defined(HAVE_LONGLONG)
-unsigned long long Curl_read64_be(unsigned char *buf)
+unsigned long long Curl_read64_be(const unsigned char *buf)
 {
   return ((unsigned long long)buf[0] << 56) |
          ((unsigned long long)buf[1] << 48) |
@@ -165,7 +165,7 @@
          ((unsigned long long)buf[7]);
 }
 #else
-unsigned __int64 Curl_read64_be(unsigned char *buf)
+unsigned __int64 Curl_read64_be(const unsigned char *buf)
 {
   return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
          ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
diff --git a/lib/curl_endian.h b/lib/curl_endian.h
index df8398c..8a2b07a 100644
--- a/lib/curl_endian.h
+++ b/lib/curl_endian.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,32 +23,32 @@
  ***************************************************************************/
 
 /* Converts a 16-bit integer from little endian */
-unsigned short Curl_read16_le(unsigned char *buf);
+unsigned short Curl_read16_le(const unsigned char *buf);
 
 /* Converts a 32-bit integer from little endian */
-unsigned int Curl_read32_le(unsigned char *buf);
+unsigned int Curl_read32_le(const unsigned char *buf);
 
 #if (CURL_SIZEOF_CURL_OFF_T > 4)
 /* Converts a 64-bit integer from little endian */
 #if defined(HAVE_LONGLONG)
-unsigned long long Curl_read64_le(unsigned char *buf);
+unsigned long long Curl_read64_le(const unsigned char *buf);
 #else
-unsigned __int64 Curl_read64_le(unsigned char *buf);
+unsigned __int64 Curl_read64_le(const unsigned char *buf);
 #endif
 #endif
 
 /* Converts a 16-bit integer from big endian */
-unsigned short Curl_read16_be(unsigned char *buf);
+unsigned short Curl_read16_be(const unsigned char *buf);
 
 /* Converts a 32-bit integer from big endian */
-unsigned int Curl_read32_be(unsigned char *buf);
+unsigned int Curl_read32_be(const unsigned char *buf);
 
 #if (CURL_SIZEOF_CURL_OFF_T > 4)
 /* Converts a 64-bit integer from big endian */
 #if defined(HAVE_LONGLONG)
-unsigned long long Curl_read64_be(unsigned char *buf);
+unsigned long long Curl_read64_be(const unsigned char *buf);
 #else
-unsigned __int64 Curl_read64_be(unsigned char *buf);
+unsigned __int64 Curl_read64_be(const unsigned char *buf);
 #endif
 #endif
 
diff --git a/lib/curl_gethostname.c b/lib/curl_gethostname.c
index 2591fd8..8337c72 100644
--- a/lib/curl_gethostname.c
+++ b/lib/curl_gethostname.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -48,8 +48,8 @@
  * For libcurl static library release builds no overriding takes place.
  */
 
-int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
-
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
+{
 #ifndef HAVE_GETHOSTNAME
 
   /* Allow compilation and return failure when unavailable */
@@ -59,7 +59,7 @@
 
 #else
   int err;
-  char* dot;
+  char *dot;
 
 #ifdef DEBUGBUILD
 
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
index bf7c766..83f3fa0 100644
--- a/lib/curl_gssapi.c
+++ b/lib/curl_gssapi.c
@@ -94,7 +94,7 @@
     if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
       len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
                       "%.*s. ", (int)status_string.length,
-                      (char*)status_string.value);
+                      (char *)status_string.value);
     }
     gss_release_buffer(&min_stat, &status_string);
   } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
diff --git a/lib/curl_hmac.h b/lib/curl_hmac.h
index 41703b4..756dc9e 100644
--- a/lib/curl_hmac.h
+++ b/lib/curl_hmac.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,11 +24,11 @@
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
 
-typedef void    (* HMAC_hinit_func)(void * context);
-typedef void    (* HMAC_hupdate_func)(void * context,
-                                      const unsigned char * data,
+typedef void    (* HMAC_hinit_func)(void *context);
+typedef void    (* HMAC_hupdate_func)(void *context,
+                                      const unsigned char *data,
                                       unsigned int len);
-typedef void    (* HMAC_hfinal_func)(unsigned char * result, void * context);
+typedef void    (* HMAC_hfinal_func)(unsigned char *result, void *context);
 
 
 /* Per-hash function HMAC parameters. */
@@ -46,21 +46,21 @@
 /* HMAC computation context. */
 
 typedef struct {
-  const HMAC_params *   hmac_hash;      /* Hash function definition. */
-  void *                hmac_hashctxt1; /* Hash function context 1. */
-  void *                hmac_hashctxt2; /* Hash function context 2. */
+  const HMAC_params *hmac_hash; /* Hash function definition. */
+  void *hmac_hashctxt1;         /* Hash function context 1. */
+  void *hmac_hashctxt2;         /* Hash function context 2. */
 } HMAC_context;
 
 
 /* Prototypes. */
 
-HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams,
-                              const unsigned char * key,
+HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
+                              const unsigned char *key,
                               unsigned int keylen);
-int Curl_HMAC_update(HMAC_context * context,
-                     const unsigned char * data,
+int Curl_HMAC_update(HMAC_context *context,
+                     const unsigned char *data,
                      unsigned int len);
-int Curl_HMAC_final(HMAC_context * context, unsigned char * result);
+int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
 
 #endif
 
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index f3fb013..812a073 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -76,6 +76,11 @@
 #  define MD5_DIGEST_LENGTH 16
 #  define MD4_DIGEST_LENGTH 16
 
+#elif defined(USE_MBEDTLS)
+
+#  include <mbedtls/des.h>
+#  include <mbedtls/md4.h>
+
 #elif defined(USE_NSS)
 
 #  include <nss.h>
@@ -100,7 +105,7 @@
 
 #include "urldata.h"
 #include "non-ascii.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "curl_ntlm_core.h"
 #include "curl_md5.h"
 #include "curl_hmac.h"
@@ -188,6 +193,26 @@
   gcry_cipher_setkey(*des, key, sizeof(key));
 }
 
+#elif defined(USE_MBEDTLS)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  mbedtls_des_context ctx;
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  mbedtls_des_key_set_parity((unsigned char *) key);
+
+  /* Perform the encryption */
+  mbedtls_des_init(&ctx);
+  mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
+  return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
+}
+
 #elif defined(USE_NSS)
 
 /*
@@ -400,8 +425,8 @@
   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_DARWINSSL) || defined(USE_OS400CRYPTO) \
-  || defined(USE_WIN32_CRYPTO)
+#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
+  || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
   encrypt_des(plaintext, results, keys);
   encrypt_des(plaintext, results + 8, keys + 7);
   encrypt_des(plaintext, results + 16, keys + 14);
@@ -464,8 +489,8 @@
     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_DARWINSSL) || defined(USE_OS400CRYPTO) \
-  || defined(USE_WIN32_CRYPTO)
+#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
+  || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
     encrypt_des(magic, lmbuffer, pw);
     encrypt_des(magic, lmbuffer + 8, pw + 7);
 #endif
@@ -543,6 +568,8 @@
     gcry_md_write(MD4pw, pw, 2 * len);
     memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
     gcry_md_close(MD4pw);
+#elif defined(USE_MBEDTLS)
+    mbedtls_md4(pw, 2 * len, ntbuffer);
 #elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
     Curl_md4it(ntbuffer, pw, 2 * len);
 #elif defined(USE_DARWINSSL)
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index afdea16..4699d8f 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -51,6 +51,7 @@
 #include "curl_ntlm_wb.h"
 #include "url.h"
 #include "strerror.h"
+#include "strdup.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -293,11 +294,10 @@
       buf[len_out - 1] = '\0';
       break;
     }
-    newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
-    if(!newbuf) {
-      free(buf);
+    newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
+    if(!newbuf)
       return CURLE_OUT_OF_MEMORY;
-    }
+
     buf = newbuf;
   }
 
@@ -349,7 +349,7 @@
 
   if(proxy) {
     allocuserpwd = &conn->allocptr.proxyuserpwd;
-    userp = conn->proxyuser;
+    userp = conn->http_proxy.user;
     ntlm = &conn->proxyntlm;
     authp = &conn->data->state.authproxy;
   }
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 35e9fea..807f5de 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -42,8 +42,6 @@
 #include "curl_sasl.h"
 #include "warnless.h"
 #include "strtok.h"
-#include "strequal.h"
-#include "rawstr.h"
 #include "sendf.h"
 #include "non-ascii.h" /* included for Curl_convert_... prototypes */
 /* The last 3 #include files should be in this order */
@@ -159,7 +157,7 @@
     sasl->prefmech = SASL_AUTH_NONE;
   }
 
-  if(strnequal(value, "*", len))
+  if(!strncmp(value, "*", len))
     sasl->prefmech = SASL_AUTH_DEFAULT;
   else {
     mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
@@ -264,10 +262,13 @@
   size_t len = 0;
   saslstate state1 = SASL_STOP;
   saslstate state2 = SASL_FINAL;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
 #if defined(USE_KERBEROS5)
-  const char* service = data->set.str[STRING_SERVICE_NAME] ?
-                        data->set.str[STRING_SERVICE_NAME] :
-                        sasl->params->service;
+  const char *service = data->set.str[STRING_SERVICE_NAME] ?
+    data->set.str[STRING_SERVICE_NAME] :
+    sasl->params->service;
 #endif
 
   sasl->force_ir = force_ir;    /* Latch for future use */
@@ -288,7 +289,8 @@
   }
   else if(conn->bits.user_passwd) {
 #if defined(USE_KERBEROS5)
-    if(enabledmechs & SASL_MECH_GSSAPI) {
+    if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
+       Curl_auth_user_contains_domain(conn->user)) {
       sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
       mech = SASL_MECH_STRING_GSSAPI;
       state1 = SASL_GSSAPI;
@@ -308,7 +310,8 @@
     else
 #endif
 #ifndef CURL_DISABLE_CRYPTO_AUTH
-    if(enabledmechs & SASL_MECH_DIGEST_MD5) {
+    if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
+       Curl_auth_is_digest_supported()) {
       mech = SASL_MECH_STRING_DIGEST_MD5;
       state1 = SASL_DIGESTMD5;
       sasl->authused = SASL_MECH_DIGEST_MD5;
@@ -321,7 +324,7 @@
     else
 #endif
 #ifdef USE_NTLM
-    if(enabledmechs & SASL_MECH_NTLM) {
+    if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
       mech = SASL_MECH_STRING_NTLM;
       state1 = SASL_NTLM;
       state2 = SASL_NTLM_TYPE2MSG;
@@ -341,8 +344,8 @@
 
       if(force_ir || data->set.sasl_ir)
         result = Curl_auth_create_oauth_bearer_message(data, conn->user,
-                                                       conn->host.name,
-                                                       conn->port,
+                                                       hostname,
+                                                       port,
                                                        conn->oauth_bearer,
                                                        &resp, &len);
     }
@@ -408,6 +411,9 @@
   struct Curl_easy *data = conn->data;
   saslstate newstate = SASL_FINAL;
   char *resp = NULL;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
 #if !defined(CURL_DISABLE_CRYPTO_AUTH)
   char *serverdata;
   char *chlg = NULL;
@@ -542,8 +548,8 @@
     /* Create the authorisation message */
     if(sasl->authused == SASL_MECH_OAUTHBEARER) {
       result = Curl_auth_create_oauth_bearer_message(data, conn->user,
-                                                     conn->host.name,
-                                                     conn->port,
+                                                     hostname,
+                                                     port,
                                                      conn->oauth_bearer,
                                                      &resp, &len);
 
diff --git a/lib/curl_sec.h b/lib/curl_sec.h
index 3f94e14..073a981 100644
--- a/lib/curl_sec.h
+++ b/lib/curl_sec.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,8 +30,8 @@
   void (*end)(void *);
   int (*check_prot)(void *, int);
   int (*overhead)(void *, int, int);
-  int (*encode)(void *, const void*, int, int, void**);
-  int (*decode)(void *, void*, int, int, struct connectdata *);
+  int (*encode)(void *, const void *, int, int, void **);
+  int (*decode)(void *, void *, int, int, struct connectdata *);
 };
 
 #define AUTH_OK         0
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 3fe00dc..d267919 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -440,8 +440,8 @@
 
 #  ifdef __minix
      /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
-     extern char * strtok_r(char *s, const char *delim, char **last);
-     extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
+     extern char *strtok_r(char *s, const char *delim, char **last);
+     extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
 #  endif
 
 #  define DIR_CHAR      "/"
@@ -572,10 +572,9 @@
 #endif
 #endif
 
-#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
-/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
-   but we only work with libidn 0.4.1 or later) */
-#define USE_LIBIDN
+#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H)
+/* The lib and header are present */
+#define USE_LIBIDN2
 #endif
 
 #define LIBIDN_REQUIRED_VERSION "0.4.1"
@@ -606,6 +605,13 @@
     defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
 
 #define USE_NTLM
+
+#elif defined(USE_MBEDTLS)
+#  include <mbedtls/md4.h>
+#  if defined(MBEDTLS_MD4_C)
+#define USE_NTLM
+#  endif
+
 #endif
 #endif
 
@@ -714,4 +720,14 @@
 #  endif
 #endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
 
+/* Detect Windows App environment which has a restricted access
+ * to the Win32 APIs. */
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)
+#  include <winapifamily.h>
+#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
+     !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#    define CURL_WINDOWS_APP
+#  endif
+# endif
+
 #endif /* HEADER_CURL_SETUP_H */
diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c
index ee3f1b1..11a7120 100644
--- a/lib/curl_sspi.c
+++ b/lib/curl_sspi.c
@@ -64,6 +64,12 @@
  *
  * Once this function has been executed, Windows SSPI functions can be
  * called through the Security Service Provider Interface dispatch table.
+ *
+ * Parameters:
+ *
+ * None.
+ *
+ * Returns CURLE_OK on success.
  */
 CURLcode Curl_sspi_global_init(void)
 {
@@ -102,8 +108,11 @@
  * Curl_sspi_global_cleanup()
  *
  * This deinitializes the Security Service Provider Interface from libcurl.
+ *
+ * Parameters:
+ *
+ * None.
  */
-
 void Curl_sspi_global_cleanup(void)
 {
   if(s_hSecDll) {
@@ -205,6 +214,15 @@
   return CURLE_OK;
 }
 
+/*
+ * Curl_sspi_free_identity()
+ *
+ * This is used to free the contents of a SSPI identifier structure.
+ *
+ * Parameters:
+ *
+ * identity [in/out] - The identity structure.
+ */
 void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
 {
   if(identity) {
diff --git a/lib/curl_threads.c b/lib/curl_threads.c
index c98d8bb..d882698 100644
--- a/lib/curl_threads.c
+++ b/lib/curl_threads.c
@@ -59,7 +59,7 @@
   return 0;
 }
 
-curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
+curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
 {
   curl_thread_t t = malloc(sizeof(pthread_t));
   struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
@@ -100,7 +100,7 @@
 
 #elif defined(USE_THREADS_WIN32)
 
-curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
                                  void *arg)
 {
 #ifdef _WIN32_WCE
diff --git a/lib/curl_threads.h b/lib/curl_threads.h
index 8cbac63..0778dd5 100644
--- a/lib/curl_threads.h
+++ b/lib/curl_threads.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -50,7 +50,7 @@
 
 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
 
-curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
                                  void *arg);
 
 void Curl_thread_destroy(curl_thread_t hnd);
diff --git a/lib/curlx.h b/lib/curlx.h
index 448a34f..6168dc1 100644
--- a/lib/curlx.h
+++ b/lib/curlx.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -34,8 +34,8 @@
    functions while they still are offered publicly. They will be made library-
    private one day */
 
-#include "strequal.h"
-/* "strequal.h" provides the strequal protos */
+#include "strcase.h"
+/* "strcase.h" provides the strcasecompare protos */
 
 #include "strtoofft.h"
 /* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
@@ -67,15 +67,12 @@
    be removed from a future libcurl official API:
    curlx_getenv
    curlx_mprintf (and its variations)
-   curlx_strequal
-   curlx_strnequal
+   curlx_strcasecompare
+   curlx_strncasecompare
 
 */
 
 #define curlx_getenv curl_getenv
-#define curlx_strequal curl_strequal
-#define curlx_strnequal curl_strnequal
-#define curlx_raw_equal Curl_raw_equal
 #define curlx_mvsnprintf curl_mvsnprintf
 #define curlx_msnprintf curl_msnprintf
 #define curlx_maprintf curl_maprintf
diff --git a/lib/dict.c b/lib/dict.c
index a7b5965..69defc4 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -52,11 +52,10 @@
 #include <curl/curl.h>
 #include "transfer.h"
 #include "sendf.h"
-
+#include "escape.h"
 #include "progress.h"
-#include "strequal.h"
 #include "dict.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -96,12 +95,12 @@
   char *newp;
   char *dictp;
   char *ptr;
-  int len;
+  size_t len;
   char ch;
   int olen=0;
 
-  newp = curl_easy_unescape(data, inputbuff, 0, &len);
-  if(!newp)
+  CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
+  if(!newp || result)
     return NULL;
 
   dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
@@ -145,9 +144,9 @@
     /* AUTH is missing */
   }
 
-  if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
-      Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
-      Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
+  if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
+     strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
+     strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
 
     word = strchr(path, ':');
     if(word) {
@@ -203,9 +202,9 @@
     Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
                         -1, NULL); /* no upload */
   }
-  else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
-           Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
-           Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
+  else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
+          strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
+          strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
 
     word = strchr(path, ':');
     if(word) {
diff --git a/lib/easy.c b/lib/easy.c
index dc7139f..1242369 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -50,7 +50,6 @@
 #include <sys/param.h>
 #endif
 
-#include "strequal.h"
 #include "urldata.h"
 #include <curl/curl.h>
 #include "transfer.h"
@@ -144,28 +143,6 @@
   return CURLE_OK;
 }
 
-#ifdef USE_LIBIDN
-/*
- * Initialise use of IDNA library.
- * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
- * idna_to_ascii_lz().
- */
-static void idna_init (void)
-{
-#ifdef WIN32
-  char buf[60];
-  UINT cp = GetACP();
-
-  if(!getenv("CHARSET") && cp > 0) {
-    snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
-    putenv(buf);
-  }
-#else
-  /* to do? */
-#endif
-}
-#endif  /* USE_LIBIDN */
-
 /* true globals -- for curl_global_init() and curl_global_cleanup() */
 static unsigned int  initialized;
 static long          init_flags;
@@ -217,7 +194,7 @@
 #endif
 
 /**
- * curl_global_init() globally initializes cURL given a bitwise set of the
+ * curl_global_init() globally initializes curl given a bitwise set of the
  * different features of what to initialize.
  */
 static CURLcode global_init(long flags, bool memoryfuncs)
@@ -262,10 +239,6 @@
   }
 #endif
 
-#ifdef USE_LIBIDN
-  idna_init();
-#endif
-
   if(Curl_resolver_global_init()) {
     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
     return CURLE_FAILED_INIT;
@@ -292,7 +265,7 @@
 
 
 /**
- * curl_global_init() globally initializes cURL given a bitwise set of the
+ * curl_global_init() globally initializes curl given a bitwise set of the
  * different features of what to initialize.
  */
 CURLcode curl_global_init(long flags)
@@ -301,7 +274,7 @@
 }
 
 /*
- * curl_global_init_mem() globally initializes cURL and also registers the
+ * curl_global_init_mem() globally initializes curl and also registers the
  * user provided callback routines.
  */
 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
@@ -333,7 +306,7 @@
 }
 
 /**
- * curl_global_cleanup() globally cleanups cURL, uses the value of
+ * curl_global_cleanup() globally cleanups curl, uses the value of
  * "init_flags" to determine what needs to be cleaned up and what doesn't.
  */
 void curl_global_cleanup(void)
@@ -954,6 +927,8 @@
 
   Curl_convert_setup(outcurl);
 
+  Curl_initinfo(outcurl);
+
   outcurl->magic = CURLEASY_MAGIC_NUMBER;
 
   /* we reach this point and thus we are OK */
@@ -995,6 +970,9 @@
   /* zero out Progress data: */
   memset(&data->progress, 0, sizeof(struct Progress));
 
+  /* zero out PureInfo data: */
+  Curl_initinfo(data);
+
   data->progress.flags |= PGRS_HIDE;
   data->state.current_speed = -1; /* init to negative == impossible */
 }
@@ -1044,7 +1022,7 @@
   if(!result &&
      ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
       (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
-    Curl_expire(data, 1); /* get this handle going again */
+    Curl_expire(data, 0); /* get this handle going again */
 
   return result;
 }
diff --git a/lib/escape.c b/lib/escape.c
index 04230b4..9fb8d3e 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -31,6 +31,7 @@
 #include "warnless.h"
 #include "non-ascii.h"
 #include "escape.h"
+#include "strdup.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -78,15 +79,21 @@
 char *curl_easy_escape(struct Curl_easy *data, const char *string,
                        int inlength)
 {
-  size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
+  size_t alloc;
   char *ns;
   char *testing_ptr = NULL;
   unsigned char in; /* we need to treat the characters unsigned */
-  size_t newlen = alloc;
+  size_t newlen;
   size_t strindex=0;
   size_t length;
   CURLcode result;
 
+  if(inlength < 0)
+    return NULL;
+
+  alloc = (inlength?(size_t)inlength:strlen(string))+1;
+  newlen = alloc;
+
   ns = malloc(alloc);
   if(!ns)
     return NULL;
@@ -103,11 +110,9 @@
       newlen += 2; /* the size grows with two, since this'll become a %XX */
       if(newlen > alloc) {
         alloc *= 2;
-        testing_ptr = realloc(ns, alloc);
-        if(!testing_ptr) {
-          free(ns);
+        testing_ptr = Curl_saferealloc(ns, alloc);
+        if(!testing_ptr)
           return NULL;
-        }
         else {
           ns = testing_ptr;
         }
@@ -211,14 +216,22 @@
                          int length, int *olen)
 {
   char *str = NULL;
-  size_t inputlen = length;
-  size_t outputlen;
-  CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
-                                FALSE);
-  if(res)
-    return NULL;
-  if(olen)
-    *olen = curlx_uztosi(outputlen);
+  if(length >= 0) {
+    size_t inputlen = length;
+    size_t outputlen;
+    CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
+                                  FALSE);
+    if(res)
+      return NULL;
+
+    if(olen) {
+      if(outputlen <= (size_t) INT_MAX)
+        *olen = curlx_uztosi(outputlen);
+      else
+        /* too large to return in an int, fail! */
+        Curl_safefree(str);
+    }
+  }
   return str;
 }
 
diff --git a/lib/file.c b/lib/file.c
index b534ec1..3dbc0f2 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -190,14 +190,15 @@
   struct FILEPROTO *file = data->req.protop;
   int fd;
 #ifdef DOS_FILESYSTEM
-  int i;
+  size_t i;
   char *actual_path;
 #endif
-  int real_path_len;
+  size_t real_path_len;
 
-  real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
-  if(!real_path)
-    return CURLE_OUT_OF_MEMORY;
+  CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
+                                   &real_path_len, FALSE);
+  if(result)
+    return result;
 
 #ifdef DOS_FILESYSTEM
   /* If the first character is a slash, and there's
@@ -312,7 +313,7 @@
   curl_off_t bytecount = 0;
   struct timeval now = Curl_tvnow();
   struct_stat file_stat;
-  const char* buf2;
+  const char *buf2;
 
   /*
    * Since FILE: doesn't do the full init, we need to provide some extra
diff --git a/lib/formdata.c b/lib/formdata.c
index 673759d..2aef5fa 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -33,9 +33,10 @@
 #include "urldata.h" /* for struct Curl_easy */
 #include "formdata.h"
 #include "vtls/vtls.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "sendf.h"
 #include "strdup.h"
+#include "rand.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -80,7 +81,7 @@
             char *buffer, size_t bufferlength,
             char *contenttype,
             long flags,
-            struct curl_slist* contentHeader,
+            struct curl_slist *contentHeader,
             char *showfilename, char *userp,
             struct curl_httppost *parent_post,
             struct curl_httppost **httppost,
@@ -201,9 +202,9 @@
   if(filename) { /* in case a NULL was passed in */
     for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
       if(strlen(filename) >= strlen(ctts[i].extension)) {
-        if(strequal(filename +
-                    strlen(filename) - strlen(ctts[i].extension),
-                    ctts[i].extension)) {
+        if(strcasecompare(filename +
+                          strlen(filename) - strlen(ctts[i].extension),
+                          ctts[i].extension)) {
           contenttype = ctts[i].type;
           break;
         }
@@ -547,9 +548,9 @@
       {
         /* this "cast increases required alignment of target type" but
            we consider it OK anyway */
-        struct curl_slist* list = array_state?
-          (struct curl_slist*)(void*)array_value:
-          va_arg(params, struct curl_slist*);
+        struct curl_slist *list = array_state?
+          (struct curl_slist *)(void *)array_value:
+          va_arg(params, struct curl_slist *);
 
         if(current_form->contentheader)
           return_value = CURL_FORMADD_OPTION_TWICE;
@@ -761,8 +762,8 @@
  * and CD/DVD images should be either a STREAM_LF format or a fixed format.
  *
  */
-curl_off_t VmsRealFileSize(const char * name,
-                           const struct_stat * stat_buf)
+curl_off_t VmsRealFileSize(const char *name,
+                           const struct_stat *stat_buf)
 {
   char buffer[8192];
   curl_off_t count;
@@ -791,8 +792,8 @@
  *  if not to call a routine to get the correct size.
  *
  */
-static curl_off_t VmsSpecialSize(const char * name,
-                                 const struct_stat * stat_buf)
+static curl_off_t VmsSpecialSize(const char *name,
+                                 const struct_stat *stat_buf)
 {
   switch(stat_buf->st_fab_rfm) {
   case FAB$C_VAR:
@@ -845,16 +846,23 @@
       goto error;
     }
 #endif
+    if(type != FORM_DATAMEM) {
+      newform->line = malloc((size_t)length+1);
+      if(!newform->line) {
+        result = CURLE_OUT_OF_MEMORY;
+        goto error;
+      }
+      alloc2 = newform->line;
+      memcpy(newform->line, line, (size_t)length);
 
-    newform->line = malloc((size_t)length+1);
-    if(!newform->line) {
-      result = CURLE_OUT_OF_MEMORY;
-      goto error;
+      /* zero terminate for easier debugging */
+      newform->line[(size_t)length]=0;
     }
-    alloc2 = newform->line;
-    memcpy(newform->line, line, (size_t)length);
+    else {
+      newform->line = (char *)line;
+      type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
+    }
     newform->length = (size_t)length;
-    newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
   }
   else
     /* For callbacks and files we don't have any actual data so we just keep a
@@ -863,13 +871,6 @@
 
   newform->type = type;
 
-  if(*formp) {
-    (*formp)->next = newform;
-    *formp = newform;
-  }
-  else
-    *formp = newform;
-
   if(size) {
     if(type != FORM_FILE)
       /* for static content as well as callback data we add the size given
@@ -878,7 +879,7 @@
     else {
       /* Since this is a file to be uploaded here, add the size of the actual
          file */
-      if(!strequal("-", newform->line)) {
+      if(strcmp("-", newform->line)) {
         struct_stat file;
         if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
           *size += filesize(newform->line, file);
@@ -889,6 +890,14 @@
       }
     }
   }
+
+  if(*formp) {
+    (*formp)->next = newform;
+    *formp = newform;
+  }
+  else
+    *formp = newform;
+
   return CURLE_OK;
   error:
   if(newform)
@@ -906,13 +915,21 @@
                              curl_off_t *size,
                              const char *fmt, ...)
 {
-  char s[4096];
+  char *s;
+  CURLcode result;
   va_list ap;
   va_start(ap, fmt);
-  vsnprintf(s, sizeof(s), fmt, ap);
+  s = curl_mvaprintf(fmt, ap);
   va_end(ap);
 
-  return AddFormData(formp, FORM_DATA, s, 0, size);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
+  if(result)
+    free(s);
+
+  return result;
 }
 
 /*
@@ -1150,7 +1167,7 @@
   curl_off_t size = 0; /* support potentially ENORMOUS formposts */
   char *boundary;
   char *fileboundary = NULL;
-  struct curl_slist* curList;
+  struct curl_slist *curList;
 
   *finalform = NULL; /* default form is empty */
 
@@ -1289,7 +1306,7 @@
         /* we should include the contents from the specified file */
         FILE *fileread;
 
-        fileread = strequal("-", file->contents)?
+        fileread = !strcmp("-", file->contents)?
           stdin:fopen(file->contents, "rb"); /* binary read for win32  */
 
         /*
@@ -1410,7 +1427,8 @@
    *
    */
 # define fopen_read vmsfopenread
-static FILE * vmsfopenread(const char *file, const char *mode) {
+static FILE * vmsfopenread(const char *file, const char *mode)
+{
   struct_stat statbuf;
   int result;
 
@@ -1553,8 +1571,12 @@
 {
   /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
      combinations */
-  return aprintf("------------------------%08x%08x",
-                 Curl_rand(data), Curl_rand(data));
+  unsigned int rnd[2];
+  CURLcode result = Curl_rand(data, &rnd[0], 2);
+  if(result)
+    return NULL;
+
+  return aprintf("------------------------%08x%08x", rnd[0], rnd[1]);
 }
 
 #else  /* CURL_DISABLE_HTTP */
diff --git a/lib/formdata.h b/lib/formdata.h
index 6eb7c6c..69629f6 100644
--- a/lib/formdata.h
+++ b/lib/formdata.h
@@ -23,6 +23,7 @@
  ***************************************************************************/
 
 enum formtype {
+  FORM_DATAMEM, /* already allocated FORM_DATA memory */
   FORM_DATA,    /* form metadata (convert to network encoding if necessary) */
   FORM_CONTENT, /* form content  (never convert) */
   FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback
@@ -64,7 +65,7 @@
                          file name will be used */
   bool showfilename_alloc;
   char *userp;        /* pointer for the read callback */
-  struct curl_slist* contentheader;
+  struct curl_slist *contentheader;
   struct FormInfo *more;
 } FormInfo;
 
diff --git a/lib/ftp.c b/lib/ftp.c
index 8af6531..1e61fc5 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -61,7 +61,7 @@
 #include "ftplistparser.h"
 #include "curl_sec.h"
 #include "strtoofft.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "vtls/vtls.h"
 #include "connect.h"
 #include "strerror.h"
@@ -72,7 +72,7 @@
 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
 #include "multiif.h"
 #include "url.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "speedcheck.h"
 #include "warnless.h"
 #include "http_proxy.h"
@@ -384,10 +384,10 @@
  * Curl_pgrsTime(..., TIMER_STARTACCEPT);
  *
  */
-static long ftp_timeleft_accept(struct Curl_easy *data)
+static time_t ftp_timeleft_accept(struct Curl_easy *data)
 {
-  long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
-  long other;
+  time_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+  time_t other;
   struct timeval now;
 
   if(data->set.accepttimeout > 0)
@@ -430,7 +430,7 @@
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
   int result;
-  long timeout_ms;
+  time_t timeout_ms;
   ssize_t nread;
   int ftpcode;
 
@@ -475,7 +475,7 @@
       if(ftpcode/100 > 3)
         return CURLE_FTP_ACCEPT_FAILED;
 
-      return CURLE_FTP_WEIRD_SERVER_REPLY;
+      return CURLE_WEIRD_SERVER_REPLY;
     }
 
     break;
@@ -499,7 +499,7 @@
   struct FTP *ftp = data->req.protop;
   CURLcode result = CURLE_OK;
 
-  if(conn->ssl[SECONDARYSOCKET].use) {
+  if(conn->bits.ftp_use_data_ssl) {
     /* since we only have a plaintext TCP connection here, we must now
      * do the TLS stuff */
     infof(data, "Doing the SSL/TLS handshake on the data stream\n");
@@ -547,7 +547,7 @@
 static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
 {
   struct Curl_easy *data = conn->data;
-  long timeout_ms;
+  time_t timeout_ms;
   CURLcode result = CURLE_OK;
 
   *connected = FALSE;
@@ -687,8 +687,8 @@
    * line in a response or continue reading.  */
 
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-  long timeout;              /* timeout in milliseconds */
-  long interval_ms;
+  time_t timeout;              /* timeout in milliseconds */
+  time_t interval_ms;
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -740,8 +740,8 @@
        * wait for more data anyway.
        */
     }
-    else {
-      switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
+    else if(!Curl_ssl_data_pending(conn, FIRSTSOCKET)) {
+      switch (SOCKET_READABLE(sockfd, interval_ms)) {
       case -1: /* select() error, stop reading */
         failf(data, "FTP response aborted due to select/poll error: %d",
               SOCKERRNO);
@@ -911,7 +911,7 @@
     }
     else {
       socks[1] = conn->sock[SECONDARYSOCKET];
-      bits |= GETSOCK_WRITESOCK(1);
+      bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
     }
 
     return bits;
@@ -1835,7 +1835,7 @@
   if(conn->bits.ipv6) {
     /* We can't disable EPSV when doing IPv6, so this is instead a fail */
     failf(conn->data, "Failed EPSV attempt, exiting\n");
-    return CURLE_FTP_WEIRD_SERVER_REPLY;
+    return CURLE_WEIRD_SERVER_REPLY;
   }
 
   infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
@@ -1850,84 +1850,6 @@
   return result;
 }
 
-/*
- * Perform the necessary magic that needs to be done once the TCP connection
- * to the proxy has completed.
- */
-static CURLcode proxy_magic(struct connectdata *conn,
-                            char *newhost, unsigned short newport,
-                            bool *magicdone)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-
-#if defined(CURL_DISABLE_PROXY)
-  (void) newhost;
-  (void) newport;
-#endif
-
-  *magicdone = FALSE;
-
-  switch(conn->proxytype) {
-  case CURLPROXY_SOCKS5:
-  case CURLPROXY_SOCKS5_HOSTNAME:
-    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
-                         newport, SECONDARYSOCKET, conn);
-    *magicdone = TRUE;
-    break;
-  case CURLPROXY_SOCKS4:
-    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
-                         SECONDARYSOCKET, conn, FALSE);
-    *magicdone = TRUE;
-    break;
-  case CURLPROXY_SOCKS4A:
-    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
-                         SECONDARYSOCKET, conn, TRUE);
-    *magicdone = TRUE;
-    break;
-  case CURLPROXY_HTTP:
-  case CURLPROXY_HTTP_1_0:
-    /* do nothing here. handled later. */
-    break;
-  default:
-    failf(data, "unknown proxytype option given");
-    result = CURLE_COULDNT_CONNECT;
-    break;
-  }
-
-  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
-    /* BLOCKING */
-    /* We want "seamless" FTP operations through HTTP proxy tunnel */
-
-    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
-     * member conn->proto.http; we want FTP through HTTP and we have to
-     * change the member temporarily for connecting to the HTTP proxy. After
-     * Curl_proxyCONNECT we have to set back the member to the original
-     * struct FTP pointer
-     */
-    struct HTTP http_proxy;
-    struct FTP *ftp_save = data->req.protop;
-    memset(&http_proxy, 0, sizeof(http_proxy));
-    data->req.protop = &http_proxy;
-
-    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
-
-    data->req.protop = ftp_save;
-
-    if(result)
-      return result;
-
-    if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
-      /* the CONNECT procedure is not complete, the tunnel is not yet up */
-      state(conn, FTP_STOP); /* this phase is completed */
-      return result;
-    }
-    else
-      *magicdone = TRUE;
-  }
-
-  return result;
-}
 
 static char *control_address(struct connectdata *conn)
 {
@@ -1935,11 +1857,7 @@
      If a proxy tunnel is used, returns the original host name instead, because
      the effective control connection address is the proxy address,
      not the ftp host. */
-  if(conn->bits.tunnel_proxy ||
-     conn->proxytype == CURLPROXY_SOCKS5 ||
-     conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
-     conn->proxytype == CURLPROXY_SOCKS4 ||
-     conn->proxytype == CURLPROXY_SOCKS4A)
+  if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
     return conn->host.name;
 
   return conn->ip_addr_str;
@@ -2063,7 +1981,9 @@
      * here. We don't want to rely on a former host lookup that might've
      * expired now, instead we remake the lookup here and now!
      */
-    rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
+    const char * const host_name = conn->bits.socksproxy ?
+      conn->socks_proxy.host.name : conn->http_proxy.host.name;
+    rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
     if(rc == CURLRESOLV_PENDING)
       /* BLOCKING, ignores the return code but 'addr' will be NULL in
          case of failure */
@@ -2073,8 +1993,7 @@
       (unsigned short)conn->port; /* we connect to the proxy's port */
 
     if(!addr) {
-      failf(data, "Can't resolve proxy host %s:%hu",
-            conn->proxy.name, connectport);
+      failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
       return CURLE_FTP_CANT_GET_HOST;
     }
   }
@@ -2115,6 +2034,10 @@
     /* this just dumps information about this second connection */
     ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
 
+  Curl_safefree(conn->secondaryhostname);
+  conn->secondaryhostname = strdup(ftpc->newhost);
+  conn->secondary_port = ftpc->newport;
+
   Curl_resolv_unlock(data, addr); /* we're done using this address */
   conn->bits.do_more = TRUE;
   state(conn, FTP_STOP); /* this phase is completed */
@@ -2742,7 +2665,7 @@
       else if(ftpcode != 220) {
         failf(data, "Got a %03d ftp-server response when 220 was expected",
               ftpcode);
-        return CURLE_FTP_WEIRD_SERVER_REPLY;
+        return CURLE_WEIRD_SERVER_REPLY;
       }
 
       /* We have received a 220 response fine, now we proceed. */
@@ -2763,7 +2686,10 @@
       }
 #endif
 
-      if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+      if(data->set.use_ssl &&
+         (!conn->ssl[FIRSTSOCKET].use ||
+          (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
+           !conn->proxy_ssl[FIRSTSOCKET].use))) {
         /* We don't have a SSL/TLS connection yet, but FTPS is
            requested. Try a FTPS connection now */
 
@@ -2808,7 +2734,7 @@
         /* Curl_ssl_connect is BLOCKING */
         result = Curl_ssl_connect(conn, FIRSTSOCKET);
         if(!result) {
-          conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
+          conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
           result = ftp_state_user(conn);
         }
       }
@@ -2850,7 +2776,7 @@
     case FTP_PROT:
       if(ftpcode/100 == 2)
         /* We have enabled SSL for the data connection! */
-        conn->ssl[SECONDARYSOCKET].use =
+        conn->bits.ftp_use_data_ssl =
           (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
       /* FTP servers typically responds with 500 if they decide to reject
          our 'P' request */
@@ -2999,7 +2925,7 @@
 
         /* Check for special servers here. */
 
-        if(strequal(os, "OS/400")) {
+        if(strcasecompare(os, "OS/400")) {
           /* Force OS400 name format 1. */
           result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
           if(result) {
@@ -3165,7 +3091,7 @@
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
 
-  /* Check for the state outside of the Curl_socket_ready() return code checks
+  /* Check for the state outside of the Curl_socket_check() return code checks
      since at times we are in fact already in this state when this function
      gets called. */
   *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
@@ -3250,8 +3176,7 @@
   ssize_t nread;
   int ftpcode;
   CURLcode result = CURLE_OK;
-  bool was_ctl_valid = ftpc->ctl_valid;
-  char *path;
+  char *path = NULL;
   const char *path_to_use = data->state.path;
 
   if(!ftp)
@@ -3274,10 +3199,9 @@
     /* the connection stays alive fine even though this happened */
     /* fall-through */
   case CURLE_OK: /* doesn't affect the control connection's status */
-    if(!premature) {
-      ftpc->ctl_valid = was_ctl_valid;
+    if(!premature)
       break;
-    }
+
     /* until we cope better with prematurely ended requests, let them
      * fallback as if in complete failure */
   default:       /* by default, an error means the control connection is
@@ -3300,13 +3224,12 @@
     ftpc->known_filesize = -1;
   }
 
-  /* get the "raw" path */
-  path = curl_easy_unescape(data, path_to_use, 0, NULL);
-  if(!path) {
-    /* out of memory, but we can limp along anyway (and should try to
-     * since we may already be in the out of memory cleanup path) */
-    if(!result)
-      result = CURLE_OUT_OF_MEMORY;
+  if(!result)
+    /* get the "raw" path */
+    result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+  if(result) {
+    /* We can limp along anyway (and should try to since we may already be in
+     * the error path) */
     ftpc->ctl_valid = FALSE; /* mark control connection as bad */
     connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
     ftpc->prevpath = NULL; /* no path remembering */
@@ -3669,10 +3592,6 @@
     /* Ready to do more? */
     if(connected) {
       DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
-      if(conn->bits.proxy) {
-        infof(data, "Connection to proxy confirmed\n");
-        result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
-      }
     }
     else {
       if(result && (ftpc->count1 == 0)) {
@@ -3684,6 +3603,18 @@
     }
   }
 
+  result = Curl_proxy_connect(conn, SECONDARYSOCKET);
+  if(result)
+    return result;
+
+  if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
+    return result;
+
+  if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+     conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE)
+    return result;
+
+
   if(ftpc->state) {
     /* already in a state so skip the intial commands.
        They are only done to kickstart the do_more state */
@@ -4093,8 +4024,7 @@
 }
 
 
-CURLcode Curl_ftpsendf(struct connectdata *conn,
-                       const char *fmt, ...)
+CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
 {
   ssize_t bytes_written;
 #define SBUF_SIZE 1024
@@ -4106,10 +4036,9 @@
   enum protection_level data_sec = conn->data_prot;
 #endif
 
-  va_list ap;
-  va_start(ap, fmt);
-  write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap);
-  va_end(ap);
+  write_len = strlen(cmd);
+  if(write_len > (sizeof(s) -3))
+    return CURLE_BAD_FUNCTION_ARGUMENT;
 
   strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
   write_len +=2;
@@ -4251,8 +4180,8 @@
   const char *cur_pos;
   const char *filename = NULL;
 
-  cur_pos = path_to_use; /* current position in path. point at the begin
-                            of next path component */
+  cur_pos = path_to_use; /* current position in path. point at the begin of
+                            next path component */
 
   ftpc->ctl_valid = FALSE;
   ftpc->cwdfail = FALSE;
@@ -4291,6 +4220,7 @@
     slash_pos=strrchr(cur_pos, '/');
     if(slash_pos || !*cur_pos) {
       size_t dirlen = slash_pos-cur_pos;
+      CURLcode result;
 
       ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
       if(!ftpc->dirs)
@@ -4299,12 +4229,13 @@
       if(!dirlen)
         dirlen++;
 
-      ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
-                                         slash_pos ? curlx_uztosi(dirlen) : 1,
-                                         NULL);
-      if(!ftpc->dirs[0]) {
+      result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
+                              slash_pos ? dirlen : 1,
+                              &ftpc->dirs[0], NULL,
+                              FALSE);
+      if(result) {
         freedirs(ftpc);
-        return CURLE_OUT_OF_MEMORY;
+        return result;
       }
       ftpc->dirdepth = 1; /* we consider it to be a single dir */
       filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
@@ -4322,7 +4253,7 @@
       return CURLE_OUT_OF_MEMORY;
 
     /* we have a special case for listing the root dir only */
-    if(strequal(path_to_use, "/")) {
+    if(!strcmp(path_to_use, "/")) {
       cur_pos++; /* make it point to the zero byte */
       ftpc->dirs[0] = strdup("/");
       ftpc->dirdepth++;
@@ -4339,18 +4270,15 @@
           /* we skip empty path components, like "x//y" since the FTP command
              CWD requires a parameter and a non-existent parameter a) doesn't
              work on many servers and b) has no effect on the others. */
-          int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
-          ftpc->dirs[ftpc->dirdepth] =
-            curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
-          if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
-            failf(data, "no memory");
-            freedirs(ftpc);
-            return CURLE_OUT_OF_MEMORY;
-          }
-          if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
+          size_t len = slash_pos - cur_pos + absolute_dir;
+          CURLcode result =
+            Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
+                           &ftpc->dirs[ftpc->dirdepth], NULL,
+                           TRUE);
+          if(result) {
             free(ftpc->dirs[ftpc->dirdepth]);
             freedirs(ftpc);
-            return CURLE_URL_MALFORMAT;
+            return result;
           }
         }
         else {
@@ -4386,15 +4314,12 @@
   } /* switch */
 
   if(filename && *filename) {
-    ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
-    if(NULL == ftpc->file) {
+    CURLcode result =
+      Curl_urldecode(conn->data, filename, 0,  &ftpc->file, NULL, TRUE);
+
+    if(result) {
       freedirs(ftpc);
-      failf(data, "no memory");
-      return CURLE_OUT_OF_MEMORY;
-    }
-    if(isBadFtpString(ftpc->file)) {
-      freedirs(ftpc);
-      return CURLE_URL_MALFORMAT;
+      return result;
     }
   }
   else
@@ -4412,16 +4337,18 @@
   if(ftpc->prevpath) {
     /* prevpath is "raw" so we convert the input path before we compare the
        strings */
-    int dlen;
-    char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
-    if(!path) {
+    size_t dlen;
+    char *path;
+    CURLcode result =
+      Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
+    if(result) {
       freedirs(ftpc);
-      return CURLE_OUT_OF_MEMORY;
+      return result;
     }
 
-    dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
-    if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
-       strnequal(path, ftpc->prevpath, dlen)) {
+    dlen -= ftpc->file?strlen(ftpc->file):0;
+    if((dlen == strlen(ftpc->prevpath)) &&
+       !strncmp(path, ftpc->prevpath, dlen)) {
       infof(data, "Request has same path as previous transfer\n");
       ftpc->cwddone = TRUE;
     }
diff --git a/lib/ftp.h b/lib/ftp.h
index 2ed5b43..3bbf262 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 @@
 extern const struct Curl_handler Curl_handler_ftps;
 #endif
 
-CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
+CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
 CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
                              int *ftpcode);
 #endif /* CURL_DISABLE_FTP */
@@ -143,7 +143,7 @@
   ftpstate state_saved; /* transfer type saved to be reloaded after
                            data connection is established */
   curl_off_t retr_size_saved; /* Size of retrieved file saved */
-  char * server_os;     /* The target server operating system. */
+  char *server_os;     /* The target server operating system. */
   curl_off_t known_filesize; /* file size is different from -1, if wildcard
                                 LIST parsing was done and wc_statemach set
                                 it */
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index abbf76e..747dbba 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -45,7 +45,6 @@
 #include "fileinfo.h"
 #include "llist.h"
 #include "strtoofft.h"
-#include "rawstr.h"
 #include "ftp.h"
 #include "ftplistparser.h"
 #include "curl_fnmatch.h"
diff --git a/lib/getenv.c b/lib/getenv.c
index 50bb79f..89d181d 100644
--- a/lib/getenv.c
+++ b/lib/getenv.c
@@ -30,7 +30,8 @@
 static
 char *GetEnv(const char *variable)
 {
-#ifdef _WIN32_WCE
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+  (void)variable;
   return NULL;
 #else
 #ifdef WIN32
diff --git a/lib/getinfo.c b/lib/getinfo.c
index 262cd93..4459a48 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -36,8 +36,11 @@
 #include "memdebug.h"
 
 /*
- * This is supposed to be called in the beginning of a perform() session
- * and should reset all session-info variables
+ * Initialize statistical and informational data.
+ *
+ * This function is called in curl_easy_reset, curl_easy_duphandle and at the
+ * beginning of a perform session. It must reset the session-info variables,
+ * in particular all variables in struct PureInfo.
  */
 CURLcode Curl_initinfo(struct Curl_easy *data)
 {
@@ -58,23 +61,32 @@
   info->filetime = -1; /* -1 is an illegal time and thus means unknown */
   info->timecond = FALSE;
 
+  info->header_size = 0;
+  info->request_size = 0;
+  info->proxyauthavail = 0;
+  info->httpauthavail = 0;
+  info->numconnects = 0;
+
   free(info->contenttype);
   info->contenttype = NULL;
 
-  info->header_size = 0;
-  info->request_size = 0;
-  info->numconnects = 0;
+  free(info->wouldredirect);
+  info->wouldredirect = NULL;
 
   info->conn_primary_ip[0] = '\0';
   info->conn_local_ip[0] = '\0';
   info->conn_primary_port = 0;
   info->conn_local_port = 0;
 
+#ifdef USE_SSL
+  Curl_ssl_free_certinfo(data);
+#endif
+
   return CURLE_OK;
 }
 
 static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
-                             char **param_charp)
+                             const char **param_charp)
 {
   switch(info) {
   case CURLINFO_EFFECTIVE_URL:
@@ -111,6 +123,9 @@
   case CURLINFO_RTSP_SESSION_ID:
     *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
     break;
+  case CURLINFO_SCHEME:
+    *param_charp = data->info.conn_scheme;
+    break;
 
   default:
     return CURLE_UNKNOWN_OPTION;
@@ -148,6 +163,9 @@
   case CURLINFO_SSL_VERIFYRESULT:
     *param_longp = data->set.ssl.certverifyresult;
     break;
+  case CURLINFO_PROXY_SSL_VERIFYRESULT:
+    *param_longp = data->set.proxy_ssl.certverifyresult;
+    break;
   case CURLINFO_REDIRECT_COUNT:
     *param_longp = data->set.followlocation;
     break;
@@ -214,6 +232,9 @@
       break;
     }
     break;
+  case CURLINFO_PROTOCOL:
+    *param_longp = data->info.conn_protocol;
+    break;
 
   default:
     return CURLE_UNKNOWN_OPTION;
@@ -370,7 +391,7 @@
   va_list arg;
   long *param_longp = NULL;
   double *param_doublep = NULL;
-  char **param_charp = NULL;
+  const char **param_charp = NULL;
   struct curl_slist **param_slistp = NULL;
   curl_socket_t *param_socketp = NULL;
   int type;
@@ -384,7 +405,7 @@
   type = CURLINFO_TYPEMASK & (int)info;
   switch(type) {
   case CURLINFO_STRING:
-    param_charp = va_arg(arg, char **);
+    param_charp = va_arg(arg, const char **);
     if(param_charp)
       result = getinfo_char(data, info, param_charp);
     break;
diff --git a/lib/gopher.c b/lib/gopher.c
index f1efb60..a073d0b 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,13 +28,11 @@
 #include <curl/curl.h>
 #include "transfer.h"
 #include "sendf.h"
-
 #include "progress.h"
-#include "strequal.h"
 #include "gopher.h"
-#include "rawstr.h"
 #include "select.h"
 #include "url.h"
+#include "escape.h"
 #include "warnless.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -83,7 +81,7 @@
   char *sel;
   char *sel_org = NULL;
   ssize_t amount, k;
-  int len;
+  size_t len;
 
   *done = TRUE; /* unconditionally */
 
@@ -107,7 +105,7 @@
         newp[i] = '\x09';
 
     /* ... and finally unescape */
-    sel = curl_easy_unescape(data, newp, 0, &len);
+    result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
     if(!sel)
       return CURLE_OUT_OF_MEMORY;
     sel_org = sel;
@@ -121,20 +119,17 @@
     result = Curl_write(conn, sockfd, sel, k, &amount);
     if(!result) { /* Which may not have written it all! */
       result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
-      if(result) {
-        free(sel_org);
-        return result;
-      }
+      if(result)
+        break;
+
       k -= amount;
       sel += amount;
       if(k < 1)
         break; /* but it did write it all */
     }
-    else {
-      failf(data, "Failed sending Gopher request");
-      free(sel_org);
-      return result;
-    }
+    else
+      break;
+
     /* Don't busyloop. The entire loop thing is a work-around as it causes a
        BLOCKING behavior which is a NO-NO. This function should rather be
        split up in a do and a doing piece where the pieces that aren't
@@ -144,14 +139,18 @@
        Wait a while for the socket to be writable. Note that this doesn't
        acknowledge the timeout.
     */
-    Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
+    if(SOCKET_WRITABLE(sockfd, 100) < 0) {
+      result = CURLE_SEND_ERROR;
+      break;
+    }
   }
 
   free(sel_org);
 
-  /* We can use Curl_sendf to send the terminal \r\n relatively safely and
-     save allocing another string/doing another _write loop. */
-  result = Curl_sendf(sockfd, conn, "\r\n");
+  if(!result)
+    /* We can use Curl_sendf to send the terminal \r\n relatively safely and
+       save allocing another string/doing another _write loop. */
+    result = Curl_sendf(sockfd, conn, "\r\n");
   if(result) {
     failf(data, "Failed sending Gopher request");
     return result;
diff --git a/lib/hash.c b/lib/hash.c
index 937381b..72a7a9b 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -291,9 +291,9 @@
   }
 }
 
-size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
+size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num)
 {
-  const char* key_str = (const char *) key;
+  const char *key_str = (const char *) key;
   const char *end = key_str + key_length;
   unsigned long h = 5381;
 
diff --git a/lib/hash.h b/lib/hash.h
index 57a17f0..a5a6cac 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,16 +29,16 @@
 #include "llist.h"
 
 /* Hash function prototype */
-typedef size_t (*hash_function) (void* key,
+typedef size_t (*hash_function) (void *key,
                                  size_t key_length,
                                  size_t slots_num);
 
 /*
    Comparator function prototype. Compares two keys.
 */
-typedef size_t (*comp_function) (void* key1,
+typedef size_t (*comp_function) (void *key1,
                                  size_t key1_len,
-                                 void*key2,
+                                 void *key2,
                                  size_t key2_len);
 
 typedef void (*curl_hash_dtor)(void *);
@@ -76,7 +76,7 @@
 
 void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
 int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
-void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
+void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
 void Curl_hash_apply(struct curl_hash *h, void *user,
                      void (*cb)(void *user, void *ptr));
 int Curl_hash_count(struct curl_hash *h);
@@ -84,10 +84,9 @@
 void Curl_hash_clean(struct curl_hash *h);
 void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
                                     int (*comp)(void *, void *));
-size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num);
-size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2,
+size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num);
+size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2,
                             size_t key2_len);
-
 void Curl_hash_start_iterate(struct curl_hash *hash,
                              struct curl_hash_iterator *iter);
 struct curl_hash_element *
diff --git a/lib/hmac.c b/lib/hmac.c
index 3df4715..dae9505 100644
--- a/lib/hmac.c
+++ b/lib/hmac.c
@@ -49,12 +49,12 @@
 
 HMAC_context *
 Curl_HMAC_init(const HMAC_params * hashparams,
-               const unsigned char * key,
+               const unsigned char *key,
                unsigned int keylen)
 {
   size_t i;
-  HMAC_context * ctxt;
-  unsigned char * hkey;
+  HMAC_context *ctxt;
+  unsigned char *hkey;
   unsigned char b;
 
   /* Create HMAC context. */
@@ -101,7 +101,7 @@
 }
 
 int Curl_HMAC_update(HMAC_context * ctxt,
-                     const unsigned char * data,
+                     const unsigned char *data,
                      unsigned int len)
 {
   /* Update first hash calculation. */
@@ -110,7 +110,7 @@
 }
 
 
-int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result)
+int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
 {
   const HMAC_params * hashparams = ctxt->hmac_hash;
 
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index 4db9e6b..f545254 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -30,7 +30,7 @@
 #endif
 
 #include "hostcheck.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "inet_pton.h"
 
 #include "curl_memory.h"
@@ -77,7 +77,7 @@
 
   pattern_wildcard = strchr(pattern, '*');
   if(pattern_wildcard == NULL)
-    return Curl_raw_equal(pattern, hostname) ?
+    return strcasecompare(pattern, hostname) ?
       CURL_HOST_MATCH : CURL_HOST_NOMATCH;
 
   /* detect IP address as hostname and fail the match if so */
@@ -94,16 +94,16 @@
   pattern_label_end = strchr(pattern, '.');
   if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
      pattern_wildcard > pattern_label_end ||
-     Curl_raw_nequal(pattern, "xn--", 4)) {
+     strncasecompare(pattern, "xn--", 4)) {
     wildcard_enabled = 0;
   }
   if(!wildcard_enabled)
-    return Curl_raw_equal(pattern, hostname) ?
+    return strcasecompare(pattern, hostname) ?
       CURL_HOST_MATCH : CURL_HOST_NOMATCH;
 
   hostname_label_end = strchr(hostname, '.');
   if(hostname_label_end == NULL ||
-     !Curl_raw_equal(pattern_label_end, hostname_label_end))
+     !strcasecompare(pattern_label_end, hostname_label_end))
     return CURL_HOST_NOMATCH;
 
   /* The wildcard must match at least one character, so the left-most
@@ -114,8 +114,8 @@
 
   prefixlen = pattern_wildcard - pattern;
   suffixlen = pattern_label_end - (pattern_wildcard+1);
-  return Curl_raw_nequal(pattern, hostname, prefixlen) &&
-    Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
+  return strncasecompare(pattern, hostname, prefixlen) &&
+    strncasecompare(pattern_wildcard+1, hostname_label_end - suffixlen,
                     suffixlen) ?
     CURL_HOST_MATCH : CURL_HOST_NOMATCH;
 }
diff --git a/lib/hostip.c b/lib/hostip.c
index f2d9841..464fa4e 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -568,7 +568,7 @@
                         const char *hostname,
                         int port,
                         struct Curl_dns_entry **entry,
-                        long timeoutms)
+                        time_t timeoutms)
 {
 #ifdef USE_ALARM_TIMEOUT
 #ifdef HAVE_SIGACTION
@@ -603,11 +603,14 @@
     /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
     return Curl_resolv(conn, hostname, port, entry);
 
-  if(timeout < 1000)
+  if(timeout < 1000) {
     /* The alarm() function only provides integer second resolution, so if
        we want to wait less than one second we must bail out already now. */
+    failf(data,
+        "remaining timeout of %ld too small to resolve via SIGALRM method",
+        timeout);
     return CURLRESOLV_TIMEDOUT;
-
+  }
   /* This allows us to time-out from the name resolver, as the timeout
      will generate a signal and we will siglongjmp() from that here.
      This technique has problems (see alarmfunc).
diff --git a/lib/hostip.h b/lib/hostip.h
index 9098ee3..0924d54 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -87,7 +87,7 @@
                 int port, struct Curl_dns_entry **dnsentry);
 int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
                         int port, struct Curl_dns_entry **dnsentry,
-                        long timeoutms);
+                        time_t timeoutms);
 
 #ifdef CURLRES_IPV6
 /*
@@ -143,7 +143,7 @@
 #endif
 
 /* IPv4 threadsafe resolve function used for synch and asynch builds */
-Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
+Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
 
 CURLcode Curl_async_resolved(struct connectdata *conn,
                              bool *protocol_connect);
diff --git a/lib/hostip4.c b/lib/hostip4.c
index 15895d7..e459328 100644
--- a/lib/hostip4.c
+++ b/lib/hostip4.c
@@ -291,7 +291,7 @@
      * gethostbyname() is the preferred one.
      */
   else {
-    h = gethostbyname((void*)hostname);
+    h = gethostbyname((void *)hostname);
 #endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
   }
 
diff --git a/lib/http.c b/lib/http.c
index 378d8f7..36317f5 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -53,7 +53,6 @@
 #include "progress.h"
 #include "curl_base64.h"
 #include "cookie.h"
-#include "strequal.h"
 #include "vauth/vauth.h"
 #include "vtls/vtls.h"
 #include "http_digest.h"
@@ -68,7 +67,7 @@
 #include "parsedate.h" /* for the week day and month names */
 #include "strtoofft.h"
 #include "multiif.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "content_encoding.h"
 #include "http_proxy.h"
 #include "warnless.h"
@@ -77,6 +76,7 @@
 #include "pipeline.h"
 #include "http2.h"
 #include "connect.h"
+#include "strdup.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -182,7 +182,7 @@
   struct Curl_easy *data = conn->data;
 
   for(head = data->set.headers;head; head=head->next) {
-    if(Curl_raw_nequal(head->data, thisheader, thislen))
+    if(strncasecompare(head->data, thisheader, thislen))
       return head->data;
   }
 
@@ -208,7 +208,7 @@
   for(head = (conn->bits.proxy && data->set.sep_headers) ?
         data->set.proxyheaders : data->set.headers;
       head; head=head->next) {
-    if(Curl_raw_nequal(head->data, thisheader, thislen))
+    if(strncasecompare(head->data, thisheader, thislen))
       return head->data;
   }
 
@@ -288,8 +288,8 @@
 
   if(proxy) {
     userp = &conn->allocptr.proxyuserpwd;
-    user = conn->proxyuser;
-    pwd = conn->proxypasswd;
+    user = conn->http_proxy.user;
+    pwd = conn->http_proxy.passwd;
   }
   else {
     userp = &conn->allocptr.userpwd;
@@ -462,7 +462,7 @@
 #endif
 
     /* This is not NTLM or many bytes left to send: close */
-    connclose(conn, "Mid-auth HTTP and much data left to send");
+    streamclose(conn, "Mid-auth HTTP and much data left to send");
     data->req.size = 0; /* don't download any more than 0 bytes */
 
     /* There still is data left to send, but this connection is marked for
@@ -642,7 +642,7 @@
   if(auth) {
     infof(data, "%s auth using %s with user '%s'\n",
           proxy ? "Proxy" : "Server", auth,
-          proxy ? (conn->proxyuser ? conn->proxyuser : "") :
+          proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
                   (conn->user ? conn->user : ""));
     authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
   }
@@ -726,7 +726,7 @@
      conn->bits.netrc ||
      !data->state.first_host ||
      data->set.http_disable_hostname_check_before_authentication ||
-     Curl_raw_equal(data->state.first_host, conn->host.name)) {
+     strcasecompare(data->state.first_host, conn->host.name)) {
     result = output_auth_headers(conn, authhost, request, path, FALSE);
   }
   else
@@ -784,23 +784,27 @@
   while(*auth) {
 #ifdef USE_SPNEGO
     if(checkprefix("Negotiate", auth)) {
-      *availp |= CURLAUTH_NEGOTIATE;
-      authp->avail |= CURLAUTH_NEGOTIATE;
+      if((authp->avail & CURLAUTH_NEGOTIATE) ||
+         Curl_auth_is_spnego_supported()) {
+        *availp |= CURLAUTH_NEGOTIATE;
+        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;
+        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;
           }
-          else
-            data->state.authproblem = TRUE;
         }
       }
     }
@@ -809,39 +813,44 @@
 #ifdef USE_NTLM
       /* NTLM support requires the SSL crypto libs */
       if(checkprefix("NTLM", auth)) {
-        *availp |= CURLAUTH_NTLM;
-        authp->avail |= CURLAUTH_NTLM;
-        if(authp->picked == CURLAUTH_NTLM ||
-           authp->picked == CURLAUTH_NTLM_WB) {
-          /* NTLM authentication is picked and activated */
-          CURLcode result = Curl_input_ntlm(conn, proxy, auth);
-          if(!result) {
-            data->state.authproblem = FALSE;
-#ifdef NTLM_WB_ENABLED
-            if(authp->picked == CURLAUTH_NTLM_WB) {
-              *availp &= ~CURLAUTH_NTLM;
-              authp->avail &= ~CURLAUTH_NTLM;
-              *availp |= CURLAUTH_NTLM_WB;
-              authp->avail |= CURLAUTH_NTLM_WB;
+        if((authp->avail & CURLAUTH_NTLM) ||
+           (authp->avail & CURLAUTH_NTLM_WB) ||
+           Curl_auth_is_ntlm_supported()) {
+          *availp |= CURLAUTH_NTLM;
+          authp->avail |= CURLAUTH_NTLM;
 
-              /* Get the challenge-message which will be passed to
-               * ntlm_auth for generating the type 3 message later */
-              while(*auth && ISSPACE(*auth))
-                auth++;
-              if(checkprefix("NTLM", auth)) {
-                auth += strlen("NTLM");
+          if(authp->picked == CURLAUTH_NTLM ||
+             authp->picked == CURLAUTH_NTLM_WB) {
+            /* NTLM authentication is picked and activated */
+            CURLcode result = Curl_input_ntlm(conn, proxy, auth);
+            if(!result) {
+              data->state.authproblem = FALSE;
+#ifdef NTLM_WB_ENABLED
+              if(authp->picked == CURLAUTH_NTLM_WB) {
+                *availp &= ~CURLAUTH_NTLM;
+                authp->avail &= ~CURLAUTH_NTLM;
+                *availp |= CURLAUTH_NTLM_WB;
+                authp->avail |= CURLAUTH_NTLM_WB;
+
+                /* Get the challenge-message which will be passed to
+                 * ntlm_auth for generating the type 3 message later */
                 while(*auth && ISSPACE(*auth))
                   auth++;
-                if(*auth)
-                  if((conn->challenge_header = strdup(auth)) == NULL)
-                    return CURLE_OUT_OF_MEMORY;
+                if(checkprefix("NTLM", auth)) {
+                  auth += strlen("NTLM");
+                  while(*auth && ISSPACE(*auth))
+                    auth++;
+                  if(*auth)
+                    if((conn->challenge_header = strdup(auth)) == NULL)
+                      return CURLE_OUT_OF_MEMORY;
+                }
               }
-            }
 #endif
-          }
-          else {
-            infof(data, "Authentication problem. Ignoring this.\n");
-            data->state.authproblem = TRUE;
+            }
+            else {
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
           }
         }
       }
@@ -849,18 +858,18 @@
 #endif
 #ifndef CURL_DISABLE_CRYPTO_AUTH
         if(checkprefix("Digest", auth)) {
-          if((authp->avail & CURLAUTH_DIGEST) != 0) {
+          if((authp->avail & CURLAUTH_DIGEST) != 0)
             infof(data, "Ignoring duplicate digest auth header.\n");
-          }
-          else {
+          else if(Curl_auth_is_digest_supported()) {
             CURLcode result;
+
             *availp |= CURLAUTH_DIGEST;
             authp->avail |= CURLAUTH_DIGEST;
 
             /* We call this function on input Digest headers even if Digest
              * authentication isn't activated yet, as we need to store the
-             * incoming data from this header in case we are gonna use
-             * Digest. */
+             * incoming data from this header in case we are going to use
+             * Digest */
             result = Curl_input_digest(conn, proxy, auth);
             if(result) {
               infof(data, "Authentication problem. Ignoring this.\n");
@@ -1090,7 +1099,9 @@
     return result;
   }
 
-  if((conn->handler->flags & PROTOPT_SSL) && conn->httpversion != 20) {
+  if((conn->handler->flags & PROTOPT_SSL ||
+     conn->http_proxy.proxytype == CURLPROXY_HTTPS)
+     && conn->httpversion != 20) {
     /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
        when we speak HTTPS, as if only a fraction of it is sent now, this data
        needs to fit into the normal read-callback buffer later on and that
@@ -1247,14 +1258,13 @@
 
     if(in->buffer)
       /* we have a buffer, enlarge the existing one */
-      new_rb = realloc(in->buffer, new_size);
+      new_rb = Curl_saferealloc(in->buffer, new_size);
     else
       /* create a new buffer */
       new_rb = malloc(new_size);
 
     if(!new_rb) {
       /* If we failed, we cleanup the whole buffer and return error */
-      Curl_safefree(in->buffer);
       free(in);
       return CURLE_OUT_OF_MEMORY;
     }
@@ -1296,7 +1306,7 @@
   const char *start;
   const char *end;
 
-  if(!Curl_raw_nequal(headerline, header, hlen))
+  if(!strncasecompare(headerline, header, hlen))
     return FALSE; /* doesn't start with header */
 
   /* pass the header */
@@ -1322,7 +1332,7 @@
 
   /* find the content string in the rest of the line */
   for(;len>=clen;len--, start++) {
-    if(Curl_raw_nequal(start, content, clen))
+    if(strncasecompare(start, content, clen))
       return TRUE; /* match! */
   }
 
@@ -1342,10 +1352,13 @@
   connkeep(conn, "HTTP default");
 
   /* the CONNECT procedure might not have been completed */
-  result = Curl_proxy_connect(conn);
+  result = Curl_proxy_connect(conn, FIRSTSOCKET);
   if(result)
     return result;
 
+  if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+    return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
+
   if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
     /* nothing else to do except wait right now - we're not done here. */
     return CURLE_OK;
@@ -1388,50 +1401,16 @@
 
   return result;
 }
-#endif
 
-#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
-    defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
-    defined(USE_MBEDTLS)
-/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
-   It should be made to query the generic SSL layer instead. */
 static int https_getsock(struct connectdata *conn,
                          curl_socket_t *socks,
                          int numsocks)
 {
-  if(conn->handler->flags & PROTOPT_SSL) {
-    struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
-
-    if(!numsocks)
-      return GETSOCK_BLANK;
-
-    if(connssl->connecting_state == ssl_connect_2_writing) {
-      /* write mode */
-      socks[0] = conn->sock[FIRSTSOCKET];
-      return GETSOCK_WRITESOCK(0);
-    }
-    else if(connssl->connecting_state == ssl_connect_2_reading) {
-      /* read mode */
-      socks[0] = conn->sock[FIRSTSOCKET];
-      return GETSOCK_READSOCK(0);
-    }
-  }
-
-  return CURLE_OK;
-}
-#else
-#ifdef USE_SSL
-static int https_getsock(struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks)
-{
-  (void)conn;
-  (void)socks;
-  (void)numsocks;
+  if(conn->handler->flags & PROTOPT_SSL)
+    return Curl_ssl_getsock(conn, socks, numsocks);
   return GETSOCK_BLANK;
 }
 #endif /* USE_SSL */
-#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
 
 /*
  * Curl_http_done() gets called after a single HTTP request has been
@@ -1443,9 +1422,8 @@
 {
   struct Curl_easy *data = conn->data;
   struct HTTP *http = data->req.protop;
-#ifdef USE_NGHTTP2
-  struct http_conn *httpc = &conn->proto.httpc;
-#endif
+
+  infof(data, "Curl_http_done: called premature == %d\n", premature);
 
   Curl_unencode_cleanup(conn);
 
@@ -1458,7 +1436,7 @@
      * Do not close CONNECT_ONLY connections. */
     if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
        !data->set.connect_only)
-      connclose(conn, "Negotiate transfer completed");
+      streamclose(conn, "Negotiate transfer completed");
     Curl_cleanup_negotiate(data);
   }
 #endif
@@ -1475,27 +1453,7 @@
     http->send_buffer = NULL; /* clear the pointer */
   }
 
-#ifdef USE_NGHTTP2
-  if(http->header_recvbuf) {
-    DEBUGF(infof(data, "free header_recvbuf!!\n"));
-    Curl_add_buffer_free(http->header_recvbuf);
-    http->header_recvbuf = NULL; /* clear the pointer */
-    Curl_add_buffer_free(http->trailer_recvbuf);
-    http->trailer_recvbuf = NULL; /* clear the pointer */
-    if(http->push_headers) {
-      /* if they weren't used and then freed before */
-      for(; http->push_headers_used > 0; --http->push_headers_used) {
-        free(http->push_headers[http->push_headers_used - 1]);
-      }
-      free(http->push_headers);
-      http->push_headers = NULL;
-    }
-  }
-  if(http->stream_id) {
-    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
-    http->stream_id = 0;
-  }
-#endif
+  Curl_http2_done(conn, premature);
 
   if(HTTPREQ_POST_FORM == data->set.httpreq) {
     data->req.bytecount = http->readbytecount + http->writebytecount;
@@ -1660,6 +1618,10 @@
                      Connection: */
                   checkprefix("Connection", headers->data))
             ;
+          else if((conn->httpversion == 20) &&
+                  checkprefix("Transfer-Encoding:", headers->data))
+            /* HTTP/2 doesn't support chunked requests */
+            ;
           else {
             CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
                                                headers->data);
@@ -1946,47 +1908,42 @@
   }
 #endif
 
-  if(conn->httpversion == 20)
-    /* In HTTP2 forbids Transfer-Encoding: chunked */
-    ptr = NULL;
+  ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
+  if(ptr) {
+    /* Some kind of TE is requested, check if 'chunked' is chosen */
+    data->req.upload_chunky =
+      Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
+  }
   else {
-    ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
-    if(ptr) {
-      /* Some kind of TE is requested, check if 'chunked' is chosen */
-      data->req.upload_chunky =
-        Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
-    }
-    else {
-      if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
-         data->set.upload &&
-         (data->state.infilesize == -1)) {
-        if(conn->bits.authneg)
-          /* don't enable chunked during auth neg */
-          ;
-        else if(use_http_1_1plus(data, conn)) {
-          /* HTTP, upload, unknown file size and not HTTP 1.0 */
-          data->req.upload_chunky = TRUE;
-        }
-        else {
-          failf(data, "Chunky upload is not supported by HTTP 1.0");
-          return CURLE_UPLOAD_FAILED;
-        }
+    if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+       data->set.upload &&
+       (data->state.infilesize == -1)) {
+      if(conn->bits.authneg)
+        /* don't enable chunked during auth neg */
+        ;
+      else if(use_http_1_1plus(data, conn)) {
+        /* HTTP, upload, unknown file size and not HTTP 1.0 */
+        data->req.upload_chunky = TRUE;
       }
       else {
-        /* else, no chunky upload */
-        data->req.upload_chunky = FALSE;
+        failf(data, "Chunky upload is not supported by HTTP 1.0");
+        return CURLE_UPLOAD_FAILED;
       }
-
-      if(data->req.upload_chunky)
-        te = "Transfer-Encoding: chunked\r\n";
     }
+    else {
+      /* else, no chunky upload */
+      data->req.upload_chunky = FALSE;
+    }
+
+    if(data->req.upload_chunky)
+      te = "Transfer-Encoding: chunked\r\n";
   }
 
   Curl_safefree(conn->allocptr.host);
 
   ptr = Curl_checkheaders(conn, "Host:");
   if(ptr && (!data->state.this_is_a_follow ||
-             Curl_raw_equal(data->state.first_host, conn->host.name))) {
+             strcasecompare(data->state.first_host, conn->host.name))) {
 #if !defined(CURL_DISABLE_COOKIES)
     /* If we have a given custom Host: header, we extract the host name in
        order to possibly use it for cookie reasons later on. We only allow the
@@ -2305,6 +2262,7 @@
                      "%s" /* TE: */
                      "%s" /* accept-encoding */
                      "%s" /* referer */
+                     "%s" /* Proxy-Connection */
                      "%s",/* transfer-encoding */
 
                      ftp_typecode,
@@ -2327,6 +2285,10 @@
                      conn->allocptr.accept_encoding:"",
                      (data->change.referer && conn->allocptr.ref)?
                      conn->allocptr.ref:"" /* Referer: <data> */,
+                     (conn->bits.httpproxy &&
+                      !conn->bits.tunnel_proxy &&
+                      !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
+                     "Proxy-Connection: Keep-Alive\r\n":"",
                      te
       );
 
@@ -2392,7 +2354,7 @@
         }
         co = co->next; /* next cookie please */
       }
-      Curl_cookie_freelist(store, FALSE); /* free the cookie list */
+      Curl_cookie_freelist(store);
     }
     if(addcookies && !result) {
       if(!count)
@@ -2768,6 +2730,11 @@
     }
   }
 
+  if((conn->httpversion == 20) && data->req.upload_chunky)
+    /* upload_chunky was set above to set up the request in a chunky fashion,
+       but is disabled here again to avoid that the chunked encoded version is
+       actually used when sending the request body over h2 */
+    data->req.upload_chunky = FALSE;
   return result;
 }
 
@@ -3040,19 +3007,19 @@
 #endif /* CURL_DOES_CONVERSIONS */
 
       if(100 <= k->httpcode && 199 >= k->httpcode) {
-        /*
-         * We have made a HTTP PUT or POST and this is 1.1-lingo
-         * that tells us that the server is OK with this and ready
-         * to receive the data.
-         * However, we'll get more headers now so we must get
-         * back into the header-parsing state!
-         */
-        k->header = TRUE;
-        k->headerline = 0; /* restart the header line counter */
-
         /* "A user agent MAY ignore unexpected 1xx status responses." */
         switch(k->httpcode) {
         case 100:
+          /*
+           * We have made a HTTP PUT or POST and this is 1.1-lingo
+           * that tells us that the server is OK with this and ready
+           * to receive the data.
+           * However, we'll get more headers now so we must get
+           * back into the header-parsing state!
+           */
+          k->header = TRUE;
+          k->headerline = 0; /* restart the header line counter */
+
           /* if we did wait for this do enable write now! */
           if(k->exp100 > EXP100_SEND_DATA) {
             k->exp100 = EXP100_SEND_DATA;
@@ -3062,9 +3029,14 @@
         case 101:
           /* Switching Protocols */
           if(k->upgr101 == UPGR101_REQUESTED) {
+            /* Switching to HTTP/2 */
             infof(data, "Received 101\n");
             k->upgr101 = UPGR101_RECEIVED;
 
+            /* we'll get more headers (HTTP/2 response) */
+            k->header = TRUE;
+            k->headerline = 0; /* restart the header line counter */
+
             /* switch to http2 now. The bytes after response headers
                are also processed here, otherwise they are lost. */
             result = Curl_http2_switched(conn, k->str, *nread);
@@ -3072,8 +3044,16 @@
               return result;
             *nread = 0;
           }
+          else {
+            /* Switching to another protocol (e.g. WebSocket) */
+            k->header = FALSE; /* no more header to parse! */
+          }
           break;
         default:
+          /* the status code 1xx indicates a provisional response, so
+             we'll get another set of headers */
+          k->header = TRUE;
+          k->headerline = 0; /* restart the header line counter */
           break;
         }
       }
@@ -3091,7 +3071,7 @@
              signal the end of the document. */
           infof(data, "no chunk, no close, no size. Assume close to "
                 "signal end\n");
-          connclose(conn, "HTTP: No end-of-message indicator");
+          streamclose(conn, "HTTP: No end-of-message indicator");
         }
       }
 
@@ -3171,12 +3151,21 @@
              * connection for closure after we've read the entire response.
              */
             if(!k->upload_done) {
-              infof(data, "HTTP error before end of send, stop sending\n");
-              connclose(conn, "Stop sending data before everything sent");
-              k->upload_done = TRUE;
-              k->keepon &= ~KEEP_SEND; /* don't send */
-              if(data->state.expect100header)
-                k->exp100 = EXP100_FAILED;
+              if(data->set.http_keep_sending_on_error) {
+                infof(data, "HTTP error before end of send, keep sending\n");
+                if(k->exp100 > EXP100_SEND_DATA) {
+                  k->exp100 = EXP100_SEND_DATA;
+                  k->keepon |= KEEP_SEND;
+                }
+              }
+              else {
+                infof(data, "HTTP error before end of send, stop sending\n");
+                streamclose(conn, "Stop sending data before everything sent");
+                k->upload_done = TRUE;
+                k->keepon &= ~KEEP_SEND; /* don't send */
+                if(data->state.expect100header)
+                  k->exp100 = EXP100_FAILED;
+              }
             }
             break;
 
@@ -3476,7 +3465,7 @@
         /* Negative Content-Length is really odd, and we know it
            happens for example when older Apache servers send large
            files */
-        connclose(conn, "negative content-length");
+        streamclose(conn, "negative content-length");
         infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
               ", closing after transfer\n", contentlength);
       }
@@ -3549,7 +3538,7 @@
        * the connection will close when this request has been
        * served.
        */
-      connclose(conn, "Connection: close used");
+      streamclose(conn, "Connection: close used");
     }
     else if(checkprefix("Transfer-Encoding:", k->p)) {
       /* One or more encodings. We check for chunked and/or a compression
diff --git a/lib/http.h b/lib/http.h
index 6529005..9fb669c 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -168,6 +168,7 @@
   const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
   size_t pauselen; /* the number of bytes left in data */
   bool closed; /* TRUE on HTTP2 stream close */
+  bool close_handled; /* TRUE if stream closure is handled by libcurl */
   uint32_t error_code; /* HTTP/2 error code */
 
   char *mem;     /* points to a buffer in memory to store received data */
diff --git a/lib/http2.c b/lib/http2.c
index efc082d..2ef1731 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -29,13 +29,13 @@
 #include "http.h"
 #include "sendf.h"
 #include "curl_base64.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "multiif.h"
 #include "conncache.h"
 #include "url.h"
 #include "connect.h"
 #include "strtoofft.h"
-
+#include "strdup.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -59,6 +59,8 @@
 #define nghttp2_session_callbacks_set_error_callback(x,y)
 #endif
 
+#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+
 /*
  * Curl_http2_init_state() is called when the easy handle is created and
  * allows for HTTP/2 specific init of state.
@@ -92,8 +94,9 @@
      because of renegotiation. */
   sock[0] = conn->sock[FIRSTSOCKET];
 
-  if(nghttp2_session_want_read(c->h2))
-    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+  /* in a HTTP/2 connection we can basically always get a frame so we should
+     always be ready for one */
+  bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
 
   if(nghttp2_session_want_write(c->h2))
     bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
@@ -150,6 +153,7 @@
   http->pauselen = 0;
   http->error_code = NGHTTP2_NO_ERROR;
   http->closed = FALSE;
+  http->close_handled = FALSE;
   http->mem = data->state.buffer;
   http->len = BUFSIZE;
   http->memlen = 0;
@@ -184,7 +188,7 @@
   ZERO_NULL,                            /* readwrite */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_STREAM                        /* flags */
 };
 
 const struct Curl_handler Curl_handler_http2_ssl = {
@@ -204,7 +208,7 @@
   ZERO_NULL,                            /* readwrite */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
-  PROTOPT_SSL                           /* flags */
+  PROTOPT_SSL | PROTOPT_STREAM          /* flags */
 };
 
 /*
@@ -221,7 +225,8 @@
 https://tools.ietf.org/html/rfc7540#page-77
 nghttp2_error_code enums are identical.
 */
-const char *Curl_http2_strerror(uint32_t err) {
+const char *Curl_http2_strerror(uint32_t err)
+{
 #ifndef NGHTTP2_HAS_HTTP2_STRERROR
   const char *str[] = {
     "NO_ERROR",             /* 0x0 */
@@ -317,7 +322,7 @@
      the middle of header, it could be matched in middle of the value,
      this is because we do prefix match.*/
   if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
-     Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
+     !strcmp(header, ":") || strchr(header + 1, ':'))
     return NULL;
   else {
     struct HTTP *stream = h->data->req.protop;
@@ -488,8 +493,11 @@
   }
 
   stream = data_s->req.protop;
-  if(!stream)
+  if(!stream) {
+    DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n",
+                 stream_id));
     return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
 
   DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
                frame->hd.type, stream_id));
@@ -547,7 +555,7 @@
 
       /* if we receive data for another handle, wake that up */
       if(conn_s->data != data_s)
-        Curl_expire(data_s, 1);
+        Curl_expire(data_s, 0);
     }
     break;
   case NGHTTP2_PUSH_PROMISE:
@@ -621,8 +629,7 @@
 
   /* if we receive data for another handle, wake that up */
   if(conn->data != data_s)
-    Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
-                               immediately? */
+    Curl_expire(data_s, 0);
 
   DEBUGF(infof(data_s, "%zu data received for stream %u "
                "(%zu left in buffer %p, total %zu)\n",
@@ -837,10 +844,9 @@
             stream->push_headers_alloc) {
       char **headp;
       stream->push_headers_alloc *= 2;
-      headp = realloc(stream->push_headers,
-                      stream->push_headers_alloc * sizeof(char *));
+      headp = Curl_saferealloc(stream->push_headers,
+                               stream->push_headers_alloc * sizeof(char *));
       if(!headp) {
-        free(stream->push_headers);
         stream->push_headers = NULL;
         return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
       }
@@ -883,7 +889,7 @@
     Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
     /* if we receive data for another handle, wake that up */
     if(conn->data != data_s)
-      Curl_expire(data_s, 1);
+      Curl_expire(data_s, 0);
 
     DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
                  stream->status_code, data_s));
@@ -899,7 +905,7 @@
   Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
   /* if we receive data for another handle, wake that up */
   if(conn->data != data_s)
-    Curl_expire(data_s, 1);
+    Curl_expire(data_s, 0);
 
   DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
                value));
@@ -941,11 +947,12 @@
     memcpy(buf, stream->upload_mem, nread);
     stream->upload_mem += nread;
     stream->upload_len -= nread;
-    stream->upload_left -= nread;
+    if(data_s->state.infilesize != -1)
+      stream->upload_left -= nread;
   }
 
   if(stream->upload_left == 0)
-    *data_flags = 1;
+    *data_flags = NGHTTP2_DATA_FLAG_EOF;
   else if(nread == 0)
     return NGHTTP2_ERR_DEFERRED;
 
@@ -961,7 +968,7 @@
  */
 static nghttp2_settings_entry settings[] = {
   { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
-  { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
+  { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, HTTP2_HUGE_WINDOW_SIZE },
 };
 
 #define H2_BUFSIZE 32768
@@ -979,6 +986,43 @@
 }
 #endif
 
+void Curl_http2_done(struct connectdata *conn, bool premature)
+{
+  struct Curl_easy *data = conn->data;
+  struct HTTP *http = data->req.protop;
+  struct http_conn *httpc = &conn->proto.httpc;
+
+  if(http->header_recvbuf) {
+    DEBUGF(infof(data, "free header_recvbuf!!\n"));
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    Curl_add_buffer_free(http->trailer_recvbuf);
+    http->trailer_recvbuf = NULL; /* clear the pointer */
+    if(http->push_headers) {
+      /* if they weren't used and then freed before */
+      for(; http->push_headers_used > 0; --http->push_headers_used) {
+        free(http->push_headers[http->push_headers_used - 1]);
+      }
+      free(http->push_headers);
+      http->push_headers = NULL;
+    }
+  }
+
+  if(premature) {
+    /* RST_STREAM */
+    nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
+                              NGHTTP2_STREAM_CLOSED);
+    if(http->stream_id == httpc->pause_stream_id) {
+      infof(data, "stopped the pause stream!\n");
+      httpc->pause_stream_id = 0;
+    }
+  }
+  if(http->stream_id) {
+    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+    http->stream_id = 0;
+  }
+}
+
 /*
  * Initialize nghttp2 for a Curl connection
  */
@@ -1091,9 +1135,10 @@
 /*
  * Returns nonzero if current HTTP/2 session should be closed.
  */
-static int should_close_session(struct http_conn *httpc) {
+static int should_close_session(struct http_conn *httpc)
+{
   return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) &&
-         !nghttp2_session_want_write(httpc->h2);
+    !nghttp2_session_want_write(httpc->h2);
 }
 
 static int h2_session_send(struct Curl_easy *data,
@@ -1107,7 +1152,8 @@
  */
 static int h2_process_pending_input(struct Curl_easy *data,
                                     struct http_conn *httpc,
-                                    CURLcode *err) {
+                                    CURLcode *err)
+{
   ssize_t nread;
   char *inbuf;
   ssize_t rv;
@@ -1155,9 +1201,41 @@
   return 0;
 }
 
+/*
+ * Called from transfer.c:done_sending when we stop uploading.
+ */
+CURLcode Curl_http2_done_sending(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if((conn->handler == &Curl_handler_http2_ssl) ||
+     (conn->handler == &Curl_handler_http2)) {
+    /* make sure this is only attempted for HTTP/2 transfers */
+
+    struct HTTP *stream = conn->data->req.protop;
+
+    if(stream->upload_left) {
+      /* If the stream still thinks there's data left to upload. */
+      struct http_conn *httpc = &conn->proto.httpc;
+      nghttp2_session *h2 = httpc->h2;
+
+      stream->upload_left = 0; /* DONE! */
+
+      /* resume sending here to trigger the callback to get called again so
+         that it can signal EOF to nghttp2 */
+      (void)nghttp2_session_resume_data(h2, stream->stream_id);
+
+      (void)h2_process_pending_input(conn->data, httpc, &result);
+    }
+  }
+  return result;
+}
+
+
 static ssize_t http2_handle_stream_close(struct connectdata *conn,
                                          struct Curl_easy *data,
-                                         struct HTTP *stream, CURLcode *err) {
+                                         struct HTTP *stream, CURLcode *err)
+{
   char *trailer_pos, *trailer_end;
   CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
@@ -1178,8 +1256,7 @@
 
   DEBUGASSERT(data->state.drain == 0);
 
-  /* Reset to FALSE to prevent infinite loop in readwrite_data
-   function. */
+  /* Reset to FALSE to prevent infinite loop in readwrite_data function. */
   stream->closed = FALSE;
   if(stream->error_code != NGHTTP2_NO_ERROR) {
     failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
@@ -1216,6 +1293,8 @@
     }
   }
 
+  stream->close_handled = TRUE;
+
   DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
   return 0;
 }
@@ -1268,10 +1347,6 @@
   return nghttp2_session_send(h2);
 }
 
-/*
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
 static ssize_t http2_recv(struct connectdata *conn, int sockindex,
                           char *mem, size_t len, CURLcode *err)
 {
@@ -1382,6 +1457,8 @@
        socket is not read.  But it seems that usually streams are
        notified with its drain property, and socket is read again
        quickly. */
+    DEBUGF(infof(data, "stream %x is paused, pause id: %x\n",
+                 stream->stream_id, httpc->pause_stream_id));
     *err = CURLE_AGAIN;
     return -1;
   }
@@ -1497,7 +1574,72 @@
 #define HEADER_OVERFLOW(x) \
   (x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen)
 
-/* return number of received (decrypted) bytes */
+/*
+ * Check header memory for the token "trailers".
+ * Parse the tokens as separated by comma and surrounded by whitespace.
+ * Returns TRUE if found or FALSE if not.
+ */
+static bool contains_trailers(const char *p, size_t len)
+{
+  const char *end = p + len;
+  for(;;) {
+    for(; p != end && (*p == ' ' || *p == '\t'); ++p)
+      ;
+    if(p == end || (size_t)(end - p) < sizeof("trailers") - 1)
+      return FALSE;
+    if(strncasecompare("trailers", p, sizeof("trailers") - 1)) {
+      p += sizeof("trailers") - 1;
+      for(; p != end && (*p == ' ' || *p == '\t'); ++p)
+        ;
+      if(p == end || *p == ',')
+        return TRUE;
+    }
+    /* skip to next token */
+    for(; p != end && *p != ','; ++p)
+      ;
+    if(p == end)
+      return FALSE;
+    ++p;
+  }
+}
+
+typedef enum {
+  /* Send header to server */
+  HEADERINST_FORWARD,
+  /* Don't send header to server */
+  HEADERINST_IGNORE,
+  /* Discard header, and replace it with "te: trailers" */
+  HEADERINST_TE_TRAILERS
+} header_instruction;
+
+/* Decides how to treat given header field. */
+static header_instruction inspect_header(const char *name, size_t namelen,
+                                         const char *value, size_t valuelen) {
+  switch(namelen) {
+  case 2:
+    if(!strncasecompare("te", name, namelen))
+      return HEADERINST_FORWARD;
+
+    return contains_trailers(value, valuelen) ?
+           HEADERINST_TE_TRAILERS : HEADERINST_IGNORE;
+  case 7:
+    return strncasecompare("upgrade", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 10:
+    return (strncasecompare("connection", name, namelen) ||
+            strncasecompare("keep-alive", name, namelen)) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 16:
+    return strncasecompare("proxy-connection", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 17:
+    return strncasecompare("transfer-encoding", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  default:
+    return HEADERINST_FORWARD;
+  }
+}
+
 static ssize_t http2_send(struct connectdata *conn, int sockindex,
                           const void *mem, size_t len, CURLcode *err)
 {
@@ -1513,7 +1655,7 @@
   size_t nheader;
   size_t i;
   size_t authority_idx;
-  char *hdbuf = (char*)mem;
+  char *hdbuf = (char *)mem;
   char *end, *line_end;
   nghttp2_data_provider data_prd;
   int32_t stream_id;
@@ -1525,6 +1667,14 @@
   DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
 
   if(stream->stream_id != -1) {
+    if(stream->close_handled) {
+      infof(conn->data, "stream %d closed\n", stream->stream_id);
+      *err = CURLE_HTTP2_STREAM;
+      return -1;
+    }
+    else if(stream->closed) {
+      return http2_handle_stream_close(conn, conn->data, stream, err);
+    }
     /* If stream_id != -1, we have dispatched request HEADERS, and now
        are going to send or sending request body in DATA frame */
     stream->upload_mem = mem;
@@ -1643,7 +1793,6 @@
   i = 3;
   while(i < nheader) {
     size_t hlen;
-    int skip = 0;
 
     hdbuf = line_end + 2;
 
@@ -1661,12 +1810,7 @@
       goto fail;
     hlen = end - hdbuf;
 
-    if(hlen == 10 && Curl_raw_nequal("connection", hdbuf, 10)) {
-      /* skip Connection: headers! */
-      skip = 1;
-      --nheader;
-    }
-    else if(hlen == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
+    if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
       authority_idx = i;
       nva[i].name = (unsigned char *)":authority";
       nva[i].namelen = strlen((char *)nva[i].name);
@@ -1679,38 +1823,28 @@
     while(*hdbuf == ' ' || *hdbuf == '\t')
       ++hdbuf;
     end = line_end;
-    if(!skip) {
+
+    switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
+                          end - hdbuf)) {
+    case HEADERINST_IGNORE:
+      /* skip header fields prohibited by HTTP/2 specification. */
+      --nheader;
+      continue;
+    case HEADERINST_TE_TRAILERS:
+      nva[i].value = (uint8_t*)"trailers";
+      nva[i].valuelen = sizeof("trailers") - 1;
+      break;
+    default:
       nva[i].value = (unsigned char *)hdbuf;
       nva[i].valuelen = (size_t)(end - hdbuf);
-      nva[i].flags = NGHTTP2_NV_FLAG_NONE;
-      if(HEADER_OVERFLOW(nva[i])) {
-        failf(conn->data, "Failed sending HTTP request: Header overflow");
-        goto fail;
-      }
-      /* Inspect Content-Length header field and retrieve the request
-         entity length so that we can set END_STREAM to the last DATA
-         frame. */
-      if(nva[i].namelen == 14 &&
-         Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
-        size_t j;
-        stream->upload_left = 0;
-        if(!nva[i].valuelen)
-          goto fail;
-        for(j = 0; j < nva[i].valuelen; ++j) {
-          if(nva[i].value[j] < '0' || nva[i].value[j] > '9')
-            goto fail;
-          if(stream->upload_left >= CURL_OFF_T_MAX / 10)
-            goto fail;
-          stream->upload_left *= 10;
-          stream->upload_left += nva[i].value[j] - '0';
-        }
-        DEBUGF(infof(conn->data,
-                     "request content-length=%"
-                     CURL_FORMAT_CURL_OFF_T
-                     "\n", stream->upload_left));
-      }
-      ++i;
     }
+
+    nva[i].flags = NGHTTP2_NV_FLAG_NONE;
+    if(HEADER_OVERFLOW(nva[i])) {
+      failf(conn->data, "Failed sending HTTP request: Header overflow");
+      goto fail;
+    }
+    ++i;
   }
 
   /* :authority must come before non-pseudo header fields */
@@ -1736,6 +1870,10 @@
       if(nva[i].valuelen > max_acc - acc)
         break;
       acc += nva[i].valuelen;
+
+      DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
+                   nva[i].namelen, nva[i].name,
+                   nva[i].valuelen, nva[i].value));
     }
 
     if(i != nheader) {
@@ -1751,6 +1889,12 @@
   case HTTPREQ_POST:
   case HTTPREQ_POST_FORM:
   case HTTPREQ_PUT:
+    if(conn->data->state.infilesize != -1)
+      stream->upload_left = conn->data->state.infilesize;
+    else
+      /* data sending without specifying the data amount up front */
+      stream->upload_left = -1; /* unknown, but not zero */
+
     data_prd.read_callback = data_source_read_callback;
     data_prd.source.ptr = NULL;
     stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
@@ -1850,10 +1994,6 @@
   infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
   Curl_multi_connchanged(conn->data->multi);
 
-  /* switch on TCP_NODELAY as we need to send off packets without delay for
-     maximum throughput */
-  Curl_tcpnodelay(conn, conn->sock[FIRSTSOCKET]);
-
   return CURLE_OK;
 }
 
@@ -1895,7 +2035,8 @@
   else {
     /* stream ID is unknown at this point */
     stream->stream_id = -1;
-    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
+    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, settings,
+                                 sizeof(settings) / sizeof(settings[0]));
     if(rv != 0) {
       failf(data, "nghttp2_submit_settings() failed: %s(%d)",
             nghttp2_strerror(rv), rv);
@@ -1903,6 +2044,14 @@
     }
   }
 
+  rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
+                                             HTTP2_HUGE_WINDOW_SIZE);
+  if(rv != 0) {
+    failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
+          nghttp2_strerror(rv), rv);
+    return CURLE_HTTP2;
+  }
+
   /* we are going to copy mem to httpc->inbuf.  This is required since
      mem is part of buffer pointed by stream->mem, and callbacks
      called by nghttp2_session_mem_recv() will write stream specific
@@ -1918,7 +2067,8 @@
                     " after upgrade: len=%zu\n",
         nread);
 
-  memcpy(httpc->inbuf, mem, nread);
+  if(nread)
+    memcpy(httpc->inbuf, mem, nread);
   httpc->inbuflen = nread;
 
   nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
diff --git a/lib/http2.h b/lib/http2.h
index bedbebf..8917535 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -51,6 +51,8 @@
 /* called from Curl_http_setup_conn */
 void Curl_http2_setup_conn(struct connectdata *conn);
 void Curl_http2_setup_req(struct Curl_easy *data);
+void Curl_http2_done(struct connectdata *conn, bool premature);
+CURLcode Curl_http2_done_sending(struct connectdata *conn);
 #else /* USE_NGHTTP2 */
 #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
@@ -61,6 +63,8 @@
 #define Curl_http2_setup_req(x)
 #define Curl_http2_init_state(x)
 #define Curl_http2_init_userset(x)
+#define Curl_http2_done(x,y)
+#define Curl_http2_done_sending(x)
 #endif
 
 #endif /* HEADER_CURL_HTTP2_H */
diff --git a/lib/http_digest.c b/lib/http_digest.c
index 97230e7..91b88a3 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -25,7 +25,7 @@
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
 
 #include "urldata.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "vauth/vauth.h"
 #include "http_digest.h"
 /* The last 3 #include files should be in this order */
@@ -95,8 +95,8 @@
   if(proxy) {
     digest = &data->state.proxydigest;
     allocuserpwd = &conn->allocptr.proxyuserpwd;
-    userp = conn->proxyuser;
-    passwdp = conn->proxypasswd;
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
     authp = &data->state.authproxy;
   }
   else {
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index c39d6f3..51375e8 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -26,7 +26,6 @@
 
 #include "urldata.h"
 #include "sendf.h"
-#include "rawstr.h"
 #include "http_negotiate.h"
 #include "vauth/vauth.h"
 
@@ -38,6 +37,7 @@
 CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
                               const char *header)
 {
+  CURLcode result;
   struct Curl_easy *data = conn->data;
   size_t len;
 
@@ -51,11 +51,11 @@
   struct negotiatedata *neg_ctx;
 
   if(proxy) {
-    userp = conn->proxyuser;
-    passwdp = conn->proxypasswd;
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
     service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
               data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
-    host = conn->proxy.name;
+    host = conn->http_proxy.host.name;
     neg_ctx = &data->state.proxyneg;
   }
   else {
@@ -90,8 +90,13 @@
   }
 
   /* Initilise the security context and decode our challenge */
-  return Curl_auth_decode_spnego_message(data, userp, passwdp, service, host,
-                                         header, neg_ctx);
+  result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
+                                           host, header, neg_ctx);
+
+  if(result)
+    Curl_auth_spnego_cleanup(neg_ctx);
+
+  return result;
 }
 
 CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index 935df25..21c77cd 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -35,7 +35,7 @@
 
 #include "urldata.h"
 #include "sendf.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "http_ntlm.h"
 #include "curl_ntlm_wb.h"
 #include "vauth/vauth.h"
@@ -136,8 +136,8 @@
 
   if(proxy) {
     allocuserpwd = &conn->allocptr.proxyuserpwd;
-    userp = conn->proxyuser;
-    passwdp = conn->proxypasswd;
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
     ntlm = &conn->proxyntlm;
     authp = &conn->data->state.authproxy;
   }
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index c6b05e3..bbe2e8e 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -31,19 +31,54 @@
 #include "http.h"
 #include "url.h"
 #include "select.h"
-#include "rawstr.h"
 #include "progress.h"
 #include "non-ascii.h"
 #include "connect.h"
 #include "curlx.h"
+#include "vtls/vtls.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
-CURLcode Curl_proxy_connect(struct connectdata *conn)
+/*
+ * Perform SSL initialization for HTTPS proxy.  Sets
+ * proxy_ssl_connected connection bit when complete.  Can be
+ * called multiple times.
+ */
+static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
 {
+#ifdef USE_SSL
+  CURLcode result = CURLE_OK;
+  DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
+  if(!conn->bits.proxy_ssl_connected[sockindex]) {
+    /* perform SSL initialization for this socket */
+    result =
+      Curl_ssl_connect_nonblocking(conn, sockindex,
+                                   &conn->bits.proxy_ssl_connected[sockindex]);
+    if(result)
+      conn->bits.close = TRUE; /* a failed connection is marked for closure to
+                                  prevent (bad) re-use or similar */
+  }
+  return result;
+#else
+  (void) conn;
+  (void) sockindex;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
+{
+  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
+    const CURLcode result = https_proxy_connect(conn, sockindex);
+    if(result)
+      return result;
+    if(!conn->bits.proxy_ssl_connected[sockindex])
+      return result; /* wait for HTTPS proxy SSL initialization to complete */
+  }
+
   if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
 #ifndef CURL_DISABLE_PROXY
     /* for [protocol] tunneled through HTTP proxy */
@@ -69,15 +104,20 @@
     memset(&http_proxy, 0, sizeof(http_proxy));
     conn->data->req.protop = &http_proxy;
     connkeep(conn, "HTTP proxy CONNECT");
-    if(conn->bits.conn_to_host)
+    if(sockindex == SECONDARYSOCKET)
+      hostname = conn->secondaryhostname;
+    else if(conn->bits.conn_to_host)
       hostname = conn->conn_to_host.name;
     else
       hostname = conn->host.name;
-    if(conn->bits.conn_to_port)
+
+    if(sockindex == SECONDARYSOCKET)
+      remote_port = conn->secondary_port;
+    else if(conn->bits.conn_to_port)
       remote_port = conn->conn_to_port;
     else
       remote_port = conn->remote_port;
-    result = Curl_proxyCONNECT(conn, FIRSTSOCKET, hostname,
+    result = Curl_proxyCONNECT(conn, sockindex, hostname,
                                remote_port, FALSE);
     conn->data->req.protop = prot_save;
     if(CURLE_OK != result)
@@ -114,7 +154,7 @@
   curl_off_t cl=0;
   bool closeConnection = FALSE;
   bool chunked_encoding = FALSE;
-  long check;
+  time_t check;
 
 #define SELECT_OK      0
 #define SELECT_ERROR   1
@@ -160,8 +200,9 @@
 
       if(!result) {
         char *host=(char *)"";
+        const char *proxyconn="";
         const char *useragent="";
-        const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
+        const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
           "1.0" : "1.1";
         bool ipv6_ip = conn->bits.ipv6_ip;
         char *hostheader;
@@ -185,6 +226,9 @@
             return CURLE_OUT_OF_MEMORY;
           }
         }
+        if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
+          proxyconn = "Proxy-Connection: Keep-Alive\r\n";
+
         if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
            data->set.str[STRING_USERAGENT])
           useragent = conn->allocptr.uagent;
@@ -194,13 +238,15 @@
                            "CONNECT %s HTTP/%s\r\n"
                            "%s"  /* Host: */
                            "%s"  /* Proxy-Authorization */
-                           "%s", /* User-Agent */
+                           "%s"  /* User-Agent */
+                           "%s", /* Proxy-Connection */
                            hostheader,
                            http,
                            host,
                            conn->allocptr.proxyuserpwd?
                            conn->allocptr.proxyuserpwd:"",
-                           useragent);
+                           useragent,
+                           proxyconn);
 
         if(host && *host)
           free(host);
@@ -239,7 +285,7 @@
     }
 
     if(!blocking) {
-      if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
+      if(0 == SOCKET_READABLE(tunnelsocket, 0))
         /* return so we'll be called again polling-style */
         return CURLE_OK;
       else {
@@ -274,8 +320,7 @@
         }
 
         /* loop every second at least, less if the timeout is near */
-        switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
-                                  check<1000L?check:1000)) {
+        switch (SOCKET_READABLE(tunnelsocket, check<1000L?check:1000)) {
         case -1: /* select() error, stop reading */
           error = SELECT_ERROR;
           failf(data, "Proxy CONNECT aborted due to select/poll error");
@@ -568,7 +613,7 @@
       free(data->req.newurl);
       data->req.newurl = NULL;
       /* failure, close this connection to avoid re-use */
-      connclose(conn, "proxy CONNECT failure");
+      streamclose(conn, "proxy CONNECT failure");
       Curl_closesocket(conn, conn->sock[sockindex]);
       conn->sock[sockindex] = CURL_SOCKET_BAD;
     }
diff --git a/lib/http_proxy.h b/lib/http_proxy.h
index fd04330..d1f5a7c 100644
--- a/lib/http_proxy.h
+++ b/lib/http_proxy.h
@@ -32,11 +32,11 @@
 /* Default proxy timeout in milliseconds */
 #define PROXY_TIMEOUT (3600*1000)
 
-CURLcode Curl_proxy_connect(struct connectdata *conn);
+CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex);
 
 #else
 #define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
-#define Curl_proxy_connect(x) CURLE_OK
+#define Curl_proxy_connect(x,y) CURLE_OK
 #endif
 
 #endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/lib/if2ip.c b/lib/if2ip.c
index 2f92b2d..d876615 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.c
@@ -51,7 +51,7 @@
 #endif
 
 #include "inet_ntop.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "if2ip.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -68,7 +68,7 @@
 #else
   if(sa->sa_family == AF_INET6) {
     const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
-    const unsigned char * b = sa6->sin6_addr.s6_addr;
+    const unsigned char *b = sa6->sin6_addr.s6_addr;
     unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
 
     switch(w & 0xFFC0) {
@@ -102,7 +102,7 @@
 
   if(getifaddrs(&head) >= 0) {
     for(iface=head; iface != NULL; iface=iface->ifa_next) {
-      if(curl_strequal(iface->ifa_name, interf)) {
+      if(strcasecompare(iface->ifa_name, interf)) {
         result = TRUE;
         break;
       }
@@ -132,7 +132,7 @@
     for(iface = head; iface != NULL; iface=iface->ifa_next) {
       if(iface->ifa_addr != NULL) {
         if(iface->ifa_addr->sa_family == af) {
-          if(curl_strequal(iface->ifa_name, interf)) {
+          if(strcasecompare(iface->ifa_name, interf)) {
             void *addr;
             char *ip;
             char scope[12] = "";
@@ -180,7 +180,7 @@
           }
         }
         else if((res == IF2IP_NOT_FOUND) &&
-                curl_strequal(iface->ifa_name, interf)) {
+                strcasecompare(iface->ifa_name, interf)) {
           res = IF2IP_AF_NOT_SUPPORTED;
         }
       }
diff --git a/lib/imap.c b/lib/imap.c
index 123ea3b..78dc6fa 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -68,16 +68,15 @@
 #include "http.h" /* for HTTP proxy tunnel stuff */
 #include "socks.h"
 #include "imap.h"
-
 #include "strtoofft.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "vtls/vtls.h"
 #include "connect.h"
 #include "strerror.h"
 #include "select.h"
 #include "multiif.h"
 #include "url.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "curl_sasl.h"
 #include "warnless.h"
 
@@ -108,7 +107,7 @@
                                           const char *initresp);
 static CURLcode imap_continue_authenticate(struct connectdata *conn,
                                            const char *resp);
-static void imap_get_message(char *buffer, char** outptr);
+static void imap_get_message(char *buffer, char **outptr);
 
 /*
  * IMAP protocol handler.
@@ -271,7 +270,7 @@
 
   /* Does the command name match and is it followed by a space character or at
      the end of line? */
-  if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) &&
+  if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) &&
      (line[cmd_len] == ' ' || line + cmd_len + 2 == end))
     return TRUE;
 
@@ -391,10 +390,10 @@
  *
  * Gets the authentication message from the response buffer.
  */
-static void imap_get_message(char *buffer, char** outptr)
+static void imap_get_message(char *buffer, char **outptr)
 {
   size_t len = 0;
-  char* message = NULL;
+  char *message = NULL;
 
   /* Find the start of the message */
   for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
@@ -846,7 +845,7 @@
 
   if(imapcode != 'O') {
     failf(data, "Got unexpected imap-server response");
-    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+    result = CURLE_WEIRD_SERVER_REPLY;
   }
   else
     result = imap_perform_capability(conn);
@@ -1179,7 +1178,7 @@
   else {
     /* We don't know how to parse this line */
     failf(pp->conn->data, "Failed to parse FETCH response.");
-    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+    result = CURLE_WEIRD_SERVER_REPLY;
   }
 
   /* End of DO phase */
@@ -1198,7 +1197,7 @@
   (void)instate; /* No use for this yet */
 
   if(imapcode != 'O')
-    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
+    result = CURLE_WEIRD_SERVER_REPLY;
   else
     /* End of DONE phase */
     state(conn, IMAP_STOP);
@@ -1275,7 +1274,7 @@
 
     /* Was there an error parsing the response line? */
     if(imapcode == -1)
-      return CURLE_FTP_WEIRD_SERVER_REPLY;
+      return CURLE_WEIRD_SERVER_REPLY;
 
     if(!imapcode)
       break;
@@ -1935,7 +1934,7 @@
     while(*ptr && *ptr != ';')
       ptr++;
 
-    if(strnequal(key, "AUTH=", 5))
+    if(strncasecompare(key, "AUTH=", 5))
       result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
                                                value, ptr - value);
     else
@@ -2031,28 +2030,28 @@
        PARTIAL) stripping of the trailing slash character if it is present.
 
        Note: Unknown parameters trigger a URL_MALFORMAT error. */
-    if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
+    if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) {
       if(valuelen > 0 && value[valuelen - 1] == '/')
         value[valuelen - 1] = '\0';
 
       imap->uidvalidity = value;
       value = NULL;
     }
-    else if(Curl_raw_equal(name, "UID") && !imap->uid) {
+    else if(strcasecompare(name, "UID") && !imap->uid) {
       if(valuelen > 0 && value[valuelen - 1] == '/')
         value[valuelen - 1] = '\0';
 
       imap->uid = value;
       value = NULL;
     }
-    else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
+    else if(strcasecompare(name, "SECTION") && !imap->section) {
       if(valuelen > 0 && value[valuelen - 1] == '/')
         value[valuelen - 1] = '\0';
 
       imap->section = value;
       value = NULL;
     }
-    else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) {
+    else if(strcasecompare(name, "PARTIAL") && !imap->partial) {
       if(valuelen > 0 && value[valuelen - 1] == '/')
         value[valuelen - 1] = '\0';
 
diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c
index 416005c..38311e3 100644
--- a/lib/inet_ntop.c
+++ b/lib/inet_ntop.c
@@ -184,10 +184,10 @@
 {
   switch (af) {
   case AF_INET:
-    return inet_ntop4((const unsigned char*)src, buf, size);
+    return inet_ntop4((const unsigned char *)src, buf, size);
 #ifdef ENABLE_IPV6
   case AF_INET6:
-    return inet_ntop6((const unsigned char*)src, buf, size);
+    return inet_ntop6((const unsigned char *)src, buf, size);
 #endif
   default:
     SET_ERRNO(EAFNOSUPPORT);
diff --git a/lib/krb5.c b/lib/krb5.c
index 87ce8ee..067b0a5 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -121,7 +121,7 @@
   /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
    * libraries modify the input buffer in gss_seal()
    */
-  dec.value = (void*)from;
+  dec.value = (void *)from;
   dec.length = length;
   maj = gss_seal(&min, *context,
                  level == PROT_PRIVATE,
@@ -182,7 +182,7 @@
   for(;;) {
     /* this really shouldn't be repeated here, but can't help it */
     if(service == srv_host) {
-      result = Curl_ftpsendf(conn, "AUTH GSSAPI");
+      result = Curl_ftpsend(conn, "AUTH GSSAPI");
       if(result)
         return -2;
 
@@ -243,16 +243,22 @@
       }
 
       if(output_buffer.length != 0) {
+        char *cmd;
+
         result = Curl_base64_encode(data, (char *)output_buffer.value,
                                     output_buffer.length, &p, &base64_sz);
         if(result) {
           Curl_infof(data, "base64-encoding: %s\n",
                      curl_easy_strerror(result));
-          ret = AUTH_CONTINUE;
+          ret = AUTH_ERROR;
           break;
         }
 
-        result = Curl_ftpsendf(conn, "ADAT %s", p);
+        cmd = aprintf("ADAT %s", p);
+        if(cmd)
+          result = Curl_ftpsend(conn, cmd);
+        else
+          result = CURLE_OUT_OF_MEMORY;
 
         free(p);
 
diff --git a/lib/ldap.c b/lib/ldap.c
index a164627..a366e0c 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -69,12 +69,11 @@
 #include "escape.h"
 #include "progress.h"
 #include "transfer.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "strtok.h"
 #include "curl_ldap.h"
 #include "curl_multibyte.h"
 #include "curl_base64.h"
-#include "rawstr.h"
 #include "connect.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -272,7 +271,7 @@
     ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
 #else
     int ldap_option;
-    char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
+    char *ldap_ca = conn->ssl_config.CAfile;
 #if defined(CURL_HAS_NOVELL_LDAPSDK)
     rc = ldapssl_client_init(NULL, NULL);
     if(rc != LDAP_SUCCESS) {
@@ -280,11 +279,11 @@
       result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
-    if(data->set.ssl.verifypeer) {
+    if(conn->ssl_config.verifypeer) {
       /* Novell SDK supports DER or BASE64 files. */
       int cert_type = LDAPSSL_CERT_FILETYPE_B64;
-      if((data->set.str[STRING_CERT_TYPE]) &&
-         (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
+      if((data->set.ssl.cert_type) &&
+         (strcasecompare(data->set.ssl.cert_type, "DER")))
         cert_type = LDAPSSL_CERT_FILETYPE_DER;
       if(!ldap_ca) {
         failf(data, "LDAP local: ERROR %s CA cert not set!",
@@ -322,10 +321,10 @@
       goto quit;
     }
 #elif defined(LDAP_OPT_X_TLS)
-    if(data->set.ssl.verifypeer) {
+    if(conn->ssl_config.verifypeer) {
       /* OpenLDAP SDK supports BASE64 files. */
-      if((data->set.str[STRING_CERT_TYPE]) &&
-         (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
+      if((data->set.ssl.cert_type) &&
+         (!strcasecompare(data->set.ssl.cert_type, "PEM"))) {
         failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
         result = CURLE_SSL_CERTPROBLEM;
         goto quit;
@@ -708,16 +707,16 @@
  */
 static int str2scope (const char *p)
 {
-  if(strequal(p, "one"))
-     return LDAP_SCOPE_ONELEVEL;
-  if(strequal(p, "onetree"))
-     return LDAP_SCOPE_ONELEVEL;
-  if(strequal(p, "base"))
-     return LDAP_SCOPE_BASE;
-  if(strequal(p, "sub"))
-     return LDAP_SCOPE_SUBTREE;
-  if(strequal(p, "subtree"))
-     return LDAP_SCOPE_SUBTREE;
+  if(strcasecompare(p, "one"))
+    return LDAP_SCOPE_ONELEVEL;
+  if(strcasecompare(p, "onetree"))
+    return LDAP_SCOPE_ONELEVEL;
+  if(strcasecompare(p, "base"))
+    return LDAP_SCOPE_BASE;
+  if(strcasecompare(p, "sub"))
+    return LDAP_SCOPE_SUBTREE;
+  if(strcasecompare(p, "subtree"))
+    return LDAP_SCOPE_SUBTREE;
   return (-1);
 }
 
@@ -767,7 +766,7 @@
  *
  * Defined in RFC4516 section 2.
  */
-static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
+static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
 {
   int rc = LDAP_SUCCESS;
   char *path;
@@ -776,9 +775,9 @@
   size_t i;
 
   if(!conn->data ||
-      !conn->data->state.path ||
-      conn->data->state.path[0] != '/' ||
-      !checkprefix("LDAP", conn->data->change.url))
+     !conn->data->state.path ||
+     conn->data->state.path[0] != '/' ||
+     !checkprefix("LDAP", conn->data->change.url))
     return LDAP_INVALID_SYNTAX;
 
   ludp->lud_scope = LDAP_SCOPE_BASE;
@@ -798,12 +797,13 @@
   if(*p) {
     char *dn = p;
     char *unescaped;
+    CURLcode result;
 
     LDAP_TRACE (("DN '%s'\n", dn));
 
     /* Unescape the DN */
-    unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
-    if(!unescaped) {
+    result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE);
+    if(result) {
       rc = LDAP_NO_MEMORY;
 
       goto quit;
@@ -862,12 +862,14 @@
 
     for(i = 0; i < count; i++) {
       char *unescaped;
+      CURLcode result;
 
       LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
 
       /* Unescape the attribute */
-      unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
-      if(!unescaped) {
+      result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
+                              FALSE);
+      if(result) {
         free(attributes);
 
         rc = LDAP_NO_MEMORY;
@@ -930,12 +932,13 @@
   if(*p) {
     char *filter = p;
     char *unescaped;
+    CURLcode result;
 
     LDAP_TRACE (("filter '%s'\n", filter));
 
     /* Unescape the filter */
-    unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
-    if(!unescaped) {
+    result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
+    if(result) {
       rc = LDAP_NO_MEMORY;
 
       goto quit;
@@ -971,8 +974,8 @@
   return rc;
 }
 
-static int _ldap_url_parse (const struct connectdata *conn,
-                            LDAPURLDesc **ludpp)
+static int _ldap_url_parse(const struct connectdata *conn,
+                           LDAPURLDesc **ludpp)
 {
   LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
   int rc;
@@ -981,7 +984,7 @@
   if(!ludp)
      return LDAP_NO_MEMORY;
 
-  rc = _ldap_url_parse2 (conn, ludp);
+  rc = _ldap_url_parse2(conn, ludp);
   if(rc != LDAP_SUCCESS) {
     _ldap_free_urldesc(ludp);
     ludp = NULL;
@@ -990,7 +993,7 @@
   return (rc);
 }
 
-static void _ldap_free_urldesc (LDAPURLDesc *ludp)
+static void _ldap_free_urldesc(LDAPURLDesc *ludp)
 {
   size_t i;
 
diff --git a/lib/libcurl.rc b/lib/libcurl.rc
index 50b365d..c1efbad 100644
--- a/lib/libcurl.rc
+++ b/lib/libcurl.rc
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,12 +44,12 @@
   BEGIN
     BLOCK "040904b0"
     BEGIN
-      VALUE "CompanyName",      "The cURL library, https://curl.haxx.se/\0"
+      VALUE "CompanyName",      "The curl library, https://curl.haxx.se/\0"
       VALUE "FileDescription",  "libcurl Shared Library\0"
       VALUE "FileVersion",      LIBCURL_VERSION "\0"
       VALUE "InternalName",     "libcurl\0"
       VALUE "OriginalFilename", "libcurl.dll\0"
-      VALUE "ProductName",      "The cURL library\0"
+      VALUE "ProductName",      "The curl library\0"
       VALUE "ProductVersion",   LIBCURL_VERSION "\0"
       VALUE "LegalCopyright",   "© " LIBCURL_COPYRIGHT "\0"
       VALUE "License",          "https://curl.haxx.se/docs/copyright.html\0"
diff --git a/lib/md5.c b/lib/md5.c
index 84adb99..7a1cac9 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -45,7 +45,7 @@
 }
 
 static void MD5_Update(MD5_CTX * ctx,
-                       const unsigned char * input,
+                       const unsigned char *input,
                        unsigned int inputLen)
 {
   md5_update(ctx, inputLen, input);
@@ -71,7 +71,7 @@
 }
 
 static void MD5_Update(MD5_CTX * ctx,
-                       const unsigned char * input,
+                       const unsigned char *input,
                        unsigned int inputLen)
 {
   gcry_md_write(*ctx, input, inputLen);
@@ -124,7 +124,7 @@
   CC_MD5_Final(digest, ctx);
 }
 
-#elif defined(_WIN32)
+#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
 
 #include <wincrypt.h>
 #include "curl_memory.h"
diff --git a/lib/memdebug.c b/lib/memdebug.c
index ccbf461..15e8661 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -90,7 +90,7 @@
   union {
     curl_off_t o;
     double d;
-    void * p;
+    void *p;
   } mem[1];
   /* I'm hoping this is the thing with the strictest alignment
    * requirements.  That also means we waste some space :-( */
diff --git a/lib/mk-ca-bundle.pl b/lib/mk-ca-bundle.pl
index 5a1435c..9574f1d 100755
--- a/lib/mk-ca-bundle.pl
+++ b/lib/mk-ca-bundle.pl
@@ -6,7 +6,7 @@
 # *                            | (__| |_| |  _ <| |___
 # *                             \___|\___/|_| \_\_____|
 # *
-# * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+# * Copyright (C) 1998 - 2016, 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 @@
 # dependency is the OpenSSL commandline tool for optional text listing.
 # Hacked by Guenter Knauf.
 #
+use Encode;
 use Getopt::Std;
 use MIME::Base64;
-use LWP::UserAgent;
 use strict;
-use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
+use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
 use List::Util;
 use Text::Wrap;
 my $MOD_SHA = "Digest::SHA";
@@ -43,18 +43,19 @@
   $MOD_SHA = "Digest::SHA::PurePerl";
   eval "require $MOD_SHA";
 }
+eval "require LWP::UserAgent";
 
 my %urls = (
   'nss' =>
-    'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
+    'https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
   'central' =>
-    'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
+    'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
   'aurora' =>
-    'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
+    'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
   'beta' =>
-    'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
+    'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
   'release' =>
-    'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
+    'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
 );
 
 $opt_d = 'release';
@@ -62,7 +63,7 @@
 # If the OpenSSL commandline is not in search path you can configure it here!
 my $openssl = 'openssl';
 
-my $version = '1.25';
+my $version = '1.27';
 
 $opt_w = 76; # default base64 encoded lines length
 
@@ -109,7 +110,7 @@
 
 $0 =~ s@.*(/|\\)@@;
 $Getopt::Std::STANDARD_HELP_VERSION = 1;
-getopts('bd:fhilnp:qs:tuvw:');
+getopts('bd:fhiklmnp:qs:tuvw:');
 
 if(!defined($opt_d)) {
     # to make plain "-d" use not cause warnings, and actually still work
@@ -117,7 +118,16 @@
 }
 
 # Use predefined URL or else custom URL specified on command line.
-my $url = ( defined( $urls{$opt_d} ) ) ? $urls{$opt_d} : $opt_d;
+my $url;
+if(defined($urls{$opt_d})) {
+  $url = $urls{$opt_d};
+  if(!$opt_k && $url !~ /^https:\/\//i) {
+    die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n";
+  }
+}
+else {
+  $url = $opt_d;
+}
 
 my $curl = `curl -V`;
 
@@ -128,8 +138,8 @@
   print "Operating System Name            : $^O\n";
   print "Getopt::Std.pm Version           : ${Getopt::Std::VERSION}\n";
   print "MIME::Base64.pm Version          : ${MIME::Base64::VERSION}\n";
-  print "LWP::UserAgent.pm Version        : ${LWP::UserAgent::VERSION}\n";
-  print "LWP.pm Version                   : ${LWP::VERSION}\n";
+  print "LWP::UserAgent.pm Version        : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION);
+  print "LWP.pm Version                   : ${LWP::VERSION}\n" if($LWP::VERSION);
   print "Digest::SHA.pm Version           : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
   print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
   print ("=" x 78 . "\n");
@@ -139,7 +149,7 @@
   if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
     print "Warning: Use of this script may pose some risk:\n";
     print "\n";
-    print "  1) Using http is subject to man in the middle attack of certdata content\n";
+    print "  1) If you use HTTP URLs they are subject to a man in the middle attack\n";
     print "  2) Default to 'release', but more recent updates may be found in other trees\n";
     print "  3) certdata.txt file format may change, lag time to update this script\n";
     print "  4) Generally unwise to blindly trust CAs without manual review & verification\n";
@@ -153,14 +163,16 @@
 }
 
 sub HELP_MESSAGE() {
-  print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
+  print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-k] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
   print "\t-b\tbackup an existing version of ca-bundle.crt\n";
   print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
   print "\t\t  Valid names are:\n";
   print "\t\t    ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
   print "\t-f\tforce rebuild even if certdata.txt is current\n";
   print "\t-i\tprint version info about used modules\n";
+  print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n";
   print "\t-l\tprint license info about certdata.txt\n";
+  print "\t-m\tinclude meta data in output\n";
   print "\t-n\tno download of certdata.txt (to use existing)\n";
   print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n";
   print "\t\t  Valid purposes are:\n";
@@ -224,33 +236,34 @@
   return @values;
 }
 
-sub sha1 {
+sub sha256 {
   my $result;
   if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) {
     open(FILE, $_[0]) or die "Can't open '$_[0]': $!";
     binmode(FILE);
-    $result = $MOD_SHA->new(1)->addfile(*FILE)->hexdigest;
+    $result = $MOD_SHA->new(256)->addfile(*FILE)->hexdigest;
     close(FILE);
   } else {
     # Use OpenSSL command if Perl Digest::SHA modules not available
-    $result = (split(/ |\r|\n/,`$openssl dgst -sha1 $_[0]`))[1];
+    $result = `"$openssl" dgst -r -sha256 "$_[0]"`;
+    $result =~ s/^([0-9a-f]{64}) .+/$1/is;
   }
   return $result;
 }
 
 
-sub oldsha1 {
-  my $sha1 = "";
+sub oldhash {
+  my $hash = "";
   open(C, "<$_[0]") || return 0;
   while(<C>) {
     chomp;
-    if($_ =~ /^\#\# SHA1: (.*)/) {
-      $sha1 = $1;
+    if($_ =~ /^\#\# SHA256: (.*)/) {
+      $hash = $1;
       last;
     }
   }
   close(C);
-  return $sha1;
+  return $hash;
 }
 
 if ( $opt_p !~ m/:/ ) {
@@ -282,39 +295,72 @@
 my $resp;
 my $fetched;
 
-my $oldsha1 = oldsha1($crt);
+my $oldhash = oldhash($crt);
 
-report "SHA1 of old file: $oldsha1";
+report "SHA256 of old file: $oldhash";
 
-report "Downloading '$txt' ...";
+if(!$opt_n) {
+  report "Downloading $txt ...";
 
-if($curl && !$opt_n) {
-  my $https = $url;
-  $https =~ s/^http:/https:/;
-  report "Get certdata over HTTPS with curl!";
-  my $quiet = $opt_q ? "-s" : "";
-  my @out = `curl -w %{response_code} $quiet -O $https`;
-  if(@out && $out[0] == 200) {
-    $fetched = 1;
-  } else {
-    report "Failed downloading HTTPS with curl, trying HTTP with LWP";
+  # If we have an HTTPS URL then use curl
+  if($url =~ /^https:\/\//i) {
+    if($curl) {
+      if($curl =~ /^Protocols:.* https( |$)/m) {
+        report "Get certdata with curl!";
+        my $proto = !$opt_k ? "--proto =https" : "";
+        my $quiet = $opt_q ? "-s" : "";
+        my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`;
+        if(@out && $out[0] == 200) {
+          $fetched = 1;
+          report "Downloaded $txt";
+        }
+        else {
+          report "Failed downloading via HTTPS with curl";
+          if(-e $txt && !unlink($txt)) {
+            report "Failed to remove '$txt': $!";
+          }
+        }
+      }
+      else {
+        report "curl lacks https support";
+      }
+    }
+    else {
+      report "curl not found";
+    }
   }
-}
 
-unless ($fetched || ($opt_n and -e $txt)) {
-  my $ua  = new LWP::UserAgent(agent => "$0/$version");
-  $ua->env_proxy();
-  $resp = $ua->mirror($url, $txt);
-  if ($resp && $resp->code eq '304') {
-    report "Not modified";
-    exit 0 if -e $crt && !$opt_f;
-  } else {
+  # If nothing was fetched then use LWP
+  if(!$fetched) {
+    if($url =~ /^https:\/\//i) {
+      report "Falling back to HTTP";
+      $url =~ s/^https:\/\//http:\/\//i;
+    }
+    if(!$opt_k) {
+      report "URLs other than HTTPS are disabled by default, to enable use -k";
+      exit 1;
+    }
+    report "Get certdata with LWP!";
+    if(!defined(${LWP::UserAgent::VERSION})) {
+      report "LWP is not available (LWP::UserAgent not found)";
+      exit 1;
+    }
+    my $ua  = new LWP::UserAgent(agent => "$0/$version");
+    $ua->env_proxy();
+    $resp = $ua->mirror($url, $txt);
+    if($resp && $resp->code eq '304') {
+      report "Not modified";
+      exit 0 if -e $crt && !$opt_f;
+    }
+    else {
       $fetched = 1;
-  }
-  if( !$resp || $resp->code !~ /^(?:200|304)$/ ) {
+      report "Downloaded $txt";
+    }
+    if(!$resp || $resp->code !~ /^(?:200|304)$/) {
       report "Unable to download latest data: "
         . ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
       exit 1 if -e $crt || ! -r $txt;
+    }
   }
 }
 
@@ -327,14 +373,14 @@
 }
 
 # get the hash from the download file
-my $newsha1= sha1($txt);
+my $newhash= sha256($txt);
 
-if(!$opt_f && $oldsha1 eq $newsha1) {
+if(!$opt_f && $oldhash eq $newhash) {
     report "Downloaded file identical to previous run\'s source file. Exiting";
     exit;
 }
 
-report "SHA1 of new file: $newsha1";
+report "SHA256 of new file: $newhash";
 
 my $currentdate = scalar gmtime($filedate);
 
@@ -348,7 +394,7 @@
 ##
 ## Bundle of CA Root Certificates
 ##
-## Certificate data from Mozilla ${datesrc}: ${currentdate}
+## Certificate data from Mozilla ${datesrc}: ${currentdate} GMT
 ##
 ## This is a bundle of X.509 certificates of public Certificate Authorities
 ## (CA). These were automatically extracted from Mozilla's root certificates
@@ -361,7 +407,7 @@
 ## Just configure this file as the SSLCACertificateFile.
 ##
 ## Conversion done with mk-ca-bundle.pl version $version.
-## SHA1: $newsha1
+## SHA256: $newhash
 ##
 
 EOT
@@ -371,6 +417,7 @@
 my $certnum = 0;
 my $skipnum = 0;
 my $start_of_cert = 0;
+my @precert;
 
 open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
 while (<TXT>) {
@@ -383,11 +430,15 @@
       last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/);
     }
   }
-  next if /^#|^\s*$/;
-  chomp;
-  if (/^CVS_ID\s+\"(.*)\"/) {
-    print CRT "# $1\n";
+  elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
+      push @precert, $_;
+      next;
   }
+  elsif(/^#|^\s*$/) {
+      undef @precert;
+      next;
+  }
+  chomp;
 
   # this is a match for the start of a certificate
   if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
@@ -436,8 +487,8 @@
               . $encoded
               . "-----END CERTIFICATE-----\n";
       print CRT "\n$caname\n";
-
-      my $maxStringLength = length($caname);
+      print CRT @precert if($opt_m);
+      my $maxStringLength = length(decode('UTF-8', $caname, Encode::FB_CROAK));
       if ($opt_t) {
         foreach my $key (keys %trust_purposes_by_level) {
            my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}});
@@ -479,7 +530,9 @@
       $certnum ++;
       $start_of_cert = 0;
     }
+    undef @precert;
   }
+
 }
 close(TXT) or die "Couldn't close $txt: $!\n";
 close(CRT) or die "Couldn't close $crt.~: $!\n";
@@ -495,5 +548,7 @@
     }
     rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
 }
-unlink $txt if ($opt_u);
+if($opt_u && -e $txt && !unlink($txt)) {
+  report "Failed to remove $txt: $!\n";
+}
 report "Done ($certnum CA certs processed, $skipnum skipped).";
diff --git a/lib/mk-ca-bundle.vbs b/lib/mk-ca-bundle.vbs
index b0d9427..a9b983e 100755
--- a/lib/mk-ca-bundle.vbs
+++ b/lib/mk-ca-bundle.vbs
@@ -26,20 +26,36 @@
 '* Hacked by Guenter Knauf

 '***************************************************************************

 Option Explicit

-Const myVersion = "0.3.9"

+Const myVersion = "0.4.0"

 

-Const myUrl = "http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"

-Const myOpenssl = "openssl.exe"

+Const myUrl = "https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"

 

-Const myCdSavF = FALSE       ' Flag: save downloaded data to file certdata.txt

+Const myOpenSSL = "openssl.exe"

+Dim myUseOpenSSL

+myUseOpenSSL = TRUE          ' Flag: TRUE to use OpenSSL. If TRUE and is not

+                             ' found then a warning is shown before continuing.

+

+Const myCdSavF = TRUE        ' Flag: save downloaded data to file certdata.txt

 Const myCaBakF = TRUE        ' Flag: backup existing ca-bundle certificate

 Const myAskLiF = TRUE        ' Flag: display certdata.txt license agreement

-Const myAskTiF = TRUE        ' Flag: ask to include certificate text info

 Const myWrapLe = 76          ' Default length of base64 output lines

 

+' cert info code doesn't work properly with any recent openssl, leave disabled.

+' Also: we want our certificate output by default to be as similar as possible

+' to mk-ca-bundle.pl and setting this TRUE changes the base64 width to

+' OpenSSL's built-in default width, which is not the same as mk-ca-bundle.pl.

+Const myAskTiF = FALSE       ' Flag: ask to include certificate text info

+

+'

 '******************* Nothing to configure below! *******************

+'

+Const adTypeBinary = 1

+Const adTypeText = 2

+Const adSaveCreateNotExist = 1

+Const adSaveCreateOverWrite = 2

 Dim objShell, objNetwork, objFSO, objHttp

-Dim myBase, mySelf, myFh, myTmpFh, myCdData, myCdFile, myCaFile, myTmpName, myBakNum, myOptTxt, i

+Dim myBase, mySelf, myStream, myTmpFh, myCdData, myCdFile

+Dim myCaFile, myTmpName, myBakNum, myOptTxt, i

 Set objNetwork = WScript.CreateObject("WScript.Network")

 Set objShell = WScript.CreateObject("WScript.Shell")

 Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

@@ -47,14 +63,60 @@
 If objHttp Is Nothing Then Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest")

 myBase = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))

 mySelf = Left(WScript.ScriptName, InstrRev(WScript.ScriptName, ".") - 1) & " " & myVersion

+

 myCdFile = Mid(myUrl, InstrRev(myUrl, "/") + 1)

 myCaFile = "ca-bundle.crt"

-myTmpName = InputBox("Enter output filename:", mySelf, myCaFile)

-If Not (myTmpName = "") Then

-  myCaFile = myTmpName

+myTmpName = InputBox("It will take a minute to download and parse the " & _

+                     "certificate data." & _

+                     vbLf & vbLf & _

+                     "Please enter the output filename:", mySelf, myCaFile)

+If (myTmpName = "") Then

+  WScript.Quit 1

 End If

-' Lets ignore SSL invalid cert errors

-objHttp.Option(4) = 256 + 512 + 4096 + 8192

+myCaFile = myTmpName

+If (myCdFile = "") Then

+  MsgBox("URL does not contain filename!"), vbCritical, mySelf

+  WScript.Quit 1

+End If

+

+' Don't use OpenSSL if it's not present.

+If (myUseOpenSSL = TRUE) Then

+  Dim errnum

+

+  On Error Resume Next

+  Call objShell.Run("""" & myOpenSSL & """ version", 0, TRUE)

+  errnum = Err.Number

+  On Error GoTo 0

+

+  If Not (errnum = 0) Then

+    myUseOpenSSL = FALSE

+    MsgBox("OpenSSL was not found so the certificate bundle will not " & _

+           "include the SHA256 hash of the raw certificate data file " & _

+           "that was used to generate the certificates in the bundle. " & _

+           vbLf & vbLf & _

+           "This does not have any effect on the certificate output, " & _

+           "so this script will continue." & _

+           vbLf & vbLf & _

+           "If you want to set a custom location for OpenSSL or disable " & _

+           "this message then edit the variables at the start of the " & _

+           "script."), vbInformation, mySelf

+  End If

+End If

+

+If (myAskTiF = TRUE) And (myUseOpenSSL = TRUE) Then

+  If (6 = objShell.PopUp("Do you want to include text information about " & _

+                         "each certificate?" & vbLf & _

+                         "(Requires OpenSSL.exe in the current directory " & _

+                         "or search path)",, _

+          mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then

+    myOptTxt = TRUE

+  Else

+    myOptTxt = FALSE

+  End If

+End If

+

+' Uncomment the line below to ignore SSL invalid cert errors

+' objHttp.Option(4) = 256 + 512 + 4096 + 8192

 objHttp.SetTimeouts 0, 5000, 10000, 10000

 objHttp.Open "GET", myUrl, FALSE

 objHttp.setRequestHeader "User-Agent", WScript.ScriptName & "/" & myVersion

@@ -63,15 +125,13 @@
   MsgBox("Failed to download '" & myCdFile & "': " & objHttp.Status & " - " & objHttp.StatusText), vbCritical, mySelf

   WScript.Quit 1

 End If

-' Convert data from ResponseBody instead of using ResponseText because of UTF-8

-myCdData = ConvertBinaryData(objHttp.ResponseBody)

-Set objHttp = Nothing

 ' Write received data to file if enabled

 If (myCdSavF = TRUE) Then

-  Set myFh = objFSO.OpenTextFile(myCdFile, 2, TRUE)

-  myFh.Write myCdData

-  myFh.Close

+  Call SaveBinaryData(myCdFile, objHttp.ResponseBody)

 End If

+' Convert data from ResponseBody instead of using ResponseText because of UTF-8

+myCdData = ConvertBinaryToUTF8(objHttp.ResponseBody)

+Set objHttp = Nothing

 ' Backup exitsing ca-bundle certificate file

 If (myCaBakF = TRUE) Then

   If objFSO.FileExists(myCaFile) Then

@@ -86,15 +146,7 @@
     myTmpFh.Move myBakFile

   End If

 End If

-If (myAskTiF = TRUE) Then

-  If (6 = objShell.PopUp("Do you want to include text information about each certificate?" & vbLf & _

-          "(requires OpenSSL commandline in current directory or in search path)",, _

-          mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then

-    myOptTxt = TRUE

-  Else

-    myOptTxt = FALSE

-  End If

-End If

+

 ' Process the received data

 Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped

 Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j

@@ -102,23 +154,33 @@
 myNumCerts = 0

 myData = ""

 myLines = Split(myCdData, vbLf, -1)

-Set myFh = objFSO.OpenTextFile(myCaFile, 2, TRUE)

-myFh.Write "##" & vbLf

-myFh.Write "## " & myCaFile & " -- Bundle of CA Root Certificates" & vbLf

-myFh.Write "##" & vbLf

-myFh.Write "## Converted at: " & Now & vbLf

-myFh.Write "##" & vbLf

-myFh.Write "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf

-myFh.Write "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf

-myFh.Write "## file (certdata.txt).  This file can be found in the mozilla source tree:" & vbLf

-myFh.Write "## '/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt'" & vbLf

-myFh.Write "##" & vbLf

-myFh.Write "## It contains the certificates in PEM format and therefore" & vbLf

-myFh.Write "## can be directly used with curl / libcurl / php_curl, or with" & vbLf

-myFh.Write "## an Apache+mod_ssl webserver for SSL client authentication." & vbLf

-myFh.Write "## Just configure this file as the SSLCACertificateFile." & vbLf

-myFh.Write "##" & vbLf

-myFh.Write vbLf

+Set myStream = CreateObject("ADODB.Stream")

+myStream.Open

+myStream.Type = adTypeText

+myStream.Charset = "utf-8"

+myStream.WriteText "##" & vbLf & _

+  "## Bundle of CA Root Certificates" & vbLf & _

+  "##" & vbLf & _

+  "## Certificate data from Mozilla as of: " & _

+    ConvertDateToString(LocalDateToUTC(Now)) & " GMT" & vbLf & _

+  "##" & vbLf & _

+  "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf & _

+  "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf & _

+  "## file (certdata.txt).  This file can be found in the mozilla source tree:" & vbLf & _

+  "## " & myUrl & vbLf & _

+  "##" & vbLf & _

+  "## It contains the certificates in PEM format and therefore" & vbLf & _

+  "## can be directly used with curl / libcurl / php_curl, or with" & vbLf & _

+  "## an Apache+mod_ssl webserver for SSL client authentication." & vbLf & _

+  "## Just configure this file as the SSLCACertificateFile." & vbLf & _

+  "##" & vbLf & _

+  "## Conversion done with mk-ca-bundle.vbs version " & myVersion & "." & vbLf

+If (myCdSavF = TRUE) And (myUseOpenSSL = TRUE) Then

+  myStream.WriteText "## SHA256: " & FileSHA256(myCdFile) & vbLf

+End If

+myStream.WriteText "##" & vbLf & vbLf

+

+myStream.WriteText vbLf

 For i = 0 To UBound(myLines)

   If InstrRev(myLines(i), "CKA_LABEL ") Then

     myPattern = "^CKA_LABEL\s+[A-Z0-9]+\s+""(.+?)"""

@@ -136,13 +198,13 @@
       If (myUntrusted = TRUE) Then

         myNumSkipped = myNumSkipped + 1

       Else

-        myFh.Write myLabel & vbLf

-        myFh.Write String(Len(myLabel), "=") & vbLf

+        myStream.WriteText myLabel & vbLf

+        myStream.WriteText String(Len(myLabel), "=") & vbLf

         myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _

                 Base64Encode(myData) & vbLf & _

                 "-----END CERTIFICATE-----" & vbLf

         If (myOptTxt = FALSE) Then

-          myFh.Write myPem & vbLf

+          myStream.WriteText myPem & vbLf

         Else

           Dim myCmd, myRval, myTmpIn, myTmpOut

           myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName

@@ -150,8 +212,8 @@
           Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE)

           myTmpFh.Write myPem

           myTmpFh.Close

-          myCmd = myOpenssl & " x509 -md5 -fingerprint -text -inform PEM" & _

-                  " -in " & myTmpIn & " -out " & myTmpOut

+          myCmd = """" & myOpenSSL & """ x509 -md5 -fingerprint -text " & _

+                  "-inform PEM -in " & myTmpIn & " -out " & myTmpOut

           myRval = objShell.Run (myCmd, 0, TRUE)

           objFSO.DeleteFile myTmpIn, TRUE

           If Not (myRval = 0) Then

@@ -160,7 +222,7 @@
             WScript.Quit 3

           End If

           Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1)

-          myFh.Write myTmpFh.ReadAll & vbLf

+          myStream.WriteText myTmpFh.ReadAll & vbLf

           myTmpFh.Close

           objFSO.DeleteFile myTmpOut, TRUE

         End If

@@ -176,7 +238,7 @@
   If InstrRev(myLines(i), "CVS_ID ") Then

     myPattern = "^CVS_ID\s+""(.+?)"""

     myRev = RegExprFirst(myPattern, myLines(i))

-    myFh.Write "# " & myRev & vbLf & vbLf

+    myStream.WriteText "# " & myRev & vbLf & vbLf

   End If

   If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then

     myInsideCert = TRUE

@@ -187,7 +249,7 @@
     myInsideLicense = TRUE

   End If

   If (myInsideLicense = TRUE) Then

-    myFh.Write myLines(i) & vbLf

+    myStream.WriteText myLines(i) & vbLf

     myLicenseText = myLicenseText & Mid(myLines(i), 2) & vbLf

   End If

   If InstrRev(myLines(i), "***** END LICENSE BLOCK *****") Then

@@ -196,28 +258,54 @@
       If Not (6 = objShell.PopUp(myLicenseText & vbLf & _

               "Do you agree to the license shown above (required to proceed) ?",, _

               mySelf, vbQuestion + vbYesNo + vbDefaultButton1)) Then

-        myFh.Close

+        myStream.Close

         objFSO.DeleteFile myCaFile, TRUE

         WScript.Quit 2

       End If

     End If

   End If

 Next

-myFh.Close

+

+' To stop the UTF-8 BOM from being written the stream has to be copied and

+' then saved as binary.

+Dim myCopy

+Set myCopy = CreateObject("ADODB.Stream")

+myCopy.Type = adTypeBinary

+myCopy.Open

+myStream.Position = 3 ' Skip UTF-8 BOM

+myStream.CopyTo myCopy

+myCopy.SaveToFile myCaFile, adSaveCreateOverWrite

+myCopy.Close

+myStream.Close

+Set myCopy = Nothing

+Set myStream = Nothing

+

+' Done

 objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _

                " untrusted skipped).", 20, mySelf, vbInformation

 WScript.Quit 0

 

-Function ConvertBinaryData(arrBytes)

+Function ConvertBinaryToUTF8(arrBytes)

   Dim objStream

   Set objStream = CreateObject("ADODB.Stream")

   objStream.Open

-  objStream.Type = 1

+  objStream.Type = adTypeBinary

   objStream.Write arrBytes

   objStream.Position = 0

-  objStream.Type = 2

-  objStream.Charset = "ascii"

-  ConvertBinaryData = objStream.ReadText

+  objStream.Type = adTypeText

+  objStream.Charset = "utf-8"

+  ConvertBinaryToUTF8 = objStream.ReadText

+  Set objStream = Nothing

+End Function

+

+Function SaveBinaryData(filename, data)

+  Dim objStream

+  Set objStream = CreateObject("ADODB.Stream")

+  objStream.Type = adTypeBinary

+  objStream.Open

+  objStream.Write data

+  objStream.SaveToFile filename, adSaveCreateOverWrite

+  objStream.Close

   Set objStream = Nothing

 End Function

 

@@ -283,4 +371,61 @@
   If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar)

 End Function

 

+' Return the date in the same format as perl to match mk-ca-bundle.pl output:

+' Wed Sep  7 03:12:05 2016

+Function ConvertDateToString(input)

+  Dim output

+  output = WeekDayName(WeekDay(input), TRUE) & " " & _

+           MonthName(Month(input), TRUE) & " "

+  If (Len(Day(input)) = 1) Then

+    output = output & " "

+  End If

+  output = output & _

+           Day(input) & " " & _

+           FormatDateTime(input, vbShortTime) & ":"

+  If (Len(Second(input)) = 1) Then

+    output = output & "0"

+  End If

+  output = output & _

+           Second(input) & " " & _

+           Year(input)

+  ConvertDateToString = output

+End Function

 

+' Convert local Date to UTC. Microsoft says:

+' Use Win32_ComputerSystem CurrentTimeZone property, because it automatically

+' adjusts the Time Zone bias for daylight saving time; Win32_Time Zone Bias

+' property does not.

+' https://msdn.microsoft.com/en-us/library/windows/desktop/ms696015.aspx

+Function LocalDateToUTC(localdate)

+  Dim item, offset

+  For Each item In GetObject("winmgmts:").InstancesOf("Win32_ComputerSystem")

+    offset = item.CurrentTimeZone ' the offset in minutes

+  Next

+  If (offset < 0) Then

+    LocalDateToUTC = DateAdd("n",  ABS(offset), localdate)

+  Else

+    LocalDateToUTC = DateAdd("n", -ABS(offset), localdate)

+  End If

+  'objShell.PopUp LocalDateToUTC

+End Function

+

+Function FileSHA256(filename)

+  Dim cmd, rval, tmpOut, tmpFh

+  if (myUseOpenSSL = TRUE) Then

+    tmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName

+    cmd = """" & myOpenSSL & """ dgst -r -sha256 -out """ & tmpOut & """ """ & filename & """"

+    rval = objShell.Run(cmd, 0, TRUE)

+    If Not (rval = 0) Then

+      MsgBox("Failed to get sha256 of """ & filename & """ with OpenSSL commandline!"), vbCritical, mySelf

+      objFSO.DeleteFile tmpOut, TRUE

+      WScript.Quit 3

+    End If

+    Set tmpFh = objFSO.OpenTextFile(tmpOut, 1)

+    FileSHA256 = RegExprFirst("^([0-9a-f]{64}) .+", tmpFh.ReadAll)

+    tmpFh.Close

+    objFSO.DeleteFile tmpOut, TRUE

+  Else

+    FileSHA256 = ""

+  End If

+End Function

diff --git a/lib/mprintf.c b/lib/mprintf.c
index 73f854b..e1ad537 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -227,10 +227,12 @@
  * Create an index with the type of each parameter entry and its
  * value (may vary in size)
  *
+ * Returns zero on success.
+ *
  ******************************************************************/
 
-static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
-                          va_list arglist)
+static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
+                         va_list arglist)
 {
   char *fmt = (char *)format;
   int param_num = 0;
@@ -301,7 +303,6 @@
           flags |= FLAGS_ALT;
           break;
         case '.':
-          flags |= FLAGS_PREC;
           if('*' == *fmt) {
             /* The precision is picked from a specified parameter */
 
@@ -393,6 +394,10 @@
 
       i = this_param - 1;
 
+      if((i < 0) || (i >= MAX_PARAMETERS))
+        /* out of allowed range */
+        return 1;
+
       switch (*fmt) {
       case 'S':
         flags |= FLAGS_ALT;
@@ -549,7 +554,7 @@
     }
   }
 
-  return max_param;
+  return 0;
 
 }
 
@@ -587,7 +592,8 @@
   char *workend = &work[sizeof(work) - 2];
 
   /* Do the actual %-code parsing */
-  dprintf_Pass1(format, vto, endpos, ap_save);
+  if(dprintf_Pass1(format, vto, endpos, ap_save))
+    return -1;
 
   end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
                        created for us */
@@ -992,7 +998,7 @@
   info.max = maxlength;
 
   retcode = dprintf_formatf(&info, addbyter, format, ap_save);
-  if(info.max) {
+  if((retcode != -1) && info.max) {
     /* we terminate this with a zero byte */
     if(info.max == info.length)
       /* we're at maximum, scrap the last letter */
@@ -1029,16 +1035,19 @@
     infop->len =0;
   }
   else if(infop->len+1 >= infop->alloc) {
-    char *newptr;
+    char *newptr = NULL;
+    size_t newsize = infop->alloc*2;
 
-    newptr = realloc(infop->buffer, infop->alloc*2);
+    /* detect wrap-around or other overflow problems */
+    if(newsize > infop->alloc)
+      newptr = realloc(infop->buffer, newsize);
 
     if(!newptr) {
       infop->fail = 1;
       return -1; /* fail */
     }
     infop->buffer = newptr;
-    infop->alloc *= 2;
+    infop->alloc = newsize;
   }
 
   infop->buffer[ infop->len ] = outc;
diff --git a/lib/multi.c b/lib/multi.c
index 8bb9366..950b600 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -42,6 +42,8 @@
 #include "multihandle.h"
 #include "pipeline.h"
 #include "sigpipe.h"
+#include "vtls/vtls.h"
+#include "connect.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -442,7 +444,7 @@
      sockets that time-out or have actions will be dealt with. Since this
      handle has no action yet, we make sure it times out to get things to
      happen. */
-  Curl_expire(data, 1);
+  Curl_expire(data, 0);
 
   /* increase the node-counter */
   multi->num_easy++;
@@ -462,6 +464,14 @@
      handle is added */
   memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
 
+  /* The closure handle only ever has default timeouts set. To improve the
+     state somewhat we clone the timeouts from each added handle so that the
+     closure handle always has the same timeouts as the most recently added
+     easy handle. */
+  multi->closure_handle->set.timeout = data->set.timeout;
+  multi->closure_handle->set.server_response_timeout =
+    data->set.server_response_timeout;
+
   update_timer(multi);
   return CURLM_OK;
 }
@@ -569,12 +579,12 @@
       result = CURLE_ABORTED_BY_CALLBACK;
   }
 
-  if((!premature &&
-      conn->send_pipe->size + conn->recv_pipe->size != 0 &&
-      !data->set.reuse_forbid &&
-      !conn->bits.close)) {
+  if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+     !data->set.reuse_forbid &&
+     !conn->bits.close) {
     /* Stop if pipeline is not empty and we do not have to close
        connection. */
+    data->easy_conn = NULL;
     DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
     return CURLE_OK;
   }
@@ -685,7 +695,7 @@
     /* If the handle is in a pipeline and has started sending off its
        request but not received its response yet, we need to close
        connection. */
-    connclose(data->easy_conn, "Removed with partial response");
+    streamclose(data->easy_conn, "Removed with partial response");
     /* Set connection owner so that the DONE function closes it.  We can
        safely do this here since connection is killed. */
     data->easy_conn->data = easy;
@@ -695,7 +705,7 @@
   /* The timer must be shut down before data->multi is set to NULL,
      else the timenode will remain in the splay tree after
      curl_easy_cleanup is called. */
-  Curl_expire(data, 0);
+  Curl_expire_clear(data);
 
   if(data->dns.hostcachetype == HCACHE_MULTI) {
     /* stop using the multi handle's DNS cache */
@@ -803,6 +813,11 @@
   if(!numsocks)
     return GETSOCK_BLANK;
 
+#ifdef USE_SSL
+  if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+    return Curl_ssl_getsock(conn, sock, numsocks);
+#endif
+
   for(i=0; i<2; i++) {
     if(conn->tempsock[i] != CURL_SOCKET_BAD) {
       sock[s] = conn->tempsock[i];
@@ -1291,14 +1306,16 @@
   CURLMcode rc;
   CURLcode result = CURLE_OK;
   struct SingleRequest *k;
-  long timeout_ms;
+  time_t timeout_ms;
   int control;
 
   if(!GOOD_EASY_HANDLE(data))
     return CURLM_BAD_EASY_HANDLE;
 
   do {
-    bool disconnect_conn = FALSE;
+    /* A "stream" here is a logical stream if the protocol can handle that
+       (HTTP/2), or the full connection for older protocols */
+    bool stream_error = FALSE;
     rc = CURLM_OK;
 
     /* Handle the case when the pipe breaks, i.e., the connection
@@ -1376,8 +1393,8 @@
 
         /* Force connection closed if the connection has indeed been used */
         if(data->mstate > CURLM_STATE_DO) {
-          connclose(data->easy_conn, "Disconnected with pending data");
-          disconnect_conn = TRUE;
+          streamclose(data->easy_conn, "Disconnected with pending data");
+          stream_error = TRUE;
         }
         result = CURLE_OPERATION_TIMEDOUT;
         (void)multi_done(&data->easy_conn, result, TRUE);
@@ -1426,7 +1443,7 @@
         /* Add this handle to the send or pend pipeline */
         result = Curl_add_handle_to_pipeline(data, data->easy_conn);
         if(result)
-          disconnect_conn = TRUE;
+          stream_error = TRUE;
         else {
           if(async)
             /* We're now waiting for an asynchronous name lookup */
@@ -1518,7 +1535,7 @@
 
       if(result) {
         /* failure detected */
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
         break;
       }
     }
@@ -1537,7 +1554,9 @@
         multistate(data, CURLM_STATE_CONNECT);
       }
       else if(!result) {
-        if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE) {
+        if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
+           data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
+           (data->easy_conn->tunnel_state[FIRSTSOCKET] != TUNNEL_CONNECT)) {
           rc = CURLM_CALL_MULTI_PERFORM;
           /* initiate protocol connect phase */
           multistate(data, CURLM_STATE_SENDPROTOCONNECT);
@@ -1550,6 +1569,14 @@
       /* awaiting a completion of an asynch TCP connect */
       result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
       if(connected && !result) {
+#ifndef CURL_DISABLE_HTTP
+        if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
+            !data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
+            (data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)) {
+          multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+          break;
+        }
+#endif
         rc = CURLM_CALL_MULTI_PERFORM;
         multistate(data, data->easy_conn->bits.tunnel_proxy?
                    CURLM_STATE_WAITPROXYCONNECT:
@@ -1558,7 +1585,7 @@
       else if(result) {
         /* failure detected */
         /* Just break, the cleaning up is handled all in one place */
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
         break;
       }
       break;
@@ -1578,7 +1605,7 @@
         /* failure detected */
         Curl_posttransfer(data);
         multi_done(&data->easy_conn, result, TRUE);
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
       }
       break;
 
@@ -1595,7 +1622,7 @@
         /* failure detected */
         Curl_posttransfer(data);
         multi_done(&data->easy_conn, result, TRUE);
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
       }
       break;
 
@@ -1670,7 +1697,7 @@
           if(drc) {
             /* a failure here pretty much implies an out of memory */
             result = drc;
-            disconnect_conn = TRUE;
+            stream_error = TRUE;
           }
           else
             retry = (newurl)?TRUE:FALSE;
@@ -1703,7 +1730,7 @@
           }
           else {
             /* Have error handler disconnect conn if we can't retry */
-            disconnect_conn = TRUE;
+            stream_error = TRUE;
             free(newurl);
           }
         }
@@ -1712,7 +1739,7 @@
           Curl_posttransfer(data);
           if(data->easy_conn)
             multi_done(&data->easy_conn, result, FALSE);
-          disconnect_conn = TRUE;
+          stream_error = TRUE;
         }
       }
       break;
@@ -1734,7 +1761,7 @@
         /* failure detected */
         Curl_posttransfer(data);
         multi_done(&data->easy_conn, result, FALSE);
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
       }
       break;
 
@@ -1763,7 +1790,7 @@
         /* failure detected */
         Curl_posttransfer(data);
         multi_done(&data->easy_conn, result, FALSE);
-        disconnect_conn = TRUE;
+        stream_error = TRUE;
       }
       break;
 
@@ -1800,9 +1827,17 @@
         result = Curl_speedcheck(data, now);
 
       if(( (data->set.max_send_speed == 0) ||
-           (data->progress.ulspeed < data->set.max_send_speed))  &&
+           (Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                   data->progress.ul_limit_size,
+                                   data->set.max_send_speed,
+                                   data->progress.ul_limit_start,
+                                   now) <= 0))  &&
          ( (data->set.max_recv_speed == 0) ||
-           (data->progress.dlspeed < data->set.max_recv_speed)))
+           (Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                   data->progress.dl_limit_size,
+                                   data->set.max_recv_speed,
+                                   data->progress.dl_limit_start,
+                                   now) <= 0)))
         multistate(data, CURLM_STATE_PERFORM);
       break;
 
@@ -1810,41 +1845,38 @@
     {
       char *newurl = NULL;
       bool retry = FALSE;
+      bool comeback = FALSE;
 
       /* check if over send speed */
-      if((data->set.max_send_speed > 0) &&
-         (data->progress.ulspeed > data->set.max_send_speed)) {
-        int buffersize;
-
-        multistate(data, CURLM_STATE_TOOFAST);
-
-        /* calculate upload rate-limitation timeout. */
-        buffersize = (int)(data->set.buffer_size ?
-                           data->set.buffer_size : BUFSIZE);
-        timeout_ms = Curl_sleep_time(data->set.max_send_speed,
-                                     data->progress.ulspeed, buffersize);
-        Curl_expire_latest(data, timeout_ms);
-        break;
+      if(data->set.max_send_speed > 0) {
+        timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                            data->progress.ul_limit_size,
+                                            data->set.max_send_speed,
+                                            data->progress.ul_limit_start,
+                                            now);
+        if(timeout_ms > 0) {
+          multistate(data, CURLM_STATE_TOOFAST);
+          Curl_expire_latest(data, timeout_ms);
+          break;
+        }
       }
 
       /* check if over recv speed */
-      if((data->set.max_recv_speed > 0) &&
-         (data->progress.dlspeed > data->set.max_recv_speed)) {
-        int buffersize;
-
-        multistate(data, CURLM_STATE_TOOFAST);
-
-        /* Calculate download rate-limitation timeout. */
-        buffersize = (int)(data->set.buffer_size ?
-                           data->set.buffer_size : BUFSIZE);
-        timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
-                                     data->progress.dlspeed, buffersize);
-        Curl_expire_latest(data, timeout_ms);
-        break;
+      if(data->set.max_recv_speed > 0) {
+        timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                            data->progress.dl_limit_size,
+                                            data->set.max_recv_speed,
+                                            data->progress.dl_limit_start,
+                                            now);
+        if(timeout_ms > 0) {
+          multistate(data, CURLM_STATE_TOOFAST);
+          Curl_expire_latest(data, timeout_ms);
+          break;
+        }
       }
 
       /* read/write data if it is ready to do so */
-      result = Curl_readwrite(data->easy_conn, data, &done);
+      result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
 
       k = &data->req;
 
@@ -1884,10 +1916,10 @@
 
         if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
            result != CURLE_HTTP2_STREAM)
-          connclose(data->easy_conn, "Transfer returned error");
+          streamclose(data->easy_conn, "Transfer returned error");
 
         Curl_posttransfer(data);
-        multi_done(&data->easy_conn, result, FALSE);
+        multi_done(&data->easy_conn, result, TRUE);
       }
       else if(done) {
         followtype follow=FOLLOW_NONE;
@@ -1900,7 +1932,7 @@
 
         /* expire the new receiving pipeline head */
         if(data->easy_conn->recv_pipe->head)
-          Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
+          Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
 
         /* Check if we can move pending requests to send pipe */
         Curl_multi_process_pending_handles(multi);
@@ -1943,13 +1975,15 @@
             if(!result)
               newurl = NULL; /* allocation was handed over Curl_follow() */
             else
-              disconnect_conn = TRUE;
+              stream_error = TRUE;
           }
 
           multistate(data, CURLM_STATE_DONE);
           rc = CURLM_CALL_MULTI_PERFORM;
         }
       }
+      else if(comeback)
+        rc = CURLM_CALL_MULTI_PERFORM;
 
       free(newurl);
       break;
@@ -2008,7 +2042,7 @@
          that could be freed anytime */
       data->easy_conn = NULL;
 
-      Curl_expire(data, 0); /* stop all timers */
+      Curl_expire_clear(data); /* stop all timers */
       break;
 
     case CURLM_STATE_MSGSENT:
@@ -2042,7 +2076,7 @@
           Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
           Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
 
-          if(disconnect_conn) {
+          if(stream_error) {
             /* Don't attempt to send data over a connection that timed out */
             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
             /* disconnect properly */
@@ -2066,7 +2100,7 @@
         /* aborted due to progress callback return code must close the
            connection */
         result = CURLE_ABORTED_BY_CALLBACK;
-        connclose(data->easy_conn, "Aborted by callback");
+        streamclose(data->easy_conn, "Aborted by callback");
 
         /* if not yet in DONE state, go there, otherwise COMPLETED */
         multistate(data, (data->mstate < CURLM_STATE_DONE)?
@@ -2160,6 +2194,7 @@
     conn->data->easy_conn = NULL; /* clear the easy handle's connection
                                      pointer */
     /* This will remove the connection from the cache */
+    connclose(conn, "kill all");
     (void)Curl_disconnect(conn, FALSE);
     sigpipe_restore(&pipe_st);
 
@@ -2467,7 +2502,7 @@
      timeout in *tv */
   for(e = list->head; e;) {
     struct curl_llist_element *n = e->next;
-    long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
+    time_t diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
     if(diff <= 0)
       /* remove outdated entry */
       Curl_llist_remove(list, e, NULL);
@@ -2745,7 +2780,7 @@
 
     if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
       /* some time left before expiration */
-      *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
+      *timeout_ms = (long)curlx_tvdiff(multi->timetree->key, now);
       if(!*timeout_ms)
         /*
          * Since we only provide millisecond resolution on the returned value
@@ -2852,7 +2887,7 @@
     /* find the correct spot in the list */
     for(e = timeoutlist->head; e; e = e->next) {
       struct timeval *checktime = e->ptr;
-      long diff = curlx_tvdiff(*checktime, *timedup);
+      time_t diff = curlx_tvdiff(*checktime, *timedup);
       if(diff > 0)
         break;
       prev = e;
@@ -2876,92 +2911,59 @@
  * given a number of milliseconds from now to use to set the 'act before
  * this'-time for the transfer, to be extracted by curl_multi_timeout()
  *
- * Note that the timeout will be added to a queue of timeouts if it defines a
- * moment in time that is later than the current head of queue.
- *
- * Pass zero to clear all timeout values for this handle.
-*/
-void Curl_expire(struct Curl_easy *data, long milli)
+ * The timeout will be added to a queue of timeouts if it defines a moment in
+ * time that is later than the current head of queue.
+ */
+void Curl_expire(struct Curl_easy *data, time_t milli)
 {
   struct Curl_multi *multi = data->multi;
   struct timeval *nowp = &data->state.expiretime;
   int rc;
+  struct timeval set;
 
   /* this is only interesting while there is still an associated multi struct
      remaining! */
   if(!multi)
     return;
 
-  if(!milli) {
-    /* No timeout, clear the time data. */
-    if(nowp->tv_sec || nowp->tv_usec) {
-      /* Since this is an cleared time, we must remove the previous entry from
-         the splay tree */
-      struct curl_llist *list = data->state.timeoutlist;
+  set = Curl_tvnow();
+  set.tv_sec += (long)(milli/1000);
+  set.tv_usec += (milli%1000)*1000;
 
-      rc = Curl_splayremovebyaddr(multi->timetree,
-                                  &data->state.timenode,
-                                  &multi->timetree);
-      if(rc)
-        infof(data, "Internal error clearing splay node = %d\n", rc);
-
-      /* flush the timeout list too */
-      while(list->size > 0)
-        Curl_llist_remove(list, list->tail, NULL);
-
-#ifdef DEBUGBUILD
-      infof(data, "Expire cleared\n");
-#endif
-      nowp->tv_sec = 0;
-      nowp->tv_usec = 0;
-    }
+  if(set.tv_usec >= 1000000) {
+    set.tv_sec++;
+    set.tv_usec -= 1000000;
   }
-  else {
-    struct timeval set;
 
-    set = Curl_tvnow();
-    set.tv_sec += milli/1000;
-    set.tv_usec += (milli%1000)*1000;
-
-    if(set.tv_usec >= 1000000) {
-      set.tv_sec++;
-      set.tv_usec -= 1000000;
+  if(nowp->tv_sec || nowp->tv_usec) {
+    /* This means that the struct is added as a node in the splay tree.
+       Compare if the new time is earlier, and only remove-old/add-new if it
+       is. */
+    time_t diff = curlx_tvdiff(set, *nowp);
+    if(diff > 0) {
+      /* the new expire time was later so just add it to the queue
+         and get out */
+      multi_addtimeout(data->state.timeoutlist, &set);
+      return;
     }
 
-    if(nowp->tv_sec || nowp->tv_usec) {
-      /* This means that the struct is added as a node in the splay tree.
-         Compare if the new time is earlier, and only remove-old/add-new if it
-         is. */
-      long diff = curlx_tvdiff(set, *nowp);
-      if(diff > 0) {
-        /* the new expire time was later so just add it to the queue
-           and get out */
-        multi_addtimeout(data->state.timeoutlist, &set);
-        return;
-      }
+    /* the new time is newer than the presently set one, so add the current
+       to the queue and update the head */
+    multi_addtimeout(data->state.timeoutlist, nowp);
 
-      /* the new time is newer than the presently set one, so add the current
-         to the queue and update the head */
-      multi_addtimeout(data->state.timeoutlist, nowp);
-
-      /* Since this is an updated time, we must remove the previous entry from
-         the splay tree first and then re-add the new value */
-      rc = Curl_splayremovebyaddr(multi->timetree,
-                                  &data->state.timenode,
-                                  &multi->timetree);
-      if(rc)
-        infof(data, "Internal error removing splay node = %d\n", rc);
-    }
-
-    *nowp = set;
-    data->state.timenode.payload = data;
-    multi->timetree = Curl_splayinsert(*nowp,
-                                       multi->timetree,
-                                       &data->state.timenode);
+    /* Since this is an updated time, we must remove the previous entry from
+       the splay tree first and then re-add the new value */
+    rc = Curl_splayremovebyaddr(multi->timetree,
+                                &data->state.timenode,
+                                &multi->timetree);
+    if(rc)
+      infof(data, "Internal error removing splay node = %d\n", rc);
   }
-#if 0
-  Curl_splayprint(multi->timetree, 0, TRUE);
-#endif
+
+  *nowp = set;
+  data->state.timenode.payload = data;
+  multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
+                                     &data->state.timenode);
 }
 
 /*
@@ -2975,14 +2977,14 @@
  * time-out period to expire.
  *
  */
-void Curl_expire_latest(struct Curl_easy *data, long milli)
+void Curl_expire_latest(struct Curl_easy *data, time_t milli)
 {
   struct timeval *expire = &data->state.expiretime;
 
   struct timeval set;
 
   set = Curl_tvnow();
-  set.tv_sec += milli / 1000;
+  set.tv_sec += (long)(milli / 1000);
   set.tv_usec += (milli % 1000) * 1000;
 
   if(set.tv_usec >= 1000000) {
@@ -2994,7 +2996,7 @@
     /* This means that the struct is added as a node in the splay tree.
        Compare if the new time is earlier, and only remove-old/add-new if it
          is. */
-    long diff = curlx_tvdiff(set, *expire);
+    time_t diff = curlx_tvdiff(set, *expire);
     if(diff > 0)
       /* the new expire time was later than the top time, so just skip this */
       return;
@@ -3004,6 +3006,49 @@
   Curl_expire(data, milli);
 }
 
+
+/*
+ * Curl_expire_clear()
+ *
+ * Clear ALL timeout values for this handle.
+ */
+void Curl_expire_clear(struct Curl_easy *data)
+{
+  struct Curl_multi *multi = data->multi;
+  struct timeval *nowp = &data->state.expiretime;
+  int rc;
+
+  /* this is only interesting while there is still an associated multi struct
+     remaining! */
+  if(!multi)
+    return;
+
+  if(nowp->tv_sec || nowp->tv_usec) {
+    /* Since this is an cleared time, we must remove the previous entry from
+       the splay tree */
+    struct curl_llist *list = data->state.timeoutlist;
+
+    rc = Curl_splayremovebyaddr(multi->timetree,
+                                &data->state.timenode,
+                                &multi->timetree);
+    if(rc)
+      infof(data, "Internal error clearing splay node = %d\n", rc);
+
+    /* flush the timeout list too */
+    while(list->size > 0)
+      Curl_llist_remove(list, list->tail, NULL);
+
+#ifdef DEBUGBUILD
+    infof(data, "Expire cleared\n");
+#endif
+    nowp->tv_sec = 0;
+    nowp->tv_usec = 0;
+  }
+}
+
+
+
+
 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
                             void *hashp)
 {
@@ -3064,7 +3109,7 @@
       Curl_llist_remove(multi->pending, e, NULL);
 
       /* Make sure that the handle will be processed soonish. */
-      Curl_expire_latest(data, 1);
+      Curl_expire_latest(data, 0);
     }
 
     e = next; /* operate on next handle */
diff --git a/lib/multihandle.h b/lib/multihandle.h
index c56b6ae..0b78de9 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -38,7 +38,9 @@
   CURLM_STATE_CONNECT,      /* 2 - resolve/connect has been sent off */
   CURLM_STATE_WAITRESOLVE,  /* 3 - awaiting the resolve to finalize */
   CURLM_STATE_WAITCONNECT,  /* 4 - awaiting the TCP connect to finalize */
-  CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */
+  CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization
+                                   to complete and/or proxy CONNECT to
+                                   finalize */
   CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
   CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
                                    phase */
diff --git a/lib/multiif.h b/lib/multiif.h
index fd2df55..e5de1fc 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -25,8 +25,9 @@
 /*
  * Prototypes for library-wide functions provided by multi.c
  */
-void Curl_expire(struct Curl_easy *data, long milli);
-void Curl_expire_latest(struct Curl_easy *data, long milli);
+void Curl_expire(struct Curl_easy *data, time_t milli);
+void Curl_expire_clear(struct Curl_easy *data);
+void Curl_expire_latest(struct Curl_easy *data, time_t milli);
 bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
 void Curl_multi_handlePipeBreak(struct Curl_easy *data);
 
diff --git a/lib/netrc.c b/lib/netrc.c
index 46f427a..996711d 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -28,10 +28,8 @@
 
 #include <curl/curl.h>
 #include "netrc.h"
-
-#include "strequal.h"
 #include "strtok.h"
-#include "rawstr.h"
+#include "strcase.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -130,20 +128,20 @@
 
         switch(state) {
         case NOTHING:
-          if(Curl_raw_equal("machine", tok)) {
+          if(strcasecompare("machine", tok)) {
             /* the next tok is the machine name, this is in itself the
                delimiter that starts the stuff entered for this machine,
                after this we need to search for 'login' and
                'password'. */
             state=HOSTFOUND;
           }
-          else if(Curl_raw_equal("default", tok)) {
+          else if(strcasecompare("default", tok)) {
             state=HOSTVALID;
             retcode=0; /* we did find our host */
           }
           break;
         case HOSTFOUND:
-          if(Curl_raw_equal(host, tok)) {
+          if(strcasecompare(host, tok)) {
             /* and yes, this is our host! */
             state=HOSTVALID;
             retcode=0; /* we did find our host */
@@ -156,7 +154,7 @@
           /* we are now parsing sub-keywords concerning "our" host */
           if(state_login) {
             if(specific_login) {
-              state_our_login = Curl_raw_equal(*loginp, tok);
+              state_our_login = strcasecompare(*loginp, tok);
             }
             else {
               free(*loginp);
@@ -179,11 +177,11 @@
             }
             state_password=0;
           }
-          else if(Curl_raw_equal("login", tok))
+          else if(strcasecompare("login", tok))
             state_login=1;
-          else if(Curl_raw_equal("password", tok))
+          else if(strcasecompare("password", tok))
             state_password=1;
-          else if(Curl_raw_equal("machine", tok)) {
+          else if(strcasecompare("machine", tok)) {
             /* ok, there's machine here go => */
             state = HOSTFOUND;
             state_our_login = FALSE;
diff --git a/lib/non-ascii.c b/lib/non-ascii.c
index ed14618..2f5de4c 100644
--- a/lib/non-ascii.c
+++ b/lib/non-ascii.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -117,7 +117,7 @@
     /* call iconv */
     input_ptr = output_ptr = buffer;
     in_bytes = out_bytes = length;
-    rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
+    rc = iconv(data->outbound_cd, (const char **)&input_ptr, &in_bytes,
                &output_ptr, &out_bytes);
     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
       error = ERRNO;
diff --git a/lib/parsedate.c b/lib/parsedate.c
index 7aad5c2..943f547 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +80,7 @@
 #endif
 
 #include <curl/curl.h>
-#include "rawstr.h"
+#include "strcase.h"
 #include "warnless.h"
 #include "parsedate.h"
 
@@ -211,7 +211,7 @@
   else
     what = &Curl_wkday[0];
   for(i=0; i<7; i++) {
-    if(Curl_raw_equal(check, what[0])) {
+    if(strcasecompare(check, what[0])) {
       found=TRUE;
       break;
     }
@@ -228,7 +228,7 @@
 
   what = &Curl_month[0];
   for(i=0; i<12; i++) {
-    if(Curl_raw_equal(check, what[0])) {
+    if(strcasecompare(check, what[0])) {
       found=TRUE;
       break;
     }
@@ -248,7 +248,7 @@
 
   what = tz;
   for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
-    if(Curl_raw_equal(check, what->name)) {
+    if(strcasecompare(check, what->name)) {
       found=TRUE;
       break;
     }
@@ -386,15 +386,17 @@
       /* a digit */
       int val;
       char *end;
+      int len=0;
       if((secnum == -1) &&
-         (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
+         (3 == sscanf(date, "%02d:%02d:%02d%n",
+                      &hournum, &minnum, &secnum, &len))) {
         /* time stamp! */
-        date += 8;
+        date += len;
       }
       else if((secnum == -1) &&
-              (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
+              (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
         /* time stamp without seconds */
-        date += 5;
+        date += len;
         secnum = 0;
       }
       else {
diff --git a/lib/pingpong.c b/lib/pingpong.c
index 92ff84b..7a99357 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -44,12 +44,12 @@
 
 /* Returns timeout in ms. 0 or negative number means the timeout has already
    triggered */
-long Curl_pp_state_timeout(struct pingpong *pp)
+time_t Curl_pp_state_timeout(struct pingpong *pp)
 {
   struct connectdata *conn = pp->conn;
   struct Curl_easy *data=conn->data;
-  long timeout_ms; /* in milliseconds */
-  long timeout2_ms; /* in milliseconds */
+  time_t timeout_ms; /* in milliseconds */
+  time_t timeout2_ms; /* in milliseconds */
   long response_time= (data->set.server_response_timeout)?
     data->set.server_response_timeout: pp->response_time;
 
@@ -83,8 +83,8 @@
   struct connectdata *conn = pp->conn;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   int rc;
-  long interval_ms;
-  long timeout_ms = Curl_pp_state_timeout(pp);
+  time_t interval_ms;
+  time_t timeout_ms = Curl_pp_state_timeout(pp);
   struct Curl_easy *data=conn->data;
   CURLcode result = CURLE_OK;
 
@@ -101,14 +101,17 @@
   else
     interval_ms = 0; /* immediate */
 
-  if(Curl_pp_moredata(pp))
+  if(Curl_ssl_data_pending(conn, FIRSTSOCKET))
+    rc = 1;
+  else if(Curl_pp_moredata(pp))
     /* We are receiving and there is data in the cache so just read it */
     rc = 1;
   else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
     /* We are receiving and there is data ready in the SSL library */
     rc = 1;
   else
-    rc = Curl_socket_ready(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
+    rc = Curl_socket_check(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
+                           CURL_SOCKET_BAD,
                            pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
                            interval_ms);
 
diff --git a/lib/pingpong.h b/lib/pingpong.h
index 2f649d5..500100a 100644
--- a/lib/pingpong.h
+++ b/lib/pingpong.h
@@ -88,7 +88,7 @@
 
 /* Returns timeout in ms. 0 or negative number means the timeout has already
    triggered */
-long Curl_pp_state_timeout(struct pingpong *pp);
+time_t Curl_pp_state_timeout(struct pingpong *pp);
 
 
 /***********************************************************************
diff --git a/lib/pipeline.c b/lib/pipeline.c
index 0ff82f0..40a5e82 100644
--- a/lib/pipeline.c
+++ b/lib/pipeline.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013-2016, 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 @@
 #include "multiif.h"
 #include "pipeline.h"
 #include "sendf.h"
-#include "rawstr.h"
+#include "strcase.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -114,7 +114,7 @@
   if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
     /* this is a new one as head, expire it */
     Curl_pipeline_leave_write(conn); /* not in use yet */
-    Curl_expire(conn->send_pipe->head->ptr, 1);
+    Curl_expire(conn->send_pipe->head->ptr, 0);
   }
 
 #if 0 /* enable for pipeline debugging */
@@ -149,7 +149,7 @@
         infof(conn->data, "%p is at send pipe head B!\n",
               (void *)conn->send_pipe->head->ptr);
 #endif
-        Curl_expire(conn->send_pipe->head->ptr, 1);
+        Curl_expire(conn->send_pipe->head->ptr, 0);
       }
 
       /* The receiver's list is not really interesting here since either this
@@ -177,7 +177,7 @@
         struct site_blacklist_entry *site;
 
         site = curr->ptr;
-        if(Curl_raw_equal(site->hostname, conn->host.name) &&
+        if(strcasecompare(site->hostname, conn->host.name) &&
            site->port == conn->remote_port) {
           infof(handle, "Site %s:%d is pipeline blacklisted\n",
                 conn->host.name, conn->remote_port);
@@ -269,7 +269,7 @@
         char *bl_server_name;
 
         bl_server_name = curr->ptr;
-        if(Curl_raw_nequal(bl_server_name, server_name,
+        if(strncasecompare(bl_server_name, server_name,
                            strlen(bl_server_name))) {
           infof(handle, "Server %s is blacklisted\n", server_name);
           return TRUE;
diff --git a/lib/pop3.c b/lib/pop3.c
index 591e877..9bb691c 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -70,16 +70,14 @@
 #include "http.h" /* for HTTP proxy tunnel stuff */
 #include "socks.h"
 #include "pop3.h"
-
 #include "strtoofft.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "vtls/vtls.h"
 #include "connect.h"
 #include "strerror.h"
 #include "select.h"
 #include "multiif.h"
 #include "url.h"
-#include "rawstr.h"
 #include "curl_sasl.h"
 #include "curl_md5.h"
 #include "warnless.h"
@@ -106,7 +104,7 @@
 static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
                                   const char *initresp);
 static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
-static void pop3_get_message(char *buffer, char** outptr);
+static void pop3_get_message(char *buffer, char **outptr);
 
 /*
  * POP3 protocol handler.
@@ -292,10 +290,10 @@
  *
  * Gets the authentication message from the response buffer.
  */
-static void pop3_get_message(char *buffer, char** outptr)
+static void pop3_get_message(char *buffer, char **outptr)
 {
   size_t len = 0;
-  char* message = NULL;
+  char *message = NULL;
 
   /* Find the start of the message */
   for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
@@ -663,7 +661,7 @@
 
   if(pop3code != '+') {
     failf(data, "Got unexpected pop3-server response");
-    result = CURLE_FTP_WEIRD_SERVER_REPLY;
+    result = CURLE_WEIRD_SERVER_REPLY;
   }
   else {
     /* Does the server support APOP authentication? */
@@ -1412,11 +1410,11 @@
     while(*ptr && *ptr != ';')
       ptr++;
 
-    if(strnequal(key, "AUTH=", 5)) {
+    if(strncasecompare(key, "AUTH=", 5)) {
       result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
                                                value, ptr - value);
 
-      if(result && strnequal(value, "+APOP", ptr - value)) {
+      if(result && strncasecompare(value, "+APOP", ptr - value)) {
         pop3c->preftype = POP3_TYPE_APOP;
         pop3c->sasl.prefmech = SASL_AUTH_NONE;
         result = CURLE_OK;
@@ -1574,7 +1572,7 @@
       if(prev) {
         /* If the partial match was the CRLF and dot then only write the CRLF
            as the server would have inserted the dot */
-        result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB,
+        result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB,
                                    strip_dot ? prev - 1 : prev);
 
         if(result)
diff --git a/lib/progress.c b/lib/progress.c
index 760ca1c..60627b2 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -216,18 +216,95 @@
 {
   data->progress.speeder_c = 0; /* reset the progress meter display */
   data->progress.start = Curl_tvnow();
+  data->progress.ul_limit_start.tv_sec = 0;
+  data->progress.ul_limit_start.tv_usec = 0;
+  data->progress.dl_limit_start.tv_sec = 0;
+  data->progress.dl_limit_start.tv_usec = 0;
   /* clear all bits except HIDE and HEADERS_OUT */
   data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
 }
 
+/*
+ * This is used to handle speed limits, calculating how much milliseconds we
+ * need to wait until we're back under the speed limit, if needed.
+ *
+ * The way it works is by having a "starting point" (time & amount of data
+ * transfered by then) used in the speed computation, to be used instead of the
+ * start of the transfer.
+ * This starting point is regularly moved as transfer goes on, to keep getting
+ * accurate values (instead of average over the entire tranfer).
+ *
+ * This function takes the current amount of data transfered, the amount at the
+ * starting point, the limit (in bytes/s), the time of the starting point and
+ * the current time.
+ *
+ * Returns -1 if no waiting is needed (not enough data transfered since
+ * starting point yet), 0 when no waiting is needed but the starting point
+ * should be reset (to current), or the number of milliseconds to wait to get
+ * back under the speed limit.
+ */
+long Curl_pgrsLimitWaitTime(curl_off_t cursize,
+                            curl_off_t startsize,
+                            curl_off_t limit,
+                            struct timeval start,
+                            struct timeval now)
+{
+  curl_off_t size = cursize - startsize;
+  time_t minimum;
+  time_t actual;
+
+  /* we don't have a starting point yet -- return 0 so it gets (re)set */
+  if(start.tv_sec == 0 && start.tv_usec == 0)
+    return 0;
+
+  /* not enough data yet */
+  if(size < limit)
+    return -1;
+
+  minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
+  actual = Curl_tvdiff(now, start);
+
+  if(actual < minimum)
+    /* this is a conversion on some systems (64bit time_t => 32bit long) */
+    return (long)(minimum - actual);
+  else
+    return 0;
+}
+
 void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
 {
+  struct timeval now = Curl_tvnow();
+
   data->progress.downloaded = size;
+
+  /* download speed limit */
+  if((data->set.max_recv_speed > 0) &&
+     (Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                             data->progress.dl_limit_size,
+                             data->set.max_recv_speed,
+                             data->progress.dl_limit_start,
+                             now) == 0)) {
+    data->progress.dl_limit_start = now;
+    data->progress.dl_limit_size = size;
+  }
 }
 
 void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
 {
+  struct timeval now = Curl_tvnow();
+
   data->progress.uploaded = size;
+
+  /* upload speed limit */
+  if((data->set.max_send_speed > 0) &&
+     (Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                             data->progress.ul_limit_size,
+                             data->set.max_send_speed,
+                             data->progress.ul_limit_start,
+                             now) == 0)) {
+    data->progress.ul_limit_start = now;
+    data->progress.ul_limit_size = size;
+  }
 }
 
 void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
@@ -284,9 +361,7 @@
   now = Curl_tvnow(); /* what time is it */
 
   /* The time spent so far (from the start) */
-  data->progress.timespent =
-    (double)(now.tv_sec - data->progress.start.tv_sec) +
-    (double)(now.tv_usec - data->progress.start.tv_usec)/1000000.0;
+  data->progress.timespent = curlx_tvdiff_secs(now, data->progress.start);
   timespent = (curl_off_t)data->progress.timespent;
 
   /* The average download speed this far */
@@ -300,7 +375,7 @@
      (data->progress.timespent>0?data->progress.timespent:1));
 
   /* Calculations done at most once a second, unless end is reached */
-  if(data->progress.lastshow != (long)now.tv_sec) {
+  if(data->progress.lastshow != now.tv_sec) {
     shownow = TRUE;
 
     data->progress.lastshow = now.tv_sec;
@@ -327,7 +402,7 @@
 
     /* first of all, we don't do this if there's no counted seconds yet */
     if(countindex) {
-      long span_ms;
+      time_t span_ms;
 
       /* Get the index position to compare with the 'nowindex' position.
          Get the oldest entry possible. While we have less than CURR_TIME
diff --git a/lib/progress.h b/lib/progress.h
index a77b7ce..155ff04 100644
--- a/lib/progress.h
+++ b/lib/progress.h
@@ -49,7 +49,11 @@
 int Curl_pgrsUpdate(struct connectdata *);
 void Curl_pgrsResetTimesSizes(struct Curl_easy *data);
 void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
-
+long Curl_pgrsLimitWaitTime(curl_off_t cursize,
+                            curl_off_t startsize,
+                            curl_off_t limit,
+                            struct timeval start,
+                            struct timeval now);
 
 /* Don't show progress for sizes smaller than: */
 #define LEAST_SIZE_PROGRESS BUFSIZE
diff --git a/lib/rand.c b/lib/rand.c
new file mode 100644
index 0000000..0e716a7
--- /dev/null
+++ b/lib/rand.c
@@ -0,0 +1,130 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, 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"
+
+#include <fcntl.h>
+
+#include <curl/curl.h>
+#include "vtls/vtls.h"
+#include "sendf.h"
+#include "rand.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
+{
+  unsigned int r;
+  CURLcode result = CURLE_OK;
+  static unsigned int randseed;
+  static bool seeded = FALSE;
+
+#ifdef CURLDEBUG
+  char *force_entropy = getenv("CURL_ENTROPY");
+  if(force_entropy) {
+    if(!seeded) {
+      size_t elen = strlen(force_entropy);
+      size_t clen = sizeof(randseed);
+      size_t min = elen < clen ? elen : clen;
+      memcpy((char *)&randseed, force_entropy, min);
+      seeded = TRUE;
+    }
+    else
+      randseed++;
+    *rnd = randseed;
+    return CURLE_OK;
+  }
+#endif
+
+  /* data may be NULL! */
+  result = Curl_ssl_random(data, (unsigned char *)&rnd, sizeof(rnd));
+  if(result != CURLE_NOT_BUILT_IN)
+    /* only if there is no random funtion in the TLS backend do the non crypto
+       version, otherwise return result */
+    return result;
+
+  /* ---- non-cryptographic version following ---- */
+
+#ifdef RANDOM_FILE
+  if(!seeded) {
+    /* if there's a random file to read a seed from, use it */
+    int fd = open(RANDOM_FILE, O_RDONLY);
+    if(fd > -1) {
+      /* read random data into the randseed variable */
+      ssize_t nread = read(fd, &randseed, sizeof(randseed));
+      if(nread == sizeof(randseed))
+        seeded = TRUE;
+      close(fd);
+    }
+  }
+#endif
+
+  if(!seeded) {
+    struct timeval now = curlx_tvnow();
+    infof(data, "WARNING: Using weak random seed\n");
+    randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    seeded = TRUE;
+  }
+
+  /* Return an unsigned 32-bit pseudo-random number. */
+  r = randseed = randseed * 1103515245 + 12345;
+  *rnd = (r << 16) | ((r >> 16) & 0xFFFF);
+  return CURLE_OK;
+}
+
+/*
+ * Curl_rand() stores 'num' number of random unsigned integers in the buffer
+ * 'rndptr' points to.
+ *
+ * If libcurl is built without TLS support or with a TLS backend that lacks a
+ * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
+ * "weak" random.
+ *
+ * When built *with* TLS support and a backend that offers strong random, it
+ * will return error if it cannot provide strong random values.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+
+CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rndptr,
+                   unsigned int num)
+{
+  CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
+  unsigned int i;
+
+  assert(num > 0);
+
+  for(i = 0; i < num; i++) {
+    result = randit(data, rndptr++);
+    if(result)
+      return result;
+  }
+  return result;
+}
diff --git a/lib/rand.h b/lib/rand.h
new file mode 100644
index 0000000..0f89861
--- /dev/null
+++ b/lib/rand.h
@@ -0,0 +1,43 @@
+#ifndef HEADER_CURL_RAND_H
+#define HEADER_CURL_RAND_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, 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.
+ *
+ ***************************************************************************/
+
+/*
+ * Curl_rand() stores 'num' number of random unsigned integers in the buffer
+ * 'rnd' points to.
+ *
+ * If libcurl is built without TLS support or with a TLS backend that lacks a
+ * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
+ * "weak" random.
+ *
+ * When built *with* TLS support and a backend that offers strong random, it
+ * will return error if it cannot provide strong random values.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rnd,
+                   unsigned int num);
+
+#endif /* HEADER_CURL_RAND_H */
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 27955bc..5da33d4 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -33,9 +33,10 @@
 #include "url.h"
 #include "progress.h"
 #include "rtsp.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "select.h"
 #include "connect.h"
+#include "strdup.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -147,7 +148,7 @@
   int sval;
   bool ret_val = TRUE;
 
-  sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0);
+  sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0);
   if(sval == 0) {
     /* timeout */
     ret_val = FALSE;
@@ -614,9 +615,9 @@
 
   if(rtspc->rtp_buf) {
     /* There was some leftover data the last time. Merge buffers */
-    char *newptr = realloc(rtspc->rtp_buf, rtspc->rtp_bufsize + *nread);
+    char *newptr = Curl_saferealloc(rtspc->rtp_buf,
+                                    rtspc->rtp_bufsize + *nread);
     if(!newptr) {
-      Curl_safefree(rtspc->rtp_buf);
       rtspc->rtp_buf = NULL;
       rtspc->rtp_bufsize = 0;
       return CURLE_OUT_OF_MEMORY;
@@ -796,19 +797,15 @@
       }
     }
     else {
-      /* If the Session ID is not set, and we find it in a response, then
-         set it */
-
-      /* The session ID can be an alphanumeric or a 'safe' character
+      /* If the Session ID is not set, and we find it in a response, then set
+       * it.
        *
-       * RFC 2326 15.1 Base Syntax:
-       * safe =  "\$" | "-" | "_" | "." | "+"
-       * */
+       * Allow any non whitespace content, up to the field seperator or end of
+       * line. RFC 2326 isn't 100% clear on the session ID and for example
+       * gstreamer does url-encoded session ID's not covered by the standard.
+       */
       char *end = start;
-      while(*end &&
-            (ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' ||
-             *end == '+' ||
-             (*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1))))
+      while(*end && *end != ';' && !ISSPACE(*end))
         end++;
 
       /* Copy the id substring into a new buffer */
diff --git a/lib/security.c b/lib/security.c
index a0bcaea..4a8f444 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -60,9 +60,9 @@
 #include "curl_sec.h"
 #include "ftp.h"
 #include "sendf.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "warnless.h"
-
+#include "strdup.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -88,7 +88,8 @@
 
 /* Convert a protocol |level| to its char representation.
    We take an int to catch programming mistakes. */
-static char level_to_char(int level) {
+static char level_to_char(int level)
+{
   switch(level) {
   case PROT_CLEAR:
     return 'C';
@@ -122,7 +123,7 @@
   vsnprintf(print_buffer, sizeof(print_buffer), message, args);
   va_end(args);
 
-  if(Curl_ftpsendf(conn, print_buffer)) {
+  if(Curl_ftpsend(conn, print_buffer)) {
     ftp_code = -1;
   }
   else {
@@ -192,15 +193,18 @@
                           struct krb5buffer *buf)
 {
   int len;
-  void* tmp;
+  void *tmp = NULL;
   CURLcode result;
 
   result = socket_read(fd, &len, sizeof(len));
   if(result)
     return result;
 
-  len = ntohl(len);
-  tmp = realloc(buf->data, len);
+  if(len) {
+    /* only realloc if there was a length */
+    len = ntohl(len);
+    tmp = Curl_saferealloc(buf->data, len);
+  }
   if(tmp == NULL)
     return CURLE_OUT_OF_MEMORY;
 
@@ -219,7 +223,7 @@
 {
   if(buf->size - buf->index < len)
     len = buf->size - buf->index;
-  memcpy(data, (char*)buf->data + buf->index, len);
+  memcpy(data, (char *)buf->data + buf->index, len);
   buf->index += len;
   return len;
 }
@@ -288,7 +292,7 @@
       prot_level = conn->command_prot;
   }
   bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
-                             (void**)&buffer);
+                             (void **)&buffer);
   if(!buffer || bytes <= 0)
     return; /* error */
 
@@ -408,7 +412,7 @@
 static int sec_set_protection_level(struct connectdata *conn)
 {
   int code;
-  char* pbsz;
+  char *pbsz;
   static unsigned int buffer_size = 1 << 20; /* 1048576 */
   enum protection_level level = conn->request_data_prot;
 
diff --git a/lib/select.c b/lib/select.c
index abf55d8..03af645 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -51,15 +51,14 @@
 #include "warnless.h"
 
 /* Convenience local macros */
-
-#define elapsed_ms  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
+#define ELAPSED_MS()  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
 
 int Curl_ack_eintr = 0;
-#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
+#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
 
 /*
  * Internal function used for waiting a specific amount of ms
- * in Curl_socket_ready() and Curl_poll() when no file descriptor
+ * in Curl_socket_check() and Curl_poll() when no file descriptor
  * is provided to wait on, just being used to delay execution.
  * WinSock select() and poll() timeout mechanisms need a valid
  * socket descriptor in a not null file descriptor set to work.
@@ -109,9 +108,9 @@
     if(r != -1)
       break;
     error = SOCKERRNO;
-    if(error && error_not_EINTR)
+    if(error && ERROR_NOT_EINTR(error))
       break;
-    pending_ms = timeout_ms - elapsed_ms;
+    pending_ms = timeout_ms - ELAPSED_MS();
     if(pending_ms <= 0) {
       r = 0;  /* Simulate a "call timed out" case */
       break;
@@ -146,7 +145,7 @@
 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
                       curl_socket_t readfd1,
                       curl_socket_t writefd, /* socket to write to */
-                      long timeout_ms)       /* milliseconds to wait */
+                      time_t timeout_ms)     /* milliseconds to wait */
 {
 #ifdef HAVE_POLL_FINE
   struct pollfd pfd[3];
@@ -165,6 +164,12 @@
   int r;
   int ret;
 
+#if SIZEOF_LONG != SIZEOF_INT
+  /* wrap-around precaution */
+  if(timeout_ms >= INT_MAX)
+    timeout_ms = INT_MAX;
+#endif
+
   if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
      (writefd == CURL_SOCKET_BAD)) {
     /* no sockets, just wait */
@@ -213,10 +218,10 @@
     if(r != -1)
       break;
     error = SOCKERRNO;
-    if(error && error_not_EINTR)
+    if(error && ERROR_NOT_EINTR(error))
       break;
     if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - elapsed_ms);
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
       if(pending_ms <= 0) {
         r = 0;  /* Simulate a "call timed out" case */
         break;
@@ -328,10 +333,10 @@
     if(r != -1)
       break;
     error = SOCKERRNO;
-    if(error && error_not_EINTR)
+    if(error && ERROR_NOT_EINTR(error))
       break;
     if(timeout_ms > 0) {
-      pending_ms = timeout_ms - elapsed_ms;
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
       if(pending_ms <= 0) {
         r = 0;  /* Simulate a "call timed out" case */
         break;
@@ -434,10 +439,10 @@
     if(r != -1)
       break;
     error = SOCKERRNO;
-    if(error && error_not_EINTR)
+    if(error && ERROR_NOT_EINTR(error))
       break;
     if(timeout_ms > 0) {
-      pending_ms = timeout_ms - elapsed_ms;
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
       if(pending_ms <= 0) {
         r = 0;  /* Simulate a "call timed out" case */
         break;
@@ -521,10 +526,10 @@
     if(r != -1)
       break;
     error = SOCKERRNO;
-    if(error && error_not_EINTR)
+    if(error && ERROR_NOT_EINTR(error))
       break;
     if(timeout_ms > 0) {
-      pending_ms = timeout_ms - elapsed_ms;
+      pending_ms = timeout_ms - ELAPSED_MS();
       if(pending_ms <= 0) {
         r = 0;  /* Simulate a "call timed out" case */
         break;
diff --git a/lib/select.h b/lib/select.h
index 695bb69..e247bd9 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,11 +73,12 @@
 
 int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
                       curl_socket_t writefd,
-                      long timeout_ms);
+                      time_t timeout_ms);
 
-/* provide the former API internally */
-#define Curl_socket_ready(x,y,z) \
-  Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
+#define SOCKET_READABLE(x,z) \
+  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
+#define SOCKET_WRITABLE(x,z) \
+  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
 
diff --git a/lib/sendf.c b/lib/sendf.c
index 2101797..4f552e8 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -488,7 +488,7 @@
  */
 CURLcode Curl_client_chop_write(struct connectdata *conn,
                                 int type,
-                                char * ptr,
+                                char *ptr,
                                 size_t len)
 {
   struct Curl_easy *data = conn->data;
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index e32b72f..a3c2a7b 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,18 +41,18 @@
 #include <qsoasync.h>
 #include <gssapi.h>
 
-extern int      Curl_getaddrinfo_a(const char * nodename,
-                                   const char * servname,
-                                   const struct addrinfo * hints,
-                                   struct addrinfo * * res);
+extern int Curl_getaddrinfo_a(const char *nodename,
+                              const char *servname,
+                              const struct addrinfo *hints,
+                              struct addrinfo **res);
 #define getaddrinfo             Curl_getaddrinfo_a
 
 
-extern int      Curl_getnameinfo_a(const struct sockaddr * sa,
-                                   curl_socklen_t salen,
-                                   char * nodename, curl_socklen_t nodenamelen,
-                                   char * servname, curl_socklen_t servnamelen,
-                                   int flags);
+extern int Curl_getnameinfo_a(const struct sockaddr *sa,
+                              curl_socklen_t salen,
+                              char *nodename, curl_socklen_t nodenamelen,
+                              char *servname, curl_socklen_t servnamelen,
+                              int flags);
 #define getnameinfo             Curl_getnameinfo_a
 
 
@@ -79,7 +79,7 @@
 
 extern int      Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
                                                 GSK_BUF_ID bufID,
-                                                const char * buffer,
+                                                const char *buffer,
                                                 int bufSize);
 #define gsk_attribute_set_buffer        Curl_gsk_attribute_set_buffer_a
 
@@ -95,29 +95,29 @@
 
 extern int      Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
                                                 GSK_CALLBACK_ID callBackID,
-                                                void * callBackAreaPtr);
+                                                void *callBackAreaPtr);
 #define gsk_attribute_set_callback      Curl_gsk_attribute_set_callback
 
 extern int      Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
                                                 GSK_BUF_ID bufID,
-                                                const char * * buffer,
-                                                int * bufSize);
+                                                const char **buffer,
+                                                int *bufSize);
 #define gsk_attribute_get_buffer        Curl_gsk_attribute_get_buffer_a
 
 extern int      Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
                                             GSK_ENUM_ID enumID,
-                                            GSK_ENUM_VALUE * enumValue);
+                                            GSK_ENUM_VALUE *enumValue);
 #define gsk_attribute_get_enum  Curl_gsk_attribute_get_enum
 
 extern int      Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
                                                      GSK_NUM_ID numID,
-                                                     int * numValue);
+                                                     int *numValue);
 #define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
 
 extern int      Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
                                  GSK_CERT_ID certID,
-                                 const gsk_cert_data_elem * * certDataElem,
-                                 int * certDataElementCount);
+                                 const gsk_cert_data_elem **certDataElem,
+                                 int *certDataElementCount);
 #define gsk_attribute_get_cert_info     Curl_gsk_attribute_get_cert_info
 
 extern int      Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
@@ -125,13 +125,13 @@
 #define gsk_secure_soc_misc     Curl_gsk_secure_soc_misc
 
 extern int      Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
-                                         char * readBuffer,
-                                         int readBufSize, int * amtRead);
+                                         char *readBuffer,
+                                         int readBufSize, int *amtRead);
 #define gsk_secure_soc_read     Curl_gsk_secure_soc_read
 
 extern int      Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
-                                          char * writeBuffer,
-                                          int writeBufSize, int * amtWritten);
+                                          char *writeBuffer,
+                                          int writeBufSize, int *amtWritten);
 #define gsk_secure_soc_write    Curl_gsk_secure_soc_write
 
 extern const char *     Curl_gsk_strerror_a(int gsk_return_value);
@@ -202,10 +202,10 @@
 
 extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
 extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
-extern int Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
-            struct sockaddr * dstaddr, int addrlen);
-extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
-                                struct sockaddr * fromaddr, int * addrlen);
+extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
+                             struct sockaddr * dstaddr, int addrlen);
+extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
+                               struct sockaddr *fromaddr, int *addrlen);
 
 #define connect                 Curl_os400_connect
 #define bind                    Curl_os400_bind
diff --git a/lib/setup-vms.h b/lib/setup-vms.h
index 4b78e0b..6c454ae 100644
--- a/lib/setup-vms.h
+++ b/lib/setup-vms.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +41,7 @@
 #   endif
 #endif
 #include <stdlib.h>
-    char * decc$getenv(const char * __name);
+char *decc$getenv(const char *__name);
 #include <pwd.h>
 
 #include <string.h>
@@ -79,23 +79,24 @@
 #   if __INITIAL_POINTER_SIZE == 32
 /* Translate the path, but only if the path is a VMS file specification */
 /* The translation is usually only needed for older versions of VMS */
-static char * vms_translate_path(const char * path) {
-char * unix_path;
-char * test_str;
+static char *vms_translate_path(const char *path)
+{
+  char *unix_path;
+  char *test_str;
 
-    /* See if the result is in VMS format, if not, we are done */
-    /* Assume that this is a PATH, not just some data */
-    test_str = strpbrk(path, ":[<^");
-    if(test_str == NULL) {
-      return (char *)path;
-    }
+  /* See if the result is in VMS format, if not, we are done */
+  /* Assume that this is a PATH, not just some data */
+  test_str = strpbrk(path, ":[<^");
+  if(test_str == NULL) {
+    return (char *)path;
+  }
 
-    unix_path = decc$translate_vms(path);
+  unix_path = decc$translate_vms(path);
 
-    if((int)unix_path <= 0) {
-      /* We can not translate it, so return the original string */
-      return (char *)path;
-    }
+  if((int)unix_path <= 0) {
+    /* We can not translate it, so return the original string */
+    return (char *)path;
+  }
 }
 #   else
     /* VMS translate path is actually not needed on the current 64 bit */
@@ -111,74 +112,74 @@
 #   endif
 #endif
 
-static char * vms_getenv(const char * envvar) {
+static char *vms_getenv(const char *envvar)
+{
+  char *result;
+  char *vms_path;
 
-char * result;
-char * vms_path;
-
-    /* first use the DECC getenv() function */
-    result = decc$getenv(envvar);
-    if(result == NULL) {
-      return result;
-    }
-
-    vms_path = result;
-    result = vms_translate_path(vms_path);
-
-    /* note that if you backport this to use VAX C RTL, that the VAX C RTL */
-    /* may do a malloc(2048) for each call to getenv(), so you will need   */
-    /* to add a free(vms_path) */
-    /* Do not do a free() for DEC C RTL builds, which should be used for */
-    /* VMS 5.5-2 and later, even if using GCC */
-
+  /* first use the DECC getenv() function */
+  result = decc$getenv(envvar);
+  if(result == NULL) {
     return result;
+  }
+
+  vms_path = result;
+  result = vms_translate_path(vms_path);
+
+  /* note that if you backport this to use VAX C RTL, that the VAX C RTL */
+  /* may do a malloc(2048) for each call to getenv(), so you will need   */
+  /* to add a free(vms_path) */
+  /* Do not do a free() for DEC C RTL builds, which should be used for */
+  /* VMS 5.5-2 and later, even if using GCC */
+
+  return result;
 }
 
 
 static struct passwd vms_passwd_cache;
 
-static struct passwd * vms_getpwuid(uid_t uid) {
-
-struct passwd * my_passwd;
+static struct passwd * vms_getpwuid(uid_t uid)
+{
+  struct passwd * my_passwd;
 
 /* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
 #ifdef __DECC
 #   if __INITIAL_POINTER_SIZE
-__char_ptr32 unix_path;
+  __char_ptr32 unix_path;
 #   else
-char * unix_path;
+  char *unix_path;
 #   endif
 #else
-char * unix_path;
+  char *unix_path;
 #endif
 
-    my_passwd = decc_getpwuid(uid);
-    if(my_passwd == NULL) {
-      return my_passwd;
-    }
+  my_passwd = decc_getpwuid(uid);
+  if(my_passwd == NULL) {
+    return my_passwd;
+  }
 
-    unix_path = vms_translate_path(my_passwd->pw_dir);
+  unix_path = vms_translate_path(my_passwd->pw_dir);
 
-    if((long)unix_path <= 0) {
-      /* We can not translate it, so return the original string */
-      return my_passwd;
-    }
+  if((long)unix_path <= 0) {
+    /* We can not translate it, so return the original string */
+    return my_passwd;
+  }
 
-    /* If no changes needed just return it */
-    if(unix_path == my_passwd->pw_dir) {
-      return my_passwd;
-    }
+  /* If no changes needed just return it */
+  if(unix_path == my_passwd->pw_dir) {
+    return my_passwd;
+  }
 
-    /* Need to copy the structure returned */
-    /* Since curl is only using pw_dir, no need to fix up *
-    /* the pw_shell when running under Bash */
-    vms_passwd_cache.pw_name = my_passwd->pw_name;
-    vms_passwd_cache.pw_uid = my_passwd->pw_uid;
-    vms_passwd_cache.pw_gid = my_passwd->pw_uid;
-    vms_passwd_cache.pw_dir = unix_path;
-    vms_passwd_cache.pw_shell = my_passwd->pw_shell;
+  /* Need to copy the structure returned */
+  /* Since curl is only using pw_dir, no need to fix up */
+  /* the pw_shell when running under Bash */
+  vms_passwd_cache.pw_name = my_passwd->pw_name;
+  vms_passwd_cache.pw_uid = my_passwd->pw_uid;
+  vms_passwd_cache.pw_gid = my_passwd->pw_uid;
+  vms_passwd_cache.pw_dir = unix_path;
+  vms_passwd_cache.pw_shell = my_passwd->pw_shell;
 
-    return &vms_passwd_cache;
+  return &vms_passwd_cache;
 }
 
 #ifdef __DECC
diff --git a/lib/smb.c b/lib/smb.c
index 56a38c2..f197fe1 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2016, 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
@@ -308,8 +308,8 @@
   if(smbc->got < sizeof(unsigned int))
     return CURLE_OK;
 
-  nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) +
-             sizeof(unsigned int);
+  nbt_size = Curl_read16_be((const unsigned char *)(buf +
+             sizeof(unsigned short))) + sizeof(unsigned int);
   if(smbc->got < nbt_size)
     return CURLE_OK;
 
@@ -320,7 +320,7 @@
     if(nbt_size >= msg_size + sizeof(unsigned short)) {
       /* Add the byte count */
       msg_size += sizeof(unsigned short) +
-                  Curl_read16_le((unsigned char *)&buf[msg_size]);
+                  Curl_read16_le((const unsigned char *)&buf[msg_size]);
       if(nbt_size < msg_size)
         return CURLE_READ_ERROR;
     }
@@ -673,7 +673,7 @@
 
   switch(smbc->state) {
   case SMB_NEGOTIATE:
-    if(h->status) {
+    if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
       connclose(conn, "SMB: negotiation failed");
       return CURLE_COULDNT_CONNECT;
     }
@@ -712,6 +712,7 @@
 {
   struct smb_request *req = conn->data->req.protop;
   struct smb_header *h;
+  struct smb_conn *smbc = &conn->proto.smbc;
   enum smb_req_state next_state = SMB_DONE;
   unsigned short len;
   unsigned short off;
@@ -754,7 +755,7 @@
     break;
 
   case SMB_OPEN:
-    if(h->status) {
+    if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
       req->result = CURLE_REMOTE_FILE_NOT_FOUND;
       next_state = SMB_TREE_DISCONNECT;
       break;
@@ -775,17 +776,16 @@
     break;
 
   case SMB_DOWNLOAD:
-    if(h->status) {
+    if(h->status || smbc->got < sizeof(struct smb_header) + 14) {
       req->result = CURLE_RECV_ERROR;
       next_state = SMB_CLOSE;
       break;
     }
-    len = Curl_read16_le(((unsigned char *) msg) +
+    len = Curl_read16_le(((const unsigned char *) msg) +
                          sizeof(struct smb_header) + 11);
-    off = Curl_read16_le(((unsigned char *) msg) +
+    off = Curl_read16_le(((const unsigned char *) msg) +
                          sizeof(struct smb_header) + 13);
     if(len > 0) {
-      struct smb_conn *smbc = &conn->proto.smbc;
       if(off + sizeof(unsigned int) + len > smbc->got) {
         failf(conn->data, "Invalid input packet");
         result = CURLE_RECV_ERROR;
@@ -807,12 +807,12 @@
     break;
 
   case SMB_UPLOAD:
-    if(h->status) {
+    if(h->status || smbc->got < sizeof(struct smb_header) + 6) {
       req->result = CURLE_UPLOAD_FAILED;
       next_state = SMB_CLOSE;
       break;
     }
-    len = Curl_read16_le(((unsigned char *) msg) +
+    len = Curl_read16_le(((const unsigned char *) msg) +
                          sizeof(struct smb_header) + 5);
     conn->data->req.bytecount += len;
     conn->data->req.offset += len;
diff --git a/lib/smtp.c b/lib/smtp.c
index d203b53..ff8e80d 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -69,16 +69,14 @@
 #include "http.h" /* for HTTP proxy tunnel stuff */
 #include "socks.h"
 #include "smtp.h"
-
 #include "strtoofft.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "vtls/vtls.h"
 #include "connect.h"
 #include "strerror.h"
 #include "select.h"
 #include "multiif.h"
 #include "url.h"
-#include "rawstr.h"
 #include "curl_gethostname.h"
 #include "curl_sasl.h"
 #include "warnless.h"
@@ -105,7 +103,7 @@
 static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
                                   const char *initresp);
 static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
-static void smtp_get_message(char *buffer, char** outptr);
+static void smtp_get_message(char *buffer, char **outptr);
 
 /*
  * SMTP protocol handler.
@@ -280,10 +278,10 @@
  *
  * Gets the authentication message from the response buffer.
  */
-static void smtp_get_message(char *buffer, char** outptr)
+static void smtp_get_message(char *buffer, char **outptr)
 {
   size_t len = 0;
-  char* message = NULL;
+  char *message = NULL;
 
   /* Find the start of the message */
   for(message = buffer + 4; *message == ' ' || *message == '\t'; message++)
@@ -674,7 +672,7 @@
 
   if(smtpcode/100 != 2) {
     failf(data, "Got unexpected smtp-server response: %d", smtpcode);
-    result = CURLE_FTP_WEIRD_SERVER_REPLY;
+    result = CURLE_WEIRD_SERVER_REPLY;
   }
   else
     result = smtp_perform_ehlo(conn);
@@ -1512,7 +1510,7 @@
     while(*ptr && *ptr != ';')
       ptr++;
 
-    if(strnequal(key, "AUTH=", 5))
+    if(strncasecompare(key, "AUTH=", 5))
       result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
                                                value, ptr - value);
     else
diff --git a/lib/socks.c b/lib/socks.c
index fccb16d..774fb20 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -33,7 +33,6 @@
 
 #include "urldata.h"
 #include "sendf.h"
-#include "strequal.h"
 #include "select.h"
 #include "connect.h"
 #include "timeval.h"
@@ -58,7 +57,7 @@
   ssize_t nread;
   ssize_t allread = 0;
   int result;
-  long timeleft;
+  time_t timeleft;
   *n = 0;
   for(;;) {
     timeleft = Curl_timeleft(conn->data, NULL, TRUE);
@@ -67,7 +66,7 @@
       result = CURLE_OPERATION_TIMEDOUT;
       break;
     }
-    if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
+    if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
       result = ~CURLE_OK;
       break;
     }
@@ -110,9 +109,10 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn,
-                     bool protocol4a)
+                     struct connectdata *conn)
 {
+  const bool protocol4a =
+    (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
 #define SOCKS4REQLEN 262
   unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
                                            id */
@@ -127,6 +127,10 @@
     return CURLE_OPERATION_TIMEDOUT;
   }
 
+  if(conn->bits.httpproxy)
+    infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
+          protocol4a ? "a" : "", hostname, remote_port);
+
   (void)curlx_nonblock(sock, FALSE);
 
   infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
@@ -170,24 +174,26 @@
       hp=dns->addr;
     if(hp) {
       char buf[64];
-      unsigned short ip[4];
       Curl_printable_address(hp, buf, sizeof(buf));
 
-      if(4 == sscanf(buf, "%hu.%hu.%hu.%hu",
-                     &ip[0], &ip[1], &ip[2], &ip[3])) {
-        /* Set DSTIP */
-        socksreq[4] = (unsigned char)ip[0];
-        socksreq[5] = (unsigned char)ip[1];
-        socksreq[6] = (unsigned char)ip[2];
-        socksreq[7] = (unsigned char)ip[3];
+      if(hp->ai_family == AF_INET) {
+        struct sockaddr_in *saddr_in;
+
+        saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
+        socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0];
+        socksreq[5] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[1];
+        socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2];
+        socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3];
+
+        infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
       }
-      else
+      else {
         hp = NULL; /* fail! */
 
-      infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
+        failf(data, "SOCKS4 connection to %s not supported\n", buf);
+      }
 
       Curl_resolv_unlock(data, dns); /* not used anymore from now on */
-
     }
     if(!hp) {
       failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
@@ -218,7 +224,7 @@
     ssize_t written;
     ssize_t hostnamelen = 0;
     int packetsize = 9 +
-      (int)strlen((char*)socksreq + 8); /* size including NUL */
+      (int)strlen((char *)socksreq + 8); /* size including NUL */
 
     /* If SOCKS4a, set special invalid IP address 0.0.0.x */
     if(protocol4a) {
@@ -229,7 +235,7 @@
       /* If still enough room in buffer, also append hostname */
       hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
       if(packetsize + hostnamelen <= SOCKS4REQLEN)
-        strcpy((char*)socksreq + packetsize, hostname);
+        strcpy((char *)socksreq + packetsize, hostname);
       else
         hostnamelen = 0; /* Flag: hostname did not fit in buffer */
     }
@@ -375,11 +381,16 @@
   CURLcode code;
   curl_socket_t sock = conn->sock[sockindex];
   struct Curl_easy *data = conn->data;
-  long timeout;
-  bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
+  time_t timeout;
+  bool socks5_resolve_local =
+    (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
   const size_t hostname_len = strlen(hostname);
   ssize_t len = 0;
 
+  if(conn->bits.httpproxy)
+    infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
+          hostname, remote_port);
+
   /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
   if(!socks5_resolve_local && hostname_len > 255) {
     infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
@@ -399,7 +410,7 @@
   (void)curlx_nonblock(sock, TRUE);
 
   /* wait until socket gets connected */
-  result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout);
+  result = SOCKET_WRITABLE(sock, timeout);
 
   if(-1 == result) {
     failf(conn->data, "SOCKS5: no connection here");
@@ -429,6 +440,8 @@
 
   (void)curlx_nonblock(sock, FALSE);
 
+  infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
+
   code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
                           &written);
   if(code || (written != (2 + (int)socksreq[1]))) {
@@ -438,7 +451,7 @@
 
   (void)curlx_nonblock(sock, TRUE);
 
-  result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout);
+  result = SOCKET_READABLE(sock, timeout);
 
   if(-1 == result) {
     failf(conn->data, "SOCKS5 nothing to read");
@@ -594,34 +607,41 @@
     if(dns)
       hp=dns->addr;
     if(hp) {
-      struct sockaddr_in *saddr_in;
-#ifdef ENABLE_IPV6
-      struct sockaddr_in6 *saddr_in6;
-#endif
       int i;
+      char buf[64];
+      Curl_printable_address(hp, buf, sizeof(buf));
 
       if(hp->ai_family == AF_INET) {
+        struct sockaddr_in *saddr_in;
         socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
 
-        saddr_in = (struct sockaddr_in*)(void*)hp->ai_addr;
+        saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
         for(i = 0; i < 4; i++) {
-          socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i];
-          infof(data, "%d\n", socksreq[len-1]);
+          socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
         }
+
+        infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
       }
 #ifdef ENABLE_IPV6
       else if(hp->ai_family == AF_INET6) {
+        struct sockaddr_in6 *saddr_in6;
         socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
 
-        saddr_in6 = (struct sockaddr_in6*)(void*)hp->ai_addr;
+        saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
         for(i = 0; i < 16; i++) {
-          socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i];
+          socksreq[len++] =
+            ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
         }
+
+        infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
       }
 #endif
-      else
+      else {
         hp = NULL; /* fail! */
 
+        failf(data, "SOCKS5 connection to %s not supported\n", buf);
+      }
+
       Curl_resolv_unlock(data, dns); /* not used anymore from now on */
     }
     if(!hp) {
@@ -668,39 +688,6 @@
           "SOCKS5 reply has wrong version, version should be 5.");
     return CURLE_COULDNT_CONNECT;
   }
-  if(socksreq[1] != 0) { /* Anything besides 0 is an error */
-    if(socksreq[3] == 1) {
-      failf(data,
-            "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
-            (unsigned char)socksreq[1]);
-    }
-    else if(socksreq[3] == 3) {
-      failf(data,
-            "Can't complete SOCKS5 connection to %s:%d. (%d)",
-            hostname,
-            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
-            (unsigned char)socksreq[1]);
-    }
-    else if(socksreq[3] == 4) {
-      failf(data,
-            "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
-            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (unsigned char)socksreq[8], (unsigned char)socksreq[9],
-            (unsigned char)socksreq[10], (unsigned char)socksreq[11],
-            (unsigned char)socksreq[12], (unsigned char)socksreq[13],
-            (unsigned char)socksreq[14], (unsigned char)socksreq[15],
-            (unsigned char)socksreq[16], (unsigned char)socksreq[17],
-            (unsigned char)socksreq[18], (unsigned char)socksreq[19],
-            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
-            (unsigned char)socksreq[1]);
-    }
-    return CURLE_COULDNT_CONNECT;
-  }
 
   /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
      1928, so the reply packet should be read until the end to avoid errors at
@@ -735,10 +722,9 @@
     /* decrypt_gssapi_blockread already read the whole packet */
 #endif
     if(len > 10) {
-      len -= 10;
       result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
-                                  len, &actualread);
-      if(result || (len != actualread)) {
+                                  len - 10, &actualread);
+      if(result || ((len - 10) != actualread)) {
         failf(data, "Failed to receive SOCKS5 connect request ack.");
         return CURLE_COULDNT_CONNECT;
       }
@@ -747,6 +733,49 @@
   }
 #endif
 
+  if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+    if(socksreq[3] == 1) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) |
+             (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+    }
+    else if(socksreq[3] == 3) {
+      unsigned char port_upper = (unsigned char)socksreq[len - 2];
+      socksreq[len - 2] = 0;
+      failf(data,
+            "Can't complete SOCKS5 connection to %s:%d. (%d)",
+            (char *)&socksreq[5],
+            ((port_upper << 8) |
+             (unsigned char)socksreq[len - 1]),
+            (unsigned char)socksreq[1]);
+      socksreq[len - 2] = port_upper;
+    }
+    else if(socksreq[3] == 4) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
+            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (unsigned char)socksreq[8], (unsigned char)socksreq[9],
+            (unsigned char)socksreq[10], (unsigned char)socksreq[11],
+            (unsigned char)socksreq[12], (unsigned char)socksreq[13],
+            (unsigned char)socksreq[14], (unsigned char)socksreq[15],
+            (unsigned char)socksreq[16], (unsigned char)socksreq[17],
+            (unsigned char)socksreq[18], (unsigned char)socksreq[19],
+            (((unsigned char)socksreq[20] << 8) |
+             (unsigned char)socksreq[21]),
+            (unsigned char)socksreq[1]);
+    }
+    return CURLE_COULDNT_CONNECT;
+  }
+  else {
+    infof(data, "SOCKS5 request granted.\n");
+  }
+
   (void)curlx_nonblock(sock, TRUE);
   return CURLE_OK; /* Proxy was successful! */
 }
diff --git a/lib/socks.h b/lib/socks.h
index a44ada6..348707e 100644
--- a/lib/socks.h
+++ b/lib/socks.h
@@ -25,7 +25,7 @@
 #include "curl_setup.h"
 
 #ifdef CURL_DISABLE_PROXY
-#define Curl_SOCKS4(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
 #define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
 #else
 /*
@@ -49,8 +49,7 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn,
-                     bool protocol4a);
+                     struct connectdata *conn);
 
 /*
  * This function logs in to a SOCKS5 proxy and sends the specifics to the
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 369245a..32d6725 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -46,7 +46,7 @@
 static int check_gss_err(struct Curl_easy *data,
                          OM_uint32 major_status,
                          OM_uint32 minor_status,
-                         const char* function)
+                         const char *function)
 {
   if(GSS_ERROR(major_status)) {
     OM_uint32 maj_stat, min_stat;
@@ -65,7 +65,7 @@
                                     &msg_ctx, &status_string);
       if(maj_stat == GSS_S_COMPLETE) {
         if(sizeof(buf) > len + status_string.length + 1) {
-          strcpy(buf+len, (char*) status_string.value);
+          strcpy(buf+len, (char *) status_string.value);
           len += status_string.length;
         }
         gss_release_buffer(&min_stat, &status_string);
@@ -86,7 +86,7 @@
                                     &msg_ctx, &status_string);
       if(maj_stat == GSS_S_COMPLETE) {
         if(sizeof(buf) > len + status_string.length)
-          strcpy(buf+len, (char*) status_string.value);
+          strcpy(buf+len, (char *) status_string.value);
         gss_release_buffer(&min_stat, &status_string);
         break;
       }
@@ -123,6 +123,7 @@
   unsigned char socksreq[4]; /* room for GSS-API exchange header only */
   const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ?
                            data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
+  const size_t serviceptr_length = strlen(serviceptr);
 
   /*   GSS-API request looks like
    * +----+------+-----+----------------+
@@ -134,22 +135,23 @@
 
   /* prepare service name */
   if(strchr(serviceptr, '/')) {
-    service.value = malloc(strlen(serviceptr));
+    service.length = serviceptr_length;
+    service.value = malloc(service.length);
     if(!service.value)
       return CURLE_OUT_OF_MEMORY;
-    service.length = strlen(serviceptr);
     memcpy(service.value, serviceptr, service.length);
 
     gss_major_status = gss_import_name(&gss_minor_status, &service,
                                        (gss_OID) GSS_C_NULL_OID, &server);
   }
   else {
-    service.value = malloc(strlen(serviceptr) +strlen(conn->proxy.name)+2);
+    service.value = malloc(serviceptr_length +
+                           strlen(conn->socks_proxy.host.name)+2);
     if(!service.value)
       return CURLE_OUT_OF_MEMORY;
-    service.length = strlen(serviceptr) +strlen(conn->proxy.name)+1;
+    service.length = serviceptr_length + strlen(conn->socks_proxy.host.name)+1;
     snprintf(service.value, service.length+1, "%s@%s",
-             serviceptr, conn->proxy.name);
+             serviceptr, conn->socks_proxy.host.name);
 
     gss_major_status = gss_import_name(&gss_minor_status, &service,
                                        GSS_C_NT_HOSTBASED_SERVICE, &server);
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index 6053490..edc73ad 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -45,7 +45,7 @@
  */
 static int check_sspi_err(struct connectdata *conn,
                           SECURITY_STATUS status,
-                          const char* function)
+                          const char *function)
 {
   if(status != SEC_E_OK &&
      status != SEC_I_COMPLETE_AND_CONTINUE &&
@@ -86,6 +86,7 @@
   unsigned char socksreq[4]; /* room for GSS-API exchange header only */
   const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
                         data->set.str[STRING_PROXY_SERVICE_NAME]  : "rcmd";
+  const size_t service_length = strlen(service);
 
   /*   GSS-API request looks like
    * +----+------+-----+----------------+
@@ -102,11 +103,13 @@
       return CURLE_OUT_OF_MEMORY;
   }
   else {
-    service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
+    service_name = malloc(service_length +
+                          strlen(conn->socks_proxy.host.name) + 2);
     if(!service_name)
       return CURLE_OUT_OF_MEMORY;
-    snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2,
-             "%s/%s", service, conn->proxy.name);
+    snprintf(service_name, service_length +
+             strlen(conn->socks_proxy.host.name)+2, "%s/%s",
+             service, conn->socks_proxy.host.name);
   }
 
   input_desc.cBuffers = 1;
diff --git a/lib/speedcheck.c b/lib/speedcheck.c
index 13c34af..bc15d97 100644
--- a/lib/speedcheck.c
+++ b/lib/speedcheck.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -40,8 +40,8 @@
      data->set.low_speed_time &&
      (Curl_tvlong(data->state.keeps_speed) != 0) &&
      (data->progress.current_speed < data->set.low_speed_limit)) {
-    long howlong = Curl_tvdiff(now, data->state.keeps_speed);
-    long nextcheck = (data->set.low_speed_time * 1000) - howlong;
+    time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
+    time_t nextcheck = (data->set.low_speed_time * 1000) - howlong;
 
     /* We are now below the "low speed limit". If we are below it
        for "low speed time" seconds we consider that enough reason
diff --git a/lib/ssh.c b/lib/ssh.c
index 7bc3136..04ca39c 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -71,8 +71,8 @@
 #include "url.h"
 #include "speedcheck.h"
 #include "getinfo.h"
-
-#include "strequal.h"
+#include "strdup.h"
+#include "strcase.h"
 #include "vtls/vtls.h"
 #include "connect.h"
 #include "strerror.h"
@@ -416,12 +416,12 @@
   struct Curl_easy *data = conn->data;
   char *real_path = NULL;
   char *working_path;
-  int working_path_len;
-
-  working_path = curl_easy_unescape(data, data->state.path, 0,
-                                    &working_path_len);
-  if(!working_path)
-    return CURLE_OUT_OF_MEMORY;
+  size_t working_path_len;
+  CURLcode result =
+    Curl_urldecode(data, data->state.path, 0, &working_path,
+                   &working_path_len, FALSE);
+  if(result)
+    return result;
 
   /* Check for /~/, indicating relative to the user's home directory */
   if(conn->handler->protocol & CURLPROTO_SCP) {
@@ -676,7 +676,7 @@
    * against a known fingerprint, if available.
    */
   if(pubkey_md5 && strlen(pubkey_md5) == 32) {
-    if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
+    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
       if(fingerprint)
         failf(data,
             "Denied establishing ssh session: mismatch md5 fingerprint. "
@@ -874,7 +874,7 @@
           break;
         }
 
-        sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
+        sshc->passphrase = data->set.ssl.key_passwd;
         if(!sshc->passphrase)
           sshc->passphrase = "";
 
@@ -1233,7 +1233,7 @@
         sshc->acceptfail = TRUE;
       }
 
-      if(curl_strequal("pwd", cmd)) {
+      if(strcasecompare("pwd", cmd)) {
         /* output debug output if that is requested */
         char *tmp = aprintf("257 \"%s\" is current directory.\n",
                             sftp_scp->path);
@@ -1297,9 +1297,9 @@
          * OpenSSH's sftp program and call the appropriate libssh2
          * functions.
          */
-        if(curl_strnequal(cmd, "chgrp ", 6) ||
-           curl_strnequal(cmd, "chmod ", 6) ||
-           curl_strnequal(cmd, "chown ", 6) ) {
+        if(strncasecompare(cmd, "chgrp ", 6) ||
+           strncasecompare(cmd, "chmod ", 6) ||
+           strncasecompare(cmd, "chown ", 6) ) {
           /* attribute change */
 
           /* sshc->quote_path1 contains the mode to set */
@@ -1321,8 +1321,8 @@
           state(conn, SSH_SFTP_QUOTE_STAT);
           break;
         }
-        else if(curl_strnequal(cmd, "ln ", 3) ||
-                curl_strnequal(cmd, "symlink ", 8)) {
+        else if(strncasecompare(cmd, "ln ", 3) ||
+                strncasecompare(cmd, "symlink ", 8)) {
           /* symbolic linking */
           /* sshc->quote_path1 is the source */
           /* get the destination */
@@ -1342,12 +1342,12 @@
           state(conn, SSH_SFTP_QUOTE_SYMLINK);
           break;
         }
-        else if(curl_strnequal(cmd, "mkdir ", 6)) {
+        else if(strncasecompare(cmd, "mkdir ", 6)) {
           /* create dir */
           state(conn, SSH_SFTP_QUOTE_MKDIR);
           break;
         }
-        else if(curl_strnequal(cmd, "rename ", 7)) {
+        else if(strncasecompare(cmd, "rename ", 7)) {
           /* rename file */
           /* first param is the source path */
           /* second param is the dest. path */
@@ -1366,17 +1366,17 @@
           state(conn, SSH_SFTP_QUOTE_RENAME);
           break;
         }
-        else if(curl_strnequal(cmd, "rmdir ", 6)) {
+        else if(strncasecompare(cmd, "rmdir ", 6)) {
           /* delete dir */
           state(conn, SSH_SFTP_QUOTE_RMDIR);
           break;
         }
-        else if(curl_strnequal(cmd, "rm ", 3)) {
+        else if(strncasecompare(cmd, "rm ", 3)) {
           state(conn, SSH_SFTP_QUOTE_UNLINK);
           break;
         }
 #ifdef HAS_STATVFS_SUPPORT
-        else if(curl_strnequal(cmd, "statvfs ", 8)) {
+        else if(strncasecompare(cmd, "statvfs ", 8)) {
           state(conn, SSH_SFTP_QUOTE_STATVFS);
           break;
         }
@@ -1431,7 +1431,7 @@
         sshc->acceptfail = TRUE;
       }
 
-      if(!curl_strnequal(cmd, "chmod", 5)) {
+      if(!strncasecompare(cmd, "chmod", 5)) {
         /* Since chown and chgrp only set owner OR group but libssh2 wants to
          * set them both at once, we need to obtain the current ownership
          * first.  This takes an extra protocol round trip.
@@ -1457,7 +1457,7 @@
       }
 
       /* Now set the new attributes... */
-      if(curl_strnequal(cmd, "chgrp", 5)) {
+      if(strncasecompare(cmd, "chgrp", 5)) {
         sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
         if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
@@ -1471,7 +1471,7 @@
           break;
         }
       }
-      else if(curl_strnequal(cmd, "chmod", 5)) {
+      else if(strncasecompare(cmd, "chmod", 5)) {
         sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
         /* permissions are octal */
@@ -1486,7 +1486,7 @@
           break;
         }
       }
-      else if(curl_strnequal(cmd, "chown", 5)) {
+      else if(strncasecompare(cmd, "chown", 5)) {
         sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
         if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
@@ -1895,7 +1895,7 @@
         /* since we don't really wait for anything at this point, we want the
            state machine to move on as soon as possible so we set a very short
            timeout here */
-        Curl_expire(data, 1);
+        Curl_expire(data, 0);
 
         state(conn, SSH_STOP);
       }
@@ -2112,9 +2112,10 @@
 
       /* get room for the filename and extra output */
       sshc->readdir_totalLen += 4 + sshc->readdir_len;
-      new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
+      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+                                          sshc->readdir_totalLen);
       if(!new_readdir_line) {
-        Curl_safefree(sshc->readdir_line);
+        sshc->readdir_line = NULL;
         Curl_safefree(sshc->readdir_filename);
         Curl_safefree(sshc->readdir_longentry);
         state(conn, SSH_SFTP_CLOSE);
@@ -2860,7 +2861,7 @@
       if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
         fd_write = sock;
       /* wait for the socket to become ready */
-      Curl_socket_ready(fd_read, fd_write,
+      Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
                         left>1000?1000:left); /* ignore result */
     }
 #endif
@@ -3109,7 +3110,6 @@
 
 }
 
-/* return number of received (decrypted) bytes */
 static ssize_t scp_send(struct connectdata *conn, int sockindex,
                         const void *mem, size_t len, CURLcode *err)
 {
@@ -3134,10 +3134,6 @@
   return nwrite;
 }
 
-/*
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
                         char *mem, size_t len, CURLcode *err)
 {
diff --git a/lib/rawstr.c b/lib/strcase.c
similarity index 80%
rename from lib/rawstr.c
rename to lib/strcase.c
index 5665ebd..ccbaac1 100644
--- a/lib/rawstr.c
+++ b/lib/strcase.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +22,9 @@
 
 #include "curl_setup.h"
 
-#include "rawstr.h"
+#include <curl/curl.h>
+
+#include "strcase.h"
 
 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
    its behavior is altered by the current locale. */
@@ -99,9 +101,11 @@
  *
  * The function is capable of comparing a-z case insensitively even for
  * non-ascii.
+ *
+ * @unittest: 1301
  */
 
-int Curl_raw_equal(const char *first, const char *second)
+int Curl_strcasecompare(const char *first, const char *second)
 {
   while(*first && *second) {
     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
@@ -116,7 +120,20 @@
   return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
 }
 
-int Curl_raw_nequal(const char *first, const char *second, size_t max)
+int Curl_safe_strcasecompare(const char *first, const char *second)
+{
+  if(first && second)
+    /* both pointers point to something then compare them */
+    return Curl_strcasecompare(first, second);
+  else
+    /* if both pointers are NULL then treat them as equal */
+    return (NULL == first && NULL == second);
+}
+
+/*
+ * @unittest: 1301
+ */
+int Curl_strncasecompare(const char *first, const char *second, size_t max)
 {
   while(*first && *second && max) {
     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
@@ -146,3 +163,14 @@
     *dest++ = Curl_raw_toupper(*src);
   } while(*src++ && --n);
 }
+
+/* --- public functions --- */
+
+int curl_strequal(const char *first, const char *second)
+{
+  return Curl_strcasecompare(first, second);
+}
+int curl_strnequal(const char *first, const char *second, size_t max)
+{
+  return Curl_strncasecompare(first, second, max);
+}
diff --git a/lib/rawstr.h b/lib/strcase.h
similarity index 64%
rename from lib/rawstr.h
rename to lib/strcase.h
index 4af00f1..ea2abc8 100644
--- a/lib/rawstr.h
+++ b/lib/strcase.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_RAWSTR_H
-#define HEADER_CURL_RAWSTR_H
+#ifndef HEADER_CURL_STRCASE_H
+#define HEADER_CURL_STRCASE_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,23 +25,27 @@
 #include <curl/curl.h>
 
 /*
- * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
- * to be locale independent and only compare strings we know are safe for
- * this.
+ * Only "raw" case insensitive strings. This is meant to be locale independent
+ * and only compare strings we know are safe for this.
  *
  * The function is capable of comparing a-z case insensitively even for
  * non-ascii.
  */
-int Curl_raw_equal(const char *first, const char *second);
-int Curl_raw_nequal(const char *first, const char *second, size_t max);
+
+#define strcasecompare(a,b) Curl_strcasecompare(a,b)
+#define strncasecompare(a,b,c) Curl_strncasecompare(a,b,c)
+
+int Curl_strcasecompare(const char *first, const char *second);
+int Curl_safe_strcasecompare(const char *first, const char *second);
+int Curl_strncasecompare(const char *first, const char *second, size_t max);
 
 char Curl_raw_toupper(char in);
 
 /* checkprefix() is a shorter version of the above, used when the first
    argument is zero-byte terminated */
-#define checkprefix(a,b)    Curl_raw_nequal(a,b,strlen(a))
+#define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
 
 void Curl_strntoupper(char *dest, const char *src, size_t n);
+char Curl_raw_toupper(char in);
 
-#endif /* HEADER_CURL_RAWSTR_H */
-
+#endif /* HEADER_CURL_STRCASE_H */
diff --git a/lib/strdup.c b/lib/strdup.c
index 23f554e..136b693 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -65,9 +65,9 @@
  * Returns the new pointer or NULL on failure.
  *
  ***************************************************************************/
-char *Curl_memdup(const char *src, size_t length)
+void *Curl_memdup(const void *src, size_t length)
 {
-  char *buffer = malloc(length);
+  void *buffer = malloc(length);
   if(!buffer)
     return NULL; /* fail */
 
@@ -75,3 +75,26 @@
 
   return buffer;
 }
+
+/***************************************************************************
+ *
+ * Curl_saferealloc(ptr, size)
+ *
+ * Does a normal realloc(), but will free the data pointer if the realloc
+ * fails. If 'size' is zero, it will free the data and return a failure.
+ *
+ * This convenience function is provided and used to help us avoid a common
+ * mistake pattern when we could pass in a zero, catch the NULL return and end
+ * up free'ing the memory twice.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+void *Curl_saferealloc(void *ptr, size_t size)
+{
+  void *datap = realloc(ptr, size);
+  if(size && !datap)
+    /* only free 'ptr' if size was non-zero */
+    free(ptr);
+  return datap;
+}
diff --git a/lib/strdup.h b/lib/strdup.h
index 4c48ca4..ae3d5d0 100644
--- a/lib/strdup.h
+++ b/lib/strdup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,6 +26,7 @@
 #ifndef HAVE_STRDUP
 extern char *curlx_strdup(const char *str);
 #endif
-char *Curl_memdup(const char *src, size_t buffer_length);
+void *Curl_memdup(const void *src, size_t buffer_length);
+void *Curl_saferealloc(void *ptr, size_t size);
 
 #endif /* HEADER_CURL_STRDUP_H */
diff --git a/lib/strequal.c b/lib/strequal.c
deleted file mode 100644
index 01c3784..0000000
--- a/lib/strequal.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2013, 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"
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include "strequal.h"
-
-/*
- * @unittest: 1301
- */
-int curl_strequal(const char *first, const char *second)
-{
-#if defined(HAVE_STRCASECMP)
-  return !(strcasecmp)(first, second);
-#elif defined(HAVE_STRCMPI)
-  return !(strcmpi)(first, second);
-#elif defined(HAVE_STRICMP)
-  return !(stricmp)(first, second);
-#else
-  while(*first && *second) {
-    if(toupper(*first) != toupper(*second)) {
-      break;
-    }
-    first++;
-    second++;
-  }
-  return toupper(*first) == toupper(*second);
-#endif
-}
-
-/*
- * @unittest: 1301
- */
-int curl_strnequal(const char *first, const char *second, size_t max)
-{
-#if defined(HAVE_STRNCASECMP)
-  return !strncasecmp(first, second, max);
-#elif defined(HAVE_STRNCMPI)
-  return !strncmpi(first, second, max);
-#elif defined(HAVE_STRNICMP)
-  return !strnicmp(first, second, max);
-#else
-  while(*first && *second && max) {
-    if(toupper(*first) != toupper(*second)) {
-      break;
-    }
-    max--;
-    first++;
-    second++;
-  }
-  if(0 == max)
-    return 1; /* they are equal this far */
-
-  return toupper(*first) == toupper(*second);
-#endif
-}
diff --git a/lib/strerror.c b/lib/strerror.c
index 0e268d5..db50c7d 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -35,8 +35,8 @@
 
 #include <curl/curl.h>
 
-#ifdef USE_LIBIDN
-#include <idna.h>
+#ifdef USE_LIBIDN2
+#include <idn2.h>
 #endif
 
 #ifdef USE_WINDOWS_SSPI
@@ -79,8 +79,8 @@
   case CURLE_COULDNT_CONNECT:
     return "Couldn't connect to server";
 
-  case CURLE_FTP_WEIRD_SERVER_REPLY:
-    return "FTP: weird server reply";
+  case CURLE_WEIRD_SERVER_REPLY:
+    return "Weird server reply";
 
   case CURLE_REMOTE_ACCESS_DENIED:
     return "Access denied to remote resource";
@@ -427,7 +427,7 @@
 
 #ifdef USE_WINSOCK
 
-/* This function handles most / all (?) Winsock errors cURL is able to produce.
+/* This function handles most / all (?) Winsock errors curl is able to produce.
  */
 static const char *
 get_winsock_error (int err, char *buf, size_t len)
@@ -726,83 +726,6 @@
   return buf;
 }
 
-#ifdef USE_LIBIDN
-/*
- * Return error-string for libidn status as returned from idna_to_ascii_lz().
- */
-const char *Curl_idn_strerror (struct connectdata *conn, int err)
-{
-#ifdef HAVE_IDNA_STRERROR
-  (void)conn;
-  return idna_strerror((Idna_rc) err);
-#else
-  const char *str;
-  char *buf;
-  size_t max;
-
-  DEBUGASSERT(conn);
-
-  buf = conn->syserr_buf;
-  max = sizeof(conn->syserr_buf)-1;
-  *buf = '\0';
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-  switch ((Idna_rc)err) {
-    case IDNA_SUCCESS:
-      str = "No error";
-      break;
-    case IDNA_STRINGPREP_ERROR:
-      str = "Error in string preparation";
-      break;
-    case IDNA_PUNYCODE_ERROR:
-      str = "Error in Punycode operation";
-      break;
-    case IDNA_CONTAINS_NON_LDH:
-      str = "Illegal ASCII characters";
-      break;
-    case IDNA_CONTAINS_MINUS:
-      str = "Contains minus";
-      break;
-    case IDNA_INVALID_LENGTH:
-      str = "Invalid output length";
-      break;
-    case IDNA_NO_ACE_PREFIX:
-      str = "No ACE prefix (\"xn--\")";
-      break;
-    case IDNA_ROUNDTRIP_VERIFY_ERROR:
-      str = "Round trip verify error";
-      break;
-    case IDNA_CONTAINS_ACE_PREFIX:
-      str = "Already have ACE prefix (\"xn--\")";
-      break;
-    case IDNA_ICONV_ERROR:
-      str = "Locale conversion failed";
-      break;
-    case IDNA_MALLOC_ERROR:
-      str = "Allocation failed";
-      break;
-    case IDNA_DLOPEN_ERROR:
-      str = "dlopen() error";
-      break;
-    default:
-      snprintf(buf, max, "error %d", err);
-      str = NULL;
-      break;
-  }
-#else
-  if((Idna_rc)err == IDNA_SUCCESS)
-    str = "No error";
-  else
-    str = "Error";
-#endif
-  if(str)
-    strncpy(buf, str, max);
-  buf[max] = '\0';
-  return (buf);
-#endif
-}
-#endif  /* USE_LIBIDN */
-
 #ifdef USE_WINDOWS_SSPI
 const char *Curl_sspi_strerror (struct connectdata *conn, int err)
 {
diff --git a/lib/strerror.h b/lib/strerror.h
index ae8c96b..627273e 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +26,7 @@
 
 const char *Curl_strerror (struct connectdata *conn, int err);
 
-#ifdef USE_LIBIDN
+#ifdef USE_LIBIDN2
 const char *Curl_idn_strerror (struct connectdata *conn, int err);
 #endif
 
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index 6d5d2d5..b854bf4 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -165,7 +165,7 @@
     value = c - 'a' + 10;
   }
 #else
-  const char * cp;
+  const char *cp;
   int value;
 
   cp = memchr(valchars, c, 10 + 26 + 26);
diff --git a/lib/system_win32.c b/lib/system_win32.c
index d6a998b..7873759 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -83,7 +83,39 @@
 {
   bool matched = FALSE;
 
-#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+#if defined(CURL_WINDOWS_APP)
+  /* We have no way to determine the Windows version from Windows apps,
+     so let's assume we're running on the target Windows version. */
+  const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
+  const WORD targetVersion = (WORD)_WIN32_WINNT;
+
+  switch(condition) {
+  case VERSION_LESS_THAN:
+    matched = targetVersion < fullVersion;
+    break;
+
+  case VERSION_LESS_THAN_EQUAL:
+    matched = targetVersion <= fullVersion;
+    break;
+
+  case VERSION_EQUAL:
+    matched = targetVersion == fullVersion;
+    break;
+
+  case VERSION_GREATER_THAN_EQUAL:
+    matched = targetVersion >= fullVersion;
+    break;
+
+  case VERSION_GREATER_THAN:
+    matched = targetVersion > fullVersion;
+    break;
+  }
+
+  if(matched && (platform == PLATFORM_WINDOWS)) {
+    /* we're always running on PLATFORM_WINNT */
+    matched = FALSE;
+  }
+#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
     (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
   OSVERSIONINFO osver;
 
@@ -128,7 +160,7 @@
     }
 
     /* Verify the platform identifier (if necessary) */
-    if(matched && platform != PLATFORM_DONT_CARE) {
+    if(matched) {
       switch(platform) {
       case PLATFORM_WINDOWS:
         if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
@@ -138,6 +170,9 @@
       case PLATFORM_WINNT:
         if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
           matched = FALSE;
+
+      default: /* like platform == PLATFORM_DONT_CARE */
+        break;
       }
     }
   }
diff --git a/lib/telnet.c b/lib/telnet.c
index cc705cf..ddf3d3b 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -58,8 +58,7 @@
 
 #include "arpa_telnet.h"
 #include "select.h"
-#include "strequal.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "warnless.h"
 
 /* The last 3 #include files should be in this order */
@@ -846,7 +845,7 @@
               option_keyword, option_arg) == 2) {
 
       /* Terminal type */
-      if(Curl_raw_equal(option_keyword, "TTYPE")) {
+      if(strcasecompare(option_keyword, "TTYPE")) {
         strncpy(tn->subopt_ttype, option_arg, 31);
         tn->subopt_ttype[31] = 0; /* String termination */
         tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
@@ -854,7 +853,7 @@
       }
 
       /* Display variable */
-      if(Curl_raw_equal(option_keyword, "XDISPLOC")) {
+      if(strcasecompare(option_keyword, "XDISPLOC")) {
         strncpy(tn->subopt_xdisploc, option_arg, 127);
         tn->subopt_xdisploc[127] = 0; /* String termination */
         tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
@@ -862,7 +861,7 @@
       }
 
       /* Environment variable */
-      if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
+      if(strcasecompare(option_keyword, "NEW_ENV")) {
         beg = curl_slist_append(tn->telnet_vars, option_arg);
         if(!beg) {
           result = CURLE_OUT_OF_MEMORY;
@@ -874,7 +873,7 @@
       }
 
           /* Window Size */
-      if(Curl_raw_equal(option_keyword, "WS")) {
+      if(strcasecompare(option_keyword, "WS")) {
         if(sscanf(option_arg, "%hu%*[xX]%hu",
                   &tn->subopt_wsx, &tn->subopt_wsy) == 2)
           tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
@@ -887,7 +886,7 @@
       }
 
       /* To take care or not of the 8th bit in data exchange */
-      if(Curl_raw_equal(option_keyword, "BINARY")) {
+      if(strcasecompare(option_keyword, "BINARY")) {
         binary_option=atoi(option_arg);
         if(binary_option!=1) {
           tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
@@ -1005,7 +1004,7 @@
   ssize_t bytes_written;
   int err;
   unsigned short x, y;
-  unsigned char*uc1, *uc2;
+  unsigned char *uc1, *uc2;
 
   struct Curl_easy *data = conn->data;
   struct TELNET *tn = (struct TELNET *)data->req.protop;
@@ -1021,8 +1020,8 @@
     /* Window size must be sent according to the 'network order' */
     x=htons(tn->subopt_wsx);
     y=htons(tn->subopt_wsy);
-    uc1 = (unsigned char*)&x;
-    uc2 = (unsigned char*)&y;
+    uc1 = (unsigned char *)&x;
+    uc2 = (unsigned char *)&y;
     CURL_SB_ACCUM(tn, uc1[0]);
     CURL_SB_ACCUM(tn, uc1[1]);
     CURL_SB_ACCUM(tn, uc2[0]);
diff --git a/lib/tftp.c b/lib/tftp.c
index d7ff94f..de99c6e 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -55,9 +55,10 @@
 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
 #include "multiif.h"
 #include "url.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "speedcheck.h"
 #include "select.h"
+#include "escape.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -198,7 +199,7 @@
 static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
 {
   time_t maxtime, timeout;
-  long timeout_ms;
+  time_t timeout_ms;
   bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
 
   time(&state->start_time);
@@ -484,10 +485,10 @@
     /* As RFC3617 describes the separator slash is not actually part of the
        file name so we skip the always-present first letter of the path
        string. */
-    filename = curl_easy_unescape(data, &state->conn->data->state.path[1], 0,
-                                  NULL);
-    if(!filename)
-      return CURLE_OUT_OF_MEMORY;
+    result = Curl_urldecode(data, &state->conn->data->state.path[1], 0,
+                            &filename, NULL, FALSE);
+    if(result)
+      return result;
 
     snprintf((char *)state->spacket.data+2,
              state->blksize,
@@ -705,6 +706,7 @@
   int rblock;
   CURLcode result = CURLE_OK;
   struct SingleRequest *k = &data->req;
+  int cb; /* Bytes currently read */
 
   switch(event) {
 
@@ -762,9 +764,20 @@
       return CURLE_OK;
     }
 
-    result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
-    if(result)
-      return result;
+    /* TFTP considers data block size < 512 bytes as an end of session. So
+     * in some cases we must wait for additional data to build full (512 bytes)
+     * data block.
+     * */
+    state->sbytes = 0;
+    state->conn->data->req.upload_fromhere = (char *)state->spacket.data+4;
+    do {
+      result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
+                                   &cb);
+      if(result)
+        return result;
+      state->sbytes += cb;
+      state->conn->data->req.upload_fromhere += cb;
+    } while(state->sbytes < state->blksize && cb != 0);
 
     sbytes = sendto(state->sockfd, (void *) state->spacket.data,
                     4 + state->sbytes, SEND_4TH_ARG,
@@ -1221,7 +1234,7 @@
   }
   else {
     /* no timeouts to handle, check our socket */
-    rc = Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, 0);
+    rc = SOCKET_READABLE(state->sockfd, 0);
 
     if(rc == -1) {
       /* bail out */
@@ -1343,7 +1356,7 @@
 static CURLcode tftp_setup_connection(struct connectdata * conn)
 {
   struct Curl_easy *data = conn->data;
-  char * type;
+  char *type;
   char command;
 
   conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
diff --git a/lib/timeval.c b/lib/timeval.c
index 629f1c8..f3b207a 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -116,7 +116,7 @@
  * Returns: the time difference in number of milliseconds. For large diffs it
  * returns 0x7fffffff on 32bit time_t systems.
  */
-long curlx_tvdiff(struct timeval newer, struct timeval older)
+time_t curlx_tvdiff(struct timeval newer, struct timeval older)
 {
 #if SIZEOF_TIME_T < 8
   /* for 32bit time_t systems, add a precaution to avoid overflow for really
@@ -126,7 +126,7 @@
     return 0x7fffffff;
 #endif
   return (newer.tv_sec-older.tv_sec)*1000+
-    (long)(newer.tv_usec-older.tv_usec)/1000;
+    (time_t)(newer.tv_usec-older.tv_usec)/1000;
 }
 
 /*
@@ -144,7 +144,7 @@
 }
 
 /* return the number of seconds in the given input timeval struct */
-long Curl_tvlong(struct timeval t1)
+time_t Curl_tvlong(struct timeval t1)
 {
   return t1.tv_sec;
 }
diff --git a/lib/timeval.h b/lib/timeval.h
index 50c31a2..09f8b3a 100644
--- a/lib/timeval.h
+++ b/lib/timeval.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +37,7 @@
  *
  * Returns: the time difference in number of milliseconds.
  */
-long curlx_tvdiff(struct timeval t1, struct timeval t2);
+time_t curlx_tvdiff(struct timeval t1, struct timeval t2);
 
 /*
  * Same as curlx_tvdiff but with full usec resolution.
@@ -46,7 +46,7 @@
  */
 double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
 
-long Curl_tvlong(struct timeval t1);
+time_t Curl_tvlong(struct timeval t1);
 
 /* These two defines below exist to provide the older API for library
    internals only. */
diff --git a/lib/transfer.c b/lib/transfer.c
index f5987fe..052ecc1 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -21,10 +21,7 @@
  ***************************************************************************/
 
 #include "curl_setup.h"
-
 #include "strtoofft.h"
-#include "strequal.h"
-#include "rawstr.h"
 
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
@@ -75,6 +72,7 @@
 #include "multiif.h"
 #include "connect.h"
 #include "non-ascii.h"
+#include "http2.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -384,11 +382,15 @@
  * Go ahead and do a read if we have a readable socket or if
  * the stream was rewound (in which case we have data in a
  * buffer)
+ *
+ * return '*comeback' TRUE if we didn't properly drain the socket so this
+ * function should get called again without select() or similar in between!
  */
 static CURLcode readwrite_data(struct Curl_easy *data,
                                struct connectdata *conn,
                                struct SingleRequest *k,
-                               int *didwhat, bool *done)
+                               int *didwhat, bool *done,
+                               bool *comeback)
 {
   CURLcode result = CURLE_OK;
   ssize_t nread; /* number of bytes read */
@@ -398,6 +400,7 @@
   int maxloops = 100;
 
   *done = FALSE;
+  *comeback = FALSE;
 
   /* This is where we loop until we have read everything there is to
      read or we get a CURLE_AGAIN */
@@ -529,6 +532,13 @@
        is non-headers. */
     if(k->str && !k->header && (nread > 0 || is_empty_data)) {
 
+      if(data->set.opt_no_body) {
+        /* data arrives although we want none, bail out */
+        streamclose(conn, "ignoring body");
+        *done = TRUE;
+        return CURLE_WEIRD_SERVER_REPLY;
+      }
+
 #ifndef CURL_DISABLE_HTTP
       if(0 == k->bodywrites && !is_empty_data) {
         /* These checks are only made the first time we are about to
@@ -804,6 +814,12 @@
 
   } while(data_pending(conn) && maxloops--);
 
+  if(maxloops <= 0) {
+    /* we mark it as read-again-please */
+    conn->cselect_bits = CURL_CSELECT_IN;
+    *comeback = TRUE;
+  }
+
   if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
      conn->bits.close) {
     /* When we've read the entire thing and the close bit is set, the server
@@ -821,6 +837,8 @@
 {
   k->keepon &= ~KEEP_SEND; /* we're done writing */
 
+  Curl_http2_done_sending(conn);
+
   if(conn->bits.rewindaftersend) {
     CURLcode result = Curl_readrewind(conn);
     if(result)
@@ -1029,10 +1047,14 @@
 /*
  * Curl_readwrite() is the low-level function to be called when data is to
  * be read and written to/from the connection.
+ *
+ * return '*comeback' TRUE if we didn't properly drain the socket so this
+ * function should get called again without select() or similar in between!
  */
 CURLcode Curl_readwrite(struct connectdata *conn,
                         struct Curl_easy *data,
-                        bool *done)
+                        bool *done,
+                        bool *comeback)
 {
   struct SingleRequest *k = &data->req;
   CURLcode result;
@@ -1064,7 +1086,7 @@
 
   if(!select_res) /* Call for select()/poll() only, if read/write/error
                      status is not known. */
-    select_res = Curl_socket_ready(fd_read, fd_write, 0);
+    select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0);
 
   if(select_res == CURL_CSELECT_ERR) {
     failf(data, "select/poll returned error");
@@ -1077,7 +1099,7 @@
   if((k->keepon & KEEP_RECV) &&
      ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
 
-    result = readwrite_data(data, conn, k, &didwhat, done);
+    result = readwrite_data(data, conn, k, &didwhat, done, comeback);
     if(result || *done)
       return result;
   }
@@ -1115,7 +1137,7 @@
 
       */
 
-      long ms = Curl_tvdiff(k->now, k->start100);
+      time_t ms = Curl_tvdiff(k->now, k->start100);
       if(ms >= data->set.expect_100_timeout) {
         /* we've waited long enough, continue anyway */
         k->exp100 = EXP100_SEND_DATA;
@@ -1249,60 +1271,6 @@
   return bitmap;
 }
 
-/*
- * Determine optimum sleep time based on configured rate, current rate,
- * and packet size.
- * Returns value in milliseconds.
- *
- * The basic idea is to adjust the desired rate up/down in this method
- * based on whether we are running too slow or too fast.  Then, calculate
- * how many milliseconds to wait for the next packet to achieve this new
- * rate.
- */
-long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
-                             int pkt_size)
-{
-  curl_off_t min_sleep = 0;
-  curl_off_t rv = 0;
-
-  if(rate_bps == 0)
-    return 0;
-
-  /* If running faster than about .1% of the desired speed, slow
-   * us down a bit.  Use shift instead of division as the 0.1%
-   * cutoff is arbitrary anyway.
-   */
-  if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) {
-    /* running too fast, decrease target rate by 1/64th of rate */
-    rate_bps -= rate_bps >> 6;
-    min_sleep = 1;
-  }
-  else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) {
-    /* running too slow, increase target rate by 1/64th of rate */
-    rate_bps += rate_bps >> 6;
-  }
-
-  /* Determine number of milliseconds to wait until we do
-   * the next packet at the adjusted rate.  We should wait
-   * longer when using larger packets, for instance.
-   */
-  rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
-
-  /* Catch rounding errors and always slow down at least 1ms if
-   * we are running too fast.
-   */
-  if(rv < min_sleep)
-    rv = min_sleep;
-
-  /* Bound value to fit in 'long' on 32-bit platform.  That's
-   * plenty long enough anyway!
-   */
-  if(rv > 0x7fffffff)
-    rv = 0x7fffffff;
-
-  return (long)rv;
-}
-
 /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
    which means this gets called once for each subsequent redirect etc */
 void Curl_init_CONNECT(struct Curl_easy *data)
@@ -1328,7 +1296,7 @@
   /* Init the SSL session ID cache here. We do it here since we want to do it
      after the *_setopt() calls (that could specify the size of the cache) but
      before any transfer takes place. */
-  result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
+  result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions);
   if(result)
     return result;
 
@@ -1875,13 +1843,12 @@
     return CURLE_OK;
 
   if((data->req.bytecount + data->req.headerbytecount == 0) &&
-      conn->bits.reuse &&
-      !data->set.opt_no_body &&
-      (data->set.rtspreq != RTSPREQ_RECEIVE)) {
-    /* We got no data, we attempted to re-use a connection and yet we want a
-       "body". This might happen if the connection was left alive when we were
-       done using it before, but that was closed when we wanted to read from
-       it again. Bad luck. Retry the same request on a fresh connect! */
+     conn->bits.reuse &&
+     (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+    /* We didn't get a single byte when we attempted to re-use a
+       connection. This might happen if the connection was left alive when we
+       were done using it before, but that was closed when we wanted to use it
+       again. Bad luck. Retry the same request on a fresh connect! */
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
     if(!*url)
diff --git a/lib/transfer.h b/lib/transfer.h
index 0e253e3..5189672 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -40,10 +40,9 @@
 
 CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
                      followtype type);
-
-
 CURLcode Curl_readwrite(struct connectdata *conn,
-                        struct Curl_easy *data, bool *done);
+                        struct Curl_easy *data, bool *done,
+                        bool *comeback);
 int Curl_single_getsock(const struct connectdata *conn,
                         curl_socket_t *socks,
                         int numsocks);
@@ -65,8 +64,5 @@
                curl_off_t *writecountp /* return number of bytes written */
 );
 
-long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
-                     int pkt_size);
-
 #endif /* HEADER_CURL_TRANSFER_H */
 
diff --git a/lib/url.c b/lib/url.c
index e547e5c..5dee7a7 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -59,24 +59,13 @@
 #include <limits.h>
 #endif
 
-#ifdef USE_LIBIDN
-#include <idna.h>
-#include <tld.h>
-#include <stringprep.h>
-#ifdef HAVE_IDN_FREE_H
-#include <idn-free.h>
-#else
-/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
-void idn_free (void *ptr);
-#endif
-#ifndef HAVE_IDN_FREE
-/* if idn_free() was not found in this version of libidn use free() instead */
-#define idn_free(x) (free)(x)
-#endif
+#ifdef USE_LIBIDN2
+#include <idn2.h>
+
 #elif defined(USE_WIN32_IDN)
 /* prototype for curl_win32_idn_to_ascii() */
 bool curl_win32_idn_to_ascii(const char *in, char **out);
-#endif  /* USE_LIBIDN */
+#endif  /* USE_LIBIDN2 */
 
 #include "urldata.h"
 #include "netrc.h"
@@ -88,7 +77,7 @@
 #include "sendf.h"
 #include "progress.h"
 #include "cookie.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "strerror.h"
 #include "escape.h"
 #include "strtok.h"
@@ -100,10 +89,10 @@
 #include "multiif.h"
 #include "easyif.h"
 #include "speedcheck.h"
-#include "rawstr.h"
 #include "warnless.h"
 #include "non-ascii.h"
 #include "inet_pton.h"
+#include "getinfo.h"
 
 /* And now for the protocols */
 #include "ftp.h"
@@ -405,7 +394,7 @@
   if(!data)
     return CURLE_OK;
 
-  Curl_expire(data, 0); /* shut off timers */
+  Curl_expire_clear(data); /* shut off timers */
 
   m = data->multi;
 
@@ -537,7 +526,7 @@
   set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
 
   /* Set the default size of the SSL session ID cache */
-  set->ssl.max_ssl_sessions = 5;
+  set->general_ssl.max_ssl_sessions = 5;
 
   set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
   set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
@@ -551,14 +540,16 @@
    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
    * switched off unless wanted.
    */
-  set->ssl.verifypeer = TRUE;
-  set->ssl.verifyhost = TRUE;
+  set->ssl.primary.verifypeer = TRUE;
+  set->ssl.primary.verifyhost = TRUE;
 #ifdef USE_TLS_SRP
   set->ssl.authtype = CURL_TLSAUTH_NONE;
 #endif
   set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
                                                       type */
-  set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
+  set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
+                                        default */
+  set->proxy_ssl = set->ssl;
 
   set->new_file_perms = 0644;    /* Default permissions */
   set->new_directory_perms = 0755; /* Default permissions */
@@ -581,14 +572,17 @@
 
   /* This is our preferred CA cert bundle/path since install time */
 #if defined(CURL_CA_BUNDLE)
-  result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
+  result = setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
   if(result)
     return result;
 #endif
 #if defined(CURL_CA_PATH)
-  result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
+  result = setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
   if(result)
     return result;
+
+  result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY],
+                     (char *) CURL_CA_PATH);
 #endif
 
   set->wildcardmatch  = FALSE;
@@ -602,6 +596,7 @@
   set->tcp_keepintvl = 60;
   set->tcp_keepidle = 60;
   set->tcp_fastopen = FALSE;
+  set->tcp_nodelay = TRUE;
 
   set->ssl_enable_npn = TRUE;
   set->ssl_enable_alpn = TRUE;
@@ -657,6 +652,8 @@
 
     Curl_convert_init(data);
 
+    Curl_initinfo(data);
+
     /* most recent connection is not yet defined */
     data->state.lastconnect = NULL;
 
@@ -705,7 +702,12 @@
     break;
   case CURLOPT_SSL_CIPHER_LIST:
     /* set a list of cipher we want to use in the SSL connection */
-    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
+    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSL_CIPHER_LIST:
+    /* set a list of cipher we want to use in the SSL connection for proxy */
+    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
                        va_arg(param, char *));
     break;
 
@@ -781,6 +783,10 @@
      */
     data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
+  case CURLOPT_KEEP_SENDING_ON_ERROR:
+    data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
+                                           TRUE : FALSE;
+    break;
   case CURLOPT_UPLOAD:
   case CURLOPT_PUT:
     /*
@@ -907,7 +913,18 @@
      * implementations are lame.
      */
 #ifdef USE_SSL
-    data->set.ssl.version = va_arg(param, long);
+    data->set.ssl.primary.version = va_arg(param, long);
+#else
+    result = CURLE_UNKNOWN_OPTION;
+#endif
+    break;
+  case CURLOPT_PROXY_SSLVERSION:
+    /*
+     * Set explicit SSL version to try to connect with for proxy, as some SSL
+     * implementations are lame.
+     */
+#ifdef USE_SSL
+    data->set.proxy_ssl.primary.version = va_arg(param, long);
 #else
     result = CURLE_UNKNOWN_OPTION;
 #endif
@@ -1014,7 +1031,7 @@
           (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
         result = CURLE_OUT_OF_MEMORY;
       else {
-        char * p;
+        char *p;
 
         (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
 
@@ -1225,23 +1242,23 @@
     if(argptr == NULL)
       break;
 
-    if(Curl_raw_equal(argptr, "ALL")) {
+    if(strcasecompare(argptr, "ALL")) {
       /* clear all cookies */
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
       Curl_cookie_clearall(data->cookies);
       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
     }
-    else if(Curl_raw_equal(argptr, "SESS")) {
+    else if(strcasecompare(argptr, "SESS")) {
       /* clear session cookies */
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
       Curl_cookie_clearsess(data->cookies);
       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
     }
-    else if(Curl_raw_equal(argptr, "FLUSH")) {
+    else if(strcasecompare(argptr, "FLUSH")) {
       /* flush cookies to file, takes care of the locking */
       Curl_flush_cookies(data, 0);
     }
-    else if(Curl_raw_equal(argptr, "RELOAD")) {
+    else if(strcasecompare(argptr, "RELOAD")) {
       /* reload cookies from file */
       Curl_cookie_loadfiles(data);
       break;
@@ -1441,18 +1458,30 @@
 
   case CURLOPT_PROXY:
     /*
-     * Set proxy server:port to use as HTTP proxy.
+     * Set proxy server:port to use as proxy.
      *
-     * If the proxy is set to "" we explicitly say that we don't want to use a
-     * proxy (even though there might be environment variables saying so).
+     * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
+     * we explicitly say that we don't want to use a proxy
+     * (even though there might be environment variables saying so).
      *
      * Setting it to NULL, means no proxy but allows the environment variables
-     * to decide for us.
+     * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
      */
     result = setstropt(&data->set.str[STRING_PROXY],
                        va_arg(param, char *));
     break;
 
+  case CURLOPT_SOCKS_PROXY:
+    /*
+     * Set proxy server:port to use as SOCKS proxy.
+     *
+     * If the proxy is set to "" or NULL we explicitly say that we don't want
+     * to use the socks proxy.
+     */
+    result = setstropt(&data->set.str[STRING_SOCKS_PROXY],
+                       va_arg(param, char *));
+    break;
+
   case CURLOPT_PROXYTYPE:
     /*
      * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
@@ -1460,6 +1489,13 @@
     data->set.proxytype = (curl_proxytype)va_arg(param, long);
     break;
 
+  case CURLOPT_SOCKS_PROXYTYPE:
+    /*
+     * Set proxy type. SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
+     */
+    data->set.socks_proxytype = (curl_proxytype)va_arg(param, long);
+    break;
+
   case CURLOPT_PROXY_TRANSFER_MODE:
     /*
      * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
@@ -1917,35 +1953,70 @@
     /*
      * String that holds file name of the SSL certificate to use
      */
-    result = setstropt(&data->set.str[STRING_CERT],
+    result = setstropt(&data->set.str[STRING_CERT_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLCERT:
+    /*
+     * String that holds file name of the SSL certificate to use for proxy
+     */
+    result = setstropt(&data->set.str[STRING_CERT_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_SSLCERTTYPE:
     /*
      * String that holds file type of the SSL certificate to use
      */
-    result = setstropt(&data->set.str[STRING_CERT_TYPE],
+    result = setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLCERTTYPE:
+    /*
+     * String that holds file type of the SSL certificate to use for proxy
+     */
+    result = setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_SSLKEY:
     /*
      * String that holds file name of the SSL key to use
      */
-    result = setstropt(&data->set.str[STRING_KEY],
+    result = setstropt(&data->set.str[STRING_KEY_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLKEY:
+    /*
+     * String that holds file name of the SSL key to use for proxy
+     */
+    result = setstropt(&data->set.str[STRING_KEY_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_SSLKEYTYPE:
     /*
      * String that holds file type of the SSL key to use
      */
-    result = setstropt(&data->set.str[STRING_KEY_TYPE],
+    result = setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLKEYTYPE:
+    /*
+     * String that holds file type of the SSL key to use for proxy
+     */
+    result = setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_KEYPASSWD:
     /*
      * String that holds the SSL or SSH private key password.
      */
-    result = setstropt(&data->set.str[STRING_KEY_PASSWD],
+    result = setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_KEYPASSWD:
+    /*
+     * String that holds the SSL private key password for proxy.
+     */
+    result = setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_SSLENGINE:
@@ -2008,7 +2079,15 @@
     /*
      * Enable peer SSL verifying.
      */
-    data->set.ssl.verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
+                                       TRUE : FALSE;
+    break;
+  case CURLOPT_PROXY_SSL_VERIFYPEER:
+    /*
+     * Enable peer SSL verifying for proxy.
+     */
+    data->set.proxy_ssl.primary.verifypeer =
+      (0 != va_arg(param, long))?TRUE:FALSE;
     break;
   case CURLOPT_SSL_VERIFYHOST:
     /*
@@ -2026,7 +2105,25 @@
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
 
-    data->set.ssl.verifyhost = (0 != arg) ? TRUE : FALSE;
+    data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
+    break;
+  case CURLOPT_PROXY_SSL_VERIFYHOST:
+    /*
+     * Enable verification of the host name in the peer certificate for proxy
+     */
+    arg = va_arg(param, long);
+
+    /* Obviously people are not reading documentation and too many thought
+       this argument took a boolean when it wasn't and misused it. We thus ban
+       1 as a sensible input and we warn about its use. Then we only have the
+       2 action internally stored as TRUE. */
+
+    if(1 == arg) {
+      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
     break;
   case CURLOPT_SSL_VERIFYSTATUS:
     /*
@@ -2037,7 +2134,8 @@
       break;
     }
 
-    data->set.ssl.verifystatus = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
+                                         TRUE : FALSE;
     break;
   case CURLOPT_SSL_CTX_FUNCTION:
 #ifdef have_curlssl_ssl_ctx
@@ -2093,7 +2191,15 @@
     /*
      * Set CA info for SSL connection. Specify file name of the CA certificate
      */
-    result = setstropt(&data->set.str[STRING_SSL_CAFILE],
+    result = setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_CAINFO:
+    /*
+     * Set CA info SSL connection for proxy. Specify file name of the
+     * CA certificate
+     */
+    result = setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_CAPATH:
@@ -2103,7 +2209,16 @@
      * certificates which have been prepared using openssl c_rehash utility.
      */
     /* This does not work on windows. */
-    result = setstropt(&data->set.str[STRING_SSL_CAPATH],
+    result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_CAPATH:
+    /*
+     * Set CA path info for SSL connection proxy. Specify directory name of the
+     * CA certificates which have been prepared using openssl c_rehash utility.
+     */
+    /* This does not work on windows. */
+    result = setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
                        va_arg(param, char *));
 #else
     result = CURLE_NOT_BUILT_IN;
@@ -2114,7 +2229,15 @@
      * Set CRL file info for SSL connection. Specify file name of the CRL
      * to check certificates revocation
      */
-    result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
+    result = setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_CRLFILE:
+    /*
+     * Set CRL file info for SSL connection for proxy. Specify file name of the
+     * CRL to check certificates revocation
+     */
+    result = setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
                        va_arg(param, char *));
     break;
   case CURLOPT_ISSUERCERT:
@@ -2122,7 +2245,7 @@
      * Set Issuer certificate file
      * to check certificates issuer
      */
-    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
+    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
                        va_arg(param, char *));
     break;
   case CURLOPT_TELNETOPTIONS:
@@ -2203,7 +2326,7 @@
       }
 #endif   /* CURL_DISABLE_HTTP */
       if(data->share->sslsession) {
-        data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
+        data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
         data->state.session = data->share->sslsession;
       }
       Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
@@ -2238,8 +2361,14 @@
 
   case CURLOPT_SSL_OPTIONS:
     arg = va_arg(param, long);
-    data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
-    data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    data->set.ssl.enable_beast = 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.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     break;
 
 #endif
@@ -2335,7 +2464,8 @@
     break;
 
   case CURLOPT_SSL_SESSIONID_CACHE:
-    data->set.ssl.sessionid = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
+                                      TRUE : FALSE;
     break;
 
 #ifdef USE_LIBSSH2
@@ -2602,23 +2732,43 @@
     break;
 #ifdef USE_TLS_SRP
   case CURLOPT_TLSAUTH_USERNAME:
-    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
+    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
                        va_arg(param, char *));
-    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+    if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
       data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
     break;
+  case CURLOPT_PROXY_TLSAUTH_USERNAME:
+    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
+                       va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
+       !data->set.proxy_ssl.authtype)
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
   case CURLOPT_TLSAUTH_PASSWORD:
-    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
+    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
                        va_arg(param, char *));
-    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+    if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
       data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
     break;
+  case CURLOPT_PROXY_TLSAUTH_PASSWORD:
+    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
+                       va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
+       !data->set.proxy_ssl.authtype)
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
   case CURLOPT_TLSAUTH_TYPE:
-    if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
+    if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
       data->set.ssl.authtype = CURL_TLSAUTH_SRP;
     else
       data->set.ssl.authtype = CURL_TLSAUTH_NONE;
     break;
+  case CURLOPT_PROXY_TLSAUTH_TYPE:
+    if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
+    else
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
+    break;
 #endif
   case CURLOPT_DNS_SERVERS:
     result = Curl_set_dns_servers(data, va_arg(param, char *));
@@ -2775,8 +2925,10 @@
   Curl_safefree(conn->passwd);
   Curl_safefree(conn->oauth_bearer);
   Curl_safefree(conn->options);
-  Curl_safefree(conn->proxyuser);
-  Curl_safefree(conn->proxypasswd);
+  Curl_safefree(conn->http_proxy.user);
+  Curl_safefree(conn->socks_proxy.user);
+  Curl_safefree(conn->http_proxy.passwd);
+  Curl_safefree(conn->socks_proxy.passwd);
   Curl_safefree(conn->allocptr.proxyuserpwd);
   Curl_safefree(conn->allocptr.uagent);
   Curl_safefree(conn->allocptr.userpwd);
@@ -2790,7 +2942,9 @@
   Curl_safefree(conn->trailer);
   Curl_safefree(conn->host.rawalloc); /* host name buffer */
   Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
-  Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
+  Curl_safefree(conn->secondaryhostname);
+  Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
+  Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
   Curl_safefree(conn->master_buffer);
 
   conn_reset_all_postponed_data(conn);
@@ -2802,7 +2956,12 @@
   conn->recv_pipe = NULL;
 
   Curl_safefree(conn->localdev);
-  Curl_free_ssl_config(&conn->ssl_config);
+  Curl_free_primary_ssl_config(&conn->ssl_config);
+  Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
+
+#ifdef USE_UNIX_SOCKETS
+  Curl_safefree(conn->unix_domain_socket);
+#endif
 
   free(conn); /* free all the connection oriented data */
 }
@@ -2829,6 +2988,17 @@
     return CURLE_OK;
   }
 
+  /*
+   * If this connection isn't marked to force-close, leave it open if there
+   * are other users of it
+   */
+  if(!conn->bits.close &&
+     (conn->send_pipe->size + conn->recv_pipe->size)) {
+    DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
+                 conn->send_pipe->size + conn->recv_pipe->size));
+    return CURLE_OK;
+  }
+
   if(conn->dns_entry != NULL) {
     Curl_resolv_unlock(data, conn->dns_entry);
     conn->dns_entry = NULL;
@@ -2852,6 +3022,8 @@
   free_fixed_hostname(&conn->host);
   free_fixed_hostname(&conn->conn_to_host);
   free_fixed_hostname(&conn->proxy);
+  free_fixed_hostname(&conn->http_proxy.host);
+  free_fixed_hostname(&conn->socks_proxy.host);
 
   Curl_ssl_close(conn, FIRSTSOCKET);
 
@@ -2876,7 +3048,7 @@
   int sval;
   bool ret_val = TRUE;
 
-  sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
+  sval = SOCKET_READABLE(sock, 0);
   if(sval == 0)
     /* timeout */
     ret_val = FALSE;
@@ -2892,7 +3064,8 @@
                                  const struct connectdata *conn)
 {
   /* If a HTTP protocol and pipelining is enabled */
-  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+     (!conn->bits.protoconnstart || !conn->bits.close)) {
 
     if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
        (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
@@ -3009,8 +3182,8 @@
   struct curl_hash_iterator iter;
   struct curl_llist_element *curr;
   struct curl_hash_element *he;
-  long highscore=-1;
-  long score;
+  time_t highscore=-1;
+  time_t score;
   struct timeval now;
   struct connectdata *conn_candidate = NULL;
   struct connectbundle *bundle;
@@ -3047,6 +3220,21 @@
   return conn_candidate;
 }
 
+static bool
+proxy_info_matches(const struct proxy_info* data,
+                   const struct proxy_info* needle)
+{
+  if((data->proxytype == needle->proxytype) &&
+     (data->port == needle->port) &&
+     Curl_safe_strcasecompare(data->host.name, needle->host.name) &&
+     Curl_safe_strcasecompare(data->user, needle->user) &&
+     Curl_safe_strcasecompare(data->passwd, needle->passwd))
+    return TRUE;
+
+  return FALSE;
+}
+
+
 /*
  * This function finds the connection in the connection
  * bundle that has been unused for the longest time.
@@ -3059,8 +3247,8 @@
                                       struct connectbundle *bundle)
 {
   struct curl_llist_element *curr;
-  long highscore=-1;
-  long score;
+  time_t highscore=-1;
+  time_t score;
   struct timeval now;
   struct connectdata *conn_candidate = NULL;
   struct connectdata *conn;
@@ -3142,7 +3330,7 @@
 static void prune_dead_connections(struct Curl_easy *data)
 {
   struct timeval now = Curl_tvnow();
-  long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+  time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
 
   if(elapsed >= 1000L) {
     Curl_conncache_foreach(data->state.conn_cache, data,
@@ -3267,6 +3455,8 @@
       pipeLen = check->send_pipe->size + check->recv_pipe->size;
 
       if(canPipeline) {
+        if(check->bits.protoconnstart && check->bits.close)
+          continue;
 
         if(!check->bits.multiplex) {
           /* If not multiplexing, make sure the pipe has only GET requests */
@@ -3319,6 +3509,17 @@
         }
       }
 
+#ifdef USE_UNIX_SOCKETS
+      if(needle->unix_domain_socket) {
+        if(!check->unix_domain_socket)
+          continue;
+        if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
+          continue;
+      }
+      else if(check->unix_domain_socket)
+        continue;
+#endif
+
       if((needle->handler->flags&PROTOPT_SSL) !=
          (check->handler->flags&PROTOPT_SSL))
         /* don't do mixed SSL and non-SSL connections */
@@ -3327,23 +3528,12 @@
           /* except protocols that have been upgraded via TLS */
           continue;
 
-      if(needle->handler->flags&PROTOPT_SSL) {
-        if((data->set.ssl.verifypeer != check->verifypeer) ||
-           (data->set.ssl.verifyhost != check->verifyhost))
-          continue;
-      }
-
-      if(needle->bits.proxy != check->bits.proxy)
-        /* don't do mixed proxy and non-proxy connections */
+      if(needle->bits.httpproxy != check->bits.httpproxy ||
+         needle->bits.socksproxy != check->bits.socksproxy)
         continue;
 
-      if(needle->bits.proxy &&
-         (needle->proxytype != check->proxytype ||
-          needle->bits.httpproxy != check->bits.httpproxy ||
-          needle->bits.tunnel_proxy != check->bits.tunnel_proxy ||
-          !Curl_raw_equal(needle->proxy.name, check->proxy.name) ||
-          needle->port != check->port))
-        /* don't mix connections that use different proxies */
+      if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
+                                                        &check->socks_proxy))
         continue;
 
       if(needle->bits.conn_to_host != check->bits.conn_to_host)
@@ -3356,6 +3546,33 @@
          * connections that don't use this feature */
         continue;
 
+      if(needle->bits.httpproxy) {
+        if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
+          continue;
+
+        if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
+          continue;
+
+        if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
+          /* use https proxy */
+          if(needle->handler->flags&PROTOPT_SSL) {
+            /* use double layer ssl */
+            if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
+                                        &check->proxy_ssl_config))
+              continue;
+            if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
+              continue;
+          }
+          else {
+            if(!Curl_ssl_config_matches(&needle->ssl_config,
+                                        &check->ssl_config))
+              continue;
+            if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
+              continue;
+          }
+        }
+      }
+
       if(!canPipeline && check->inuse)
         /* this request can't be pipelined but the checked connection is
            already in use so we skip it */
@@ -3375,35 +3592,35 @@
         */
         if((check->localport != needle->localport) ||
            (check->localportrange != needle->localportrange) ||
-           !check->localdev ||
-           !needle->localdev ||
-           strcmp(check->localdev, needle->localdev))
+           (needle->localdev &&
+            (!check->localdev || strcmp(check->localdev, needle->localdev))))
           continue;
       }
 
       if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
         /* This protocol requires credentials per connection,
            so verify that we're using the same name and password as well */
-        if(!strequal(needle->user, check->user) ||
-           !strequal(needle->passwd, check->passwd)) {
+        if(strcmp(needle->user, check->user) ||
+           strcmp(needle->passwd, check->passwd)) {
           /* one of them was different */
           continue;
         }
       }
 
       if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
-         (needle->bits.httpproxy && needle->bits.tunnel_proxy)) {
+         needle->bits.tunnel_proxy) {
         /* The requested connection does not use a HTTP proxy or it uses SSL or
-           it is a non-SSL protocol tunneled over the same HTTP proxy name and
-           port number */
-        if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
+           it is a non-SSL protocol tunneled or it is a non-SSL protocol which
+           is allowed to be upgraded via TLS */
+
+        if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
             (get_protocol_family(check->handler->protocol) ==
              needle->handler->protocol && check->tls_upgraded)) &&
-           (!needle->bits.conn_to_host || Curl_raw_equal(
+           (!needle->bits.conn_to_host || strcasecompare(
             needle->conn_to_host.name, check->conn_to_host.name)) &&
            (!needle->bits.conn_to_port ||
              needle->conn_to_port == check->conn_to_port) &&
-           Curl_raw_equal(needle->host.name, check->host.name) &&
+           strcasecompare(needle->host.name, check->host.name) &&
            needle->remote_port == check->remote_port) {
           /* The schemes match or the the protocol family is the same and the
              previous connection was TLS upgraded, and the hostname and host
@@ -3445,8 +3662,8 @@
            possible. (Especially we must not reuse the same connection if
            partway through a handshake!) */
         if(wantNTLMhttp) {
-          if(!strequal(needle->user, check->user) ||
-             !strequal(needle->passwd, check->passwd))
+          if(strcmp(needle->user, check->user) ||
+             strcmp(needle->passwd, check->passwd))
             continue;
         }
         else if(check->ntlm.state != NTLMSTATE_NONE) {
@@ -3456,12 +3673,13 @@
 
         /* Same for Proxy NTLM authentication */
         if(wantProxyNTLMhttp) {
-          /* Both check->proxyuser and check->proxypasswd can be NULL */
-          if(!check->proxyuser || !check->proxypasswd)
+          /* Both check->http_proxy.user and check->http_proxy.passwd can be
+           * NULL */
+          if(!check->http_proxy.user || !check->http_proxy.passwd)
             continue;
 
-          if(!strequal(needle->proxyuser, check->proxyuser) ||
-             !strequal(needle->proxypasswd, check->proxypasswd))
+          if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
+             strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
             continue;
         }
         else if(check->proxyntlm.state != NTLMSTATE_NONE) {
@@ -3565,51 +3783,48 @@
    Note: this function's sub-functions call failf()
 
 */
-CURLcode Curl_connected_proxy(struct connectdata *conn,
-                              int sockindex)
+CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
 {
-  if(!conn->bits.proxy || sockindex)
-    /* this magic only works for the primary socket as the secondary is used
-       for FTP only and it has FTP specific magic in ftp.c */
-    return CURLE_OK;
+  CURLcode result = CURLE_OK;
 
-  switch(conn->proxytype) {
+  if(conn->bits.socksproxy) {
 #ifndef CURL_DISABLE_PROXY
-  case CURLPROXY_SOCKS5:
-  case CURLPROXY_SOCKS5_HOSTNAME:
-    return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
-                       conn->bits.conn_to_host ? conn->conn_to_host.name :
-                       conn->host.name,
-                       conn->bits.conn_to_port ? conn->conn_to_port :
-                       conn->remote_port,
-                       FIRSTSOCKET, conn);
+    const char * const host = conn->bits.conn_to_host ?
+                              conn->conn_to_host.name :
+                              conn->bits.httpproxy ?
+                              conn->http_proxy.host.name :
+                              sockindex == SECONDARYSOCKET ?
+                              conn->secondaryhostname : conn->host.name;
+    const int port = conn->bits.conn_to_port ? conn->conn_to_port :
+                     conn->bits.httpproxy ?
+                     (int)conn->http_proxy.port :
+                     sockindex == SECONDARYSOCKET ?
+                      conn->secondary_port : conn->remote_port;
+    conn->bits.socksproxy_connecting = TRUE;
+    switch(conn->socks_proxy.proxytype) {
+    case CURLPROXY_SOCKS5:
+    case CURLPROXY_SOCKS5_HOSTNAME:
+      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+                         host, port, sockindex, conn);
+      break;
 
-  case CURLPROXY_SOCKS4:
-    return Curl_SOCKS4(conn->proxyuser,
-                       conn->bits.conn_to_host ? conn->conn_to_host.name :
-                       conn->host.name,
-                       conn->bits.conn_to_port ? conn->conn_to_port :
-                       conn->remote_port,
-                       FIRSTSOCKET, conn, FALSE);
+    case CURLPROXY_SOCKS4:
+    case CURLPROXY_SOCKS4A:
+      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+                           conn);
+      break;
 
-  case CURLPROXY_SOCKS4A:
-    return Curl_SOCKS4(conn->proxyuser,
-                       conn->bits.conn_to_host ? conn->conn_to_host.name :
-                       conn->host.name,
-                       conn->bits.conn_to_port ? conn->conn_to_port :
-                       conn->remote_port,
-                       FIRSTSOCKET, conn, TRUE);
-
+    default:
+      failf(conn->data, "unknown proxytype option given");
+      result = CURLE_COULDNT_CONNECT;
+    } /* switch proxytype */
+    conn->bits.socksproxy_connecting = FALSE;
+#else
+  (void)sockindex;
 #endif /* CURL_DISABLE_PROXY */
-  case CURLPROXY_HTTP:
-  case CURLPROXY_HTTP_1_0:
-    /* do nothing here. handled later. */
-    break;
-  default:
-    break;
-  } /* switch proxytype */
+  }
 
-  return CURLE_OK;
+  return result;
 }
 
 /*
@@ -3620,7 +3835,9 @@
 {
   if(conn->data->set.verbose)
     infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
-          conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
+          conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
+          conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+                             conn->host.dispname,
           conn->ip_addr_str, conn->port, conn->connection_id);
 }
 #endif
@@ -3710,10 +3927,14 @@
 
   if(!conn->bits.protoconnstart) {
 
-    result = Curl_proxy_connect(conn);
+    result = Curl_proxy_connect(conn, FIRSTSOCKET);
     if(result)
       return result;
 
+    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+      /* wait for HTTPS proxy SSL initialization to complete */
+      return CURLE_OK;
+
     if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
        (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
       /* when using an HTTP tunnel proxy, await complete tunnel establishment
@@ -3743,7 +3964,7 @@
  */
 static bool is_ASCII_name(const char *hostname)
 {
-  const unsigned char *ch = (const unsigned char*)hostname;
+  const unsigned char *ch = (const unsigned char *)hostname;
 
   while(*ch) {
     if(*ch++ & 0x80)
@@ -3752,58 +3973,15 @@
   return TRUE;
 }
 
-#ifdef USE_LIBIDN
-/*
- * Check if characters in hostname is allowed in Top Level Domain.
- */
-static bool tld_check_name(struct Curl_easy *data,
-                           const char *ace_hostname)
-{
-  size_t err_pos;
-  char *uc_name = NULL;
-  int rc;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-  const char *tld_errmsg = "<no msg>";
-#else
-  (void)data;
-#endif
-
-  /* Convert (and downcase) ACE-name back into locale's character set */
-  rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
-  if(rc != IDNA_SUCCESS)
-    return FALSE;
-
-  /* Warning: err_pos receives "the decoded character offset rather than the
-     byte position in the string." And as of libidn 1.32 that character offset
-     is for UTF-8, even if the passed in string is another locale. */
-  rc = tld_check_lz(uc_name, &err_pos, NULL);
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-#ifdef HAVE_TLD_STRERROR
-  if(rc != TLD_SUCCESS)
-    tld_errmsg = tld_strerror((Tld_rc)rc);
-#endif
-  if(rc != TLD_SUCCESS)
-    infof(data, "WARNING: TLD check for %s failed; %s\n",
-          uc_name, tld_errmsg);
-#endif /* CURL_DISABLE_VERBOSE_STRINGS */
-  if(uc_name)
-     idn_free(uc_name);
-  if(rc != TLD_SUCCESS)
-    return FALSE;
-
-  return TRUE;
-}
-#endif
-
 /*
  * Perform any necessary IDN conversion of hostname
  */
-static void fix_hostname(struct Curl_easy *data,
-                         struct connectdata *conn, struct hostname *host)
+static void fix_hostname(struct connectdata *conn, struct hostname *host)
 {
   size_t len;
+  struct Curl_easy *data = conn->data;
 
-#ifndef USE_LIBIDN
+#ifndef USE_LIBIDN2
   (void)data;
   (void)conn;
 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -3821,25 +3999,18 @@
 
   /* Check name for non-ASCII and convert hostname to ACE form if we can */
   if(!is_ASCII_name(host->name)) {
-#ifdef USE_LIBIDN
-    if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
+#ifdef USE_LIBIDN2
+    if(idn2_check_version(IDN2_VERSION)) {
       char *ace_hostname = NULL;
-
-      int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
-      infof(data, "Input domain encoded as `%s'\n",
-            stringprep_locale_charset());
-      if(rc == IDNA_SUCCESS) {
-        /* tld_check_name() displays a warning if the host name contains
-           "illegal" characters for this TLD */
-        (void)tld_check_name(data, ace_hostname);
-
-        host->encalloc = ace_hostname;
+      int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, 0);
+      if(rc == IDN2_OK) {
+        host->encalloc = (char *)ace_hostname;
         /* change the name pointer to point to the encoded hostname */
         host->name = host->encalloc;
       }
       else
         infof(data, "Failed to convert %s to ACE; %s\n", host->name,
-              Curl_idn_strerror(conn, rc));
+              idn2_strerror(rc));
     }
 #elif defined(USE_WIN32_IDN)
     char *ace_hostname = NULL;
@@ -3862,9 +4033,9 @@
  */
 static void free_fixed_hostname(struct hostname *host)
 {
-#if defined(USE_LIBIDN)
+#if defined(USE_LIBIDN2)
   if(host->encalloc) {
-    idn_free(host->encalloc); /* must be freed with idn_free() since this was
+    idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
                                  allocated by libidn */
     host->encalloc = NULL;
   }
@@ -3922,12 +4093,14 @@
   conn->data = data; /* Setup the association between this connection
                         and the Curl_easy */
 
-  conn->proxytype = data->set.proxytype; /* type */
+  conn->http_proxy.proxytype = data->set.proxytype;
+  conn->socks_proxy.proxytype = data->set.socks_proxytype;
 
 #ifdef CURL_DISABLE_PROXY
 
   conn->bits.proxy = FALSE;
   conn->bits.httpproxy = FALSE;
+  conn->bits.socksproxy = FALSE;
   conn->bits.proxy_user_passwd = FALSE;
   conn->bits.tunnel_proxy = FALSE;
 
@@ -3938,11 +4111,20 @@
   conn->bits.proxy = (data->set.str[STRING_PROXY] &&
                       *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
   conn->bits.httpproxy = (conn->bits.proxy &&
-                          (conn->proxytype == CURLPROXY_HTTP ||
-                           conn->proxytype == CURLPROXY_HTTP_1_0)) ?
-                          TRUE : FALSE;
-  conn->bits.proxy_user_passwd = (data->set.str[STRING_PROXYUSERNAME]) ?
-                                 TRUE : FALSE;
+                          (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
+                           conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
+                           conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
+                           TRUE : FALSE;
+  conn->bits.socksproxy = (conn->bits.proxy &&
+                           !conn->bits.httpproxy) ? TRUE : FALSE;
+
+  if(data->set.str[STRING_SOCKS_PROXY] && *data->set.str[STRING_SOCKS_PROXY]) {
+    conn->bits.proxy = TRUE;
+    conn->bits.socksproxy = TRUE;
+  }
+
+  conn->bits.proxy_user_passwd =
+    (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
 
 #endif /* CURL_DISABLE_PROXY */
@@ -3951,8 +4133,10 @@
   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
 
-  conn->verifypeer = data->set.ssl.verifypeer;
-  conn->verifyhost = data->set.ssl.verifyhost;
+  conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
+  conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+  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;
 
@@ -4022,7 +4206,7 @@
      variables based on the URL. Now that the handler may be changed later
      when the protocol specific setup function is called. */
   for(pp = protocols; (p = *pp) != NULL; pp++) {
-    if(Curl_raw_equal(p->scheme, protostr)) {
+    if(strcasecompare(p->scheme, protostr)) {
       /* Protocol found in table. Check if allowed */
       if(!(data->set.allowed_protocols & p->protocol))
         /* nope, get out */
@@ -4091,7 +4275,7 @@
    ************************************************************/
   if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
                   protobuf, path)) &&
-     Curl_raw_equal(protobuf, "file")) {
+     strcasecompare(protobuf, "file")) {
     if(path[0] == '/' && path[1] == '/') {
       /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
        * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
@@ -4108,33 +4292,38 @@
      * the URL protocols specified in RFC 1738
      */
     if(path[0] != '/') {
-      /* the URL included a host name, we ignore host names in file:// URLs
-         as the standards don't define what to do with them */
-      char *ptr=strchr(path, '/');
-      if(ptr) {
-        /* there was a slash present
-
-           RFC1738 (section 3.1, page 5) says:
-
-           The rest of the locator consists of data specific to the scheme,
-           and is known as the "url-path". It supplies the details of how the
-           specified resource can be accessed. Note that the "/" between the
-           host (or port) and the url-path is NOT part of the url-path.
-
-           As most agents use file://localhost/foo to get '/foo' although the
-           slash preceding foo is a separator and not a slash for the path,
-           a URL as file://localhost//foo must be valid as well, to refer to
-           the same file with an absolute path.
-        */
-
-        if(ptr[1] && ('/' == ptr[1]))
-          /* if there was two slashes, we skip the first one as that is then
-             used truly as a separator */
-          ptr++;
-
-        /* This cannot be made with strcpy, as the memory chunks overlap! */
-        memmove(path, ptr, strlen(ptr)+1);
+      /* the URL includes a host name, it must match "localhost" or
+         "127.0.0.1" to be valid */
+      char *ptr;
+      if(!checkprefix("localhost/", path) &&
+         !checkprefix("127.0.0.1/", path)) {
+        failf(data, "Valid host name with slash missing in URL");
+        return CURLE_URL_MALFORMAT;
       }
+      ptr = &path[9]; /* now points to the slash after the host */
+
+      /* there was a host name and slash present
+
+         RFC1738 (section 3.1, page 5) says:
+
+         The rest of the locator consists of data specific to the scheme,
+         and is known as the "url-path". It supplies the details of how the
+         specified resource can be accessed. Note that the "/" between the
+         host (or port) and the url-path is NOT part of the url-path.
+
+         As most agents use file://localhost/foo to get '/foo' although the
+         slash preceding foo is a separator and not a slash for the path,
+         a URL as file://localhost//foo must be valid as well, to refer to
+         the same file with an absolute path.
+      */
+
+      if('/' == ptr[1])
+        /* if there was two slashes, we skip the first one as that is then
+           used truly as a separator */
+        ptr++;
+
+      /* This cannot be made with strcpy, as the memory chunks overlap! */
+      memmove(path, ptr, strlen(ptr)+1);
     }
 
     protop = "file"; /* protocol string */
@@ -4145,7 +4334,7 @@
     path[0]=0;
 
     rc = sscanf(data->change.url,
-                "%15[^\n:]:%3[/]%[^\n/?]%[^\n]",
+                "%15[^\n:]:%3[/]%[^\n/?#]%[^\n]",
                 protobuf, slashbuf, conn->host.name, path);
     if(2 == rc) {
       failf(data, "Bad URL");
@@ -4157,7 +4346,7 @@
        * The URL was badly formatted, let's try the browser-style _without_
        * protocol specified like 'http://'.
        */
-      rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
+      rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
       if(1 > rc) {
         /*
          * We couldn't even get this format.
@@ -4262,10 +4451,10 @@
   }
 
   /* If the URL is malformatted (missing a '/' after hostname before path) we
-   * insert a slash here. The only letter except '/' we accept to start a path
-   * is '?'.
+   * insert a slash here. The only letters except '/' that can start a path is
+   * '?' and '#' - as controlled by the two sscanf() patterns above.
    */
-  if(path[0] == '?') {
+  if(path[0] != '/') {
     /* We need this function to deal with overlapping memory areas. We know
        that the memory area 'path' points to is 'urllen' bytes big and that
        is bigger than the path. Use +1 to move the zero byte too. */
@@ -4516,7 +4705,7 @@
 * Checks if the host is in the noproxy list. returns true if it matches
 * and therefore the proxy should NOT be used.
 ****************************************************************/
-static bool check_noproxy(const char* name, const char* no_proxy)
+static bool check_noproxy(const char *name, const char *no_proxy)
 {
   /* no_proxy=domain1.dom,host.domain2.dom
    *   (a comma-separated list of hosts which should
@@ -4525,13 +4714,13 @@
    */
   size_t tok_start;
   size_t tok_end;
-  const char* separator = ", ";
+  const char *separator = ", ";
   size_t no_proxy_len;
   size_t namelen;
   char *endptr;
 
   if(no_proxy && no_proxy[0]) {
-    if(Curl_raw_equal("*", no_proxy)) {
+    if(strcasecompare("*", no_proxy)) {
       return TRUE;
     }
 
@@ -4569,7 +4758,7 @@
       if((tok_end - tok_start) <= namelen) {
         /* Match the last part of the name to the domain we are checking. */
         const char *checkn = name + namelen - (tok_end - tok_start);
-        if(Curl_raw_nequal(no_proxy + tok_start, checkn,
+        if(strncasecompare(no_proxy + tok_start, checkn,
                            tok_end - tok_start)) {
           if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
             /* We either have an exact match, or the previous character is a .
@@ -4648,7 +4837,7 @@
      * This can cause 'internal' http/ftp requests to be
      * arbitrarily redirected by any external attacker.
      */
-    if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
+    if(!prox && !strcasecompare("http_proxy", proxy_env)) {
       /* There was no lowercase variable, try the uppercase version: */
       Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
       prox=curl_getenv(proxy_env);
@@ -4679,7 +4868,8 @@
  * that may exist registered to the same proxy host.
  */
 static CURLcode parse_proxy(struct Curl_easy *data,
-                            struct connectdata *conn, char *proxy)
+                            struct connectdata *conn, char *proxy,
+                            curl_proxytype proxytype)
 {
   char *prox_portno;
   char *endofprot;
@@ -4688,6 +4878,10 @@
   char *proxyptr;
   char *portptr;
   char *atsign;
+  long port = -1;
+  char *proxyuser = NULL;
+  char *proxypasswd = NULL;
+  bool sockstype;
 
   /* We do the proxy host string parsing here. We want the host name and the
    * port name. Accept a protocol:// prefix
@@ -4697,64 +4891,41 @@
   endofprot = strstr(proxy, "://");
   if(endofprot) {
     proxyptr = endofprot+3;
-    if(checkprefix("socks5h", proxy))
-      conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
+    if(checkprefix("https", proxy))
+      proxytype = CURLPROXY_HTTPS;
+    else if(checkprefix("socks5h", proxy))
+      proxytype = CURLPROXY_SOCKS5_HOSTNAME;
     else if(checkprefix("socks5", proxy))
-      conn->proxytype = CURLPROXY_SOCKS5;
+      proxytype = CURLPROXY_SOCKS5;
     else if(checkprefix("socks4a", proxy))
-      conn->proxytype = CURLPROXY_SOCKS4A;
+      proxytype = CURLPROXY_SOCKS4A;
     else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
-      conn->proxytype = CURLPROXY_SOCKS4;
-    /* Any other xxx:// : change to http proxy */
+      proxytype = CURLPROXY_SOCKS4;
+    else if(checkprefix("http:", proxy))
+      ; /* leave it as HTTP or HTTP/1.0 */
+    else {
+      /* Any other xxx:// reject! */
+      failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
+      return CURLE_COULDNT_CONNECT;
+    }
   }
   else
     proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
 
+  sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+              proxytype == CURLPROXY_SOCKS5 ||
+              proxytype == CURLPROXY_SOCKS4A ||
+              proxytype == CURLPROXY_SOCKS4;
+
   /* Is there a username and password given in this proxy url? */
   atsign = strchr(proxyptr, '@');
   if(atsign) {
-    char *proxyuser = NULL;
-    char *proxypasswd = NULL;
     CURLcode result =
       parse_login_details(proxyptr, atsign - proxyptr,
-                          &proxyuser, &proxypasswd, NULL);
-    if(!result) {
-      /* found user and password, rip them out.  note that we are
-         unescaping them, as there is otherwise no way to have a
-         username or password with reserved characters like ':' in
-         them. */
-      Curl_safefree(conn->proxyuser);
-      if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
-        conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
-      else
-        conn->proxyuser = strdup("");
-
-      if(!conn->proxyuser)
-        result = CURLE_OUT_OF_MEMORY;
-      else {
-        Curl_safefree(conn->proxypasswd);
-        if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
-          conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
-        else
-          conn->proxypasswd = strdup("");
-
-        if(!conn->proxypasswd)
-          result = CURLE_OUT_OF_MEMORY;
-      }
-
-      if(!result) {
-        conn->bits.proxy_user_passwd = TRUE; /* enable it */
-        atsign++; /* the right side of the @-letter */
-
-        proxyptr = atsign; /* now use this instead */
-      }
-    }
-
-    free(proxyuser);
-    free(proxypasswd);
-
+                              &proxyuser, &proxypasswd, NULL);
     if(result)
       return result;
+    proxyptr = atsign + 1;
   }
 
   /* start scanning for port number at this point */
@@ -4791,7 +4962,7 @@
   prox_portno = strchr(portptr, ':');
   if(prox_portno) {
     char *endp = NULL;
-    long port = 0;
+
     *prox_portno = 0x0; /* cut off number from host name */
     prox_portno ++;
     /* now set the local port number */
@@ -4825,15 +4996,53 @@
     if(data->set.proxyport)
       /* None given in the proxy string, then get the default one if it is
          given */
-      conn->port = data->set.proxyport;
+      port = data->set.proxyport;
   }
 
-  /* now, clone the cleaned proxy host name */
-  conn->proxy.rawalloc = strdup(proxyptr);
-  conn->proxy.name = conn->proxy.rawalloc;
+  if(*proxyptr) {
+    struct proxy_info *proxyinfo =
+      sockstype ? &conn->socks_proxy : &conn->http_proxy;
+    proxyinfo->proxytype = proxytype;
 
-  if(!conn->proxy.rawalloc)
-    return CURLE_OUT_OF_MEMORY;
+    if(proxyuser) {
+      /* found user and password, rip them out.  note that we are unescaping
+         them, as there is otherwise no way to have a username or password
+         with reserved characters like ':' in them. */
+      Curl_safefree(proxyinfo->user);
+      proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
+
+      if(!proxyinfo->user)
+        return CURLE_OUT_OF_MEMORY;
+
+      Curl_safefree(proxyinfo->passwd);
+      if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
+        proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+      else
+        proxyinfo->passwd = strdup("");
+
+      if(!proxyinfo->passwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      conn->bits.proxy_user_passwd = TRUE; /* enable it */
+    }
+
+    if(port >= 0) {
+      proxyinfo->port = port;
+      if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
+        conn->port = port;
+    }
+
+    /* now, clone the cleaned proxy host name */
+    Curl_safefree(proxyinfo->host.rawalloc);
+    proxyinfo->host.rawalloc = strdup(proxyptr);
+    proxyinfo->host.name = proxyinfo->host.rawalloc;
+
+    if(!proxyinfo->host.rawalloc)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_safefree(proxyuser);
+  Curl_safefree(proxypasswd);
 
   return CURLE_OK;
 }
@@ -4846,6 +5055,7 @@
 {
   char proxyuser[MAX_CURL_USER_LENGTH]="";
   char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
+  CURLcode result;
 
   if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
     strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
@@ -4858,15 +5068,12 @@
     proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
   }
 
-  conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
-  if(!conn->proxyuser)
-    return CURLE_OUT_OF_MEMORY;
-
-  conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
-  if(!conn->proxypasswd)
-    return CURLE_OUT_OF_MEMORY;
-
-  return CURLE_OK;
+  result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
+                          FALSE);
+  if(!result)
+    result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
+                            NULL, FALSE);
+  return result;
 }
 #endif /* CURL_DISABLE_PROXY */
 
@@ -4940,9 +5147,8 @@
     conn->bits.user_passwd = TRUE; /* enable user+password */
 
     /* Decode the user */
-    newname = curl_easy_unescape(data, userp, 0, NULL);
-    if(!newname) {
-      result = CURLE_OUT_OF_MEMORY;
+    result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
+    if(result) {
       goto out;
     }
 
@@ -4952,9 +5158,9 @@
 
   if(passwdp) {
     /* We have a password in the URL so decode it */
-    char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
-    if(!newpasswd) {
-      result = CURLE_OUT_OF_MEMORY;
+    char *newpasswd;
+    result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
+    if(result) {
       goto out;
     }
 
@@ -4964,9 +5170,9 @@
 
   if(optionsp) {
     /* We have an options list in the URL so decode it */
-    char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
-    if(!newoptions) {
-      result = CURLE_OUT_OF_MEMORY;
+    char *newoptions;
+    result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
+    if(result) {
       goto out;
     }
 
@@ -5457,7 +5663,8 @@
     if(!hostname_to_match)
       return CURLE_OUT_OF_MEMORY;
     hostname_to_match_len = strlen(hostname_to_match);
-    host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len);
+    host_match = strncasecompare(ptr, hostname_to_match,
+                                 hostname_to_match_len);
     free(hostname_to_match);
     ptr += hostname_to_match_len;
 
@@ -5551,7 +5758,7 @@
                                bool *async)
 {
   CURLcode result=CURLE_OK;
-  long timeout_ms = Curl_timeleft(data, NULL, TRUE);
+  time_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
   /*************************************************************
    * Resolve the name of the server or proxy
@@ -5568,11 +5775,11 @@
     struct Curl_dns_entry *hostaddr;
 
 #ifdef USE_UNIX_SOCKETS
-    if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+    if(conn->unix_domain_socket) {
       /* Unix domain sockets are local. The host gets ignored, just use the
        * specified domain socket address. Do not cache "DNS entries". There is
        * no DNS involved and we already have the filesystem path available */
-      const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
+      const char *path = conn->unix_domain_socket;
 
       hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
       if(!hostaddr)
@@ -5593,7 +5800,7 @@
     }
     else
 #endif
-    if(!conn->proxy.name || !*conn->proxy.name) {
+    if(!conn->bits.proxy) {
       struct hostname *connhost;
       if(conn->bits.conn_to_host)
         connhost = &conn->conn_to_host;
@@ -5625,8 +5832,11 @@
     else {
       /* This is a proxy that hasn't been resolved yet. */
 
+      struct hostname * const host = conn->bits.socksproxy ?
+        &conn->socks_proxy.host : &conn->http_proxy.host;
+
       /* resolve proxy */
-      rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
+      rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
                                &hostaddr, timeout_ms);
 
       if(rc == CURLRESOLV_PENDING)
@@ -5636,7 +5846,7 @@
         result = CURLE_OPERATION_TIMEDOUT;
 
       else if(!hostaddr) {
-        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
+        failf(data, "Couldn't resolve proxy '%s'", host->dispname);
         result = CURLE_COULDNT_RESOLVE_PROXY;
         /* don't return yet, we need to clean up the timeout first */
       }
@@ -5656,12 +5866,18 @@
 static void reuse_conn(struct connectdata *old_conn,
                        struct connectdata *conn)
 {
+  free_fixed_hostname(&old_conn->http_proxy.host);
+  free_fixed_hostname(&old_conn->socks_proxy.host);
   free_fixed_hostname(&old_conn->proxy);
+
+  free(old_conn->http_proxy.host.rawalloc);
+  free(old_conn->socks_proxy.host.rawalloc);
   free(old_conn->proxy.rawalloc);
 
   /* free the SSL config struct from this connection struct as this was
      allocated in vain and is targeted for destruction */
-  Curl_free_ssl_config(&old_conn->ssl_config);
+  Curl_free_primary_ssl_config(&old_conn->ssl_config);
+  Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
 
   conn->data = old_conn->data;
 
@@ -5681,12 +5897,18 @@
   conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
   if(conn->bits.proxy_user_passwd) {
     /* use the new proxy user name and proxy password though */
-    Curl_safefree(conn->proxyuser);
-    Curl_safefree(conn->proxypasswd);
-    conn->proxyuser = old_conn->proxyuser;
-    conn->proxypasswd = old_conn->proxypasswd;
-    old_conn->proxyuser = NULL;
-    old_conn->proxypasswd = NULL;
+    Curl_safefree(conn->http_proxy.user);
+    Curl_safefree(conn->socks_proxy.user);
+    Curl_safefree(conn->http_proxy.passwd);
+    Curl_safefree(conn->socks_proxy.passwd);
+    conn->http_proxy.user = old_conn->http_proxy.user;
+    conn->socks_proxy.user = old_conn->socks_proxy.user;
+    conn->http_proxy.passwd = old_conn->http_proxy.passwd;
+    conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
+    old_conn->http_proxy.user = NULL;
+    old_conn->socks_proxy.user = NULL;
+    old_conn->http_proxy.passwd = NULL;
+    old_conn->socks_proxy.passwd = NULL;
   }
 
   /* host can change, when doing keepalive with a proxy or if the case is
@@ -5712,8 +5934,10 @@
 
   Curl_safefree(old_conn->user);
   Curl_safefree(old_conn->passwd);
-  Curl_safefree(old_conn->proxyuser);
-  Curl_safefree(old_conn->proxypasswd);
+  Curl_safefree(old_conn->http_proxy.user);
+  Curl_safefree(old_conn->socks_proxy.user);
+  Curl_safefree(old_conn->http_proxy.passwd);
+  Curl_safefree(old_conn->socks_proxy.passwd);
   Curl_safefree(old_conn->localdev);
 
   Curl_llist_destroy(old_conn->send_pipe, NULL);
@@ -5723,6 +5947,10 @@
   old_conn->recv_pipe = NULL;
 
   Curl_safefree(old_conn->master_buffer);
+
+#ifdef USE_UNIX_SOCKETS
+  Curl_safefree(old_conn->unix_domain_socket);
+#endif
 }
 
 /**
@@ -5754,6 +5982,7 @@
   char *options = NULL;
   bool reuse;
   char *proxy = NULL;
+  char *socksproxy = NULL;
   bool prot_missing = FALSE;
   bool connections_available = TRUE;
   bool force_reuse = FALSE;
@@ -5920,18 +6149,35 @@
     }
   }
 
+  if(data->set.str[STRING_SOCKS_PROXY]) {
+    socksproxy = strdup(data->set.str[STRING_SOCKS_PROXY]);
+    /* if global socks proxy is set, this is it */
+    if(NULL == socksproxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
   if(data->set.str[STRING_NOPROXY] &&
      check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
-    free(proxy);  /* proxy is in exception list */
-    proxy = NULL;
+    Curl_safefree(proxy);
+    Curl_safefree(socksproxy);
   }
-  else if(!proxy)
+  else if(!proxy && !socksproxy)
     proxy = detect_proxy(conn);
 
 #ifdef USE_UNIX_SOCKETS
-  if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
-    free(proxy);  /* Unix domain sockets cannot be proxied, so disable it */
-    proxy = NULL;
+  if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+    if(proxy) {
+      free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
+      proxy = NULL;
+    }
+    conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
+    if(conn->unix_domain_socket == NULL) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
   }
 #endif
 
@@ -5940,23 +6186,36 @@
                      protocol doesn't work with network */
     proxy = NULL;
   }
+  if(socksproxy && (!*socksproxy ||
+                    (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(socksproxy);  /* Don't bother with an empty socks proxy string or if
+                          the protocol doesn't work with network */
+    socksproxy = NULL;
+  }
 
   /***********************************************************************
    * If this is supposed to use a proxy, we need to figure out the proxy host
    * name, proxy type and port number, so that we can re-use an existing
    * connection that may exist registered to the same proxy host.
    ***********************************************************************/
-  if(proxy) {
-    result = parse_proxy(data, conn, proxy);
+  if(proxy || socksproxy) {
+    if(proxy) {
+      result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
+      Curl_safefree(proxy); /* parse_proxy copies the proxy string */
+      if(result)
+        goto out;
+    }
 
-    free(proxy); /* parse_proxy copies the proxy string */
-    proxy = NULL;
+    if(socksproxy) {
+      result = parse_proxy(data, conn, socksproxy,
+                           conn->socks_proxy.proxytype);
+      /* parse_proxy copies the socks proxy string */
+      Curl_safefree(socksproxy);
+      if(result)
+        goto out;
+    }
 
-    if(result)
-      goto out;
-
-    if((conn->proxytype == CURLPROXY_HTTP) ||
-       (conn->proxytype == CURLPROXY_HTTP_1_0)) {
+    if(conn->http_proxy.host.rawalloc) {
 #ifdef CURL_DISABLE_HTTP
       /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
       result = CURLE_UNSUPPORTED_PROTOCOL;
@@ -5975,12 +6234,34 @@
       conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
       conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
     }
-    conn->bits.proxy = TRUE;
+
+    if(conn->socks_proxy.host.rawalloc) {
+      if(!conn->http_proxy.host.rawalloc) {
+        /* once a socks proxy */
+        if(!conn->socks_proxy.user) {
+          conn->socks_proxy.user = conn->http_proxy.user;
+          conn->http_proxy.user = NULL;
+          Curl_safefree(conn->socks_proxy.passwd);
+          conn->socks_proxy.passwd = conn->http_proxy.passwd;
+          conn->http_proxy.passwd = NULL;
+        }
+      }
+      conn->bits.socksproxy = TRUE;
+    }
+    else
+      conn->bits.socksproxy = FALSE; /* not a socks proxy */
   }
   else {
+    conn->bits.socksproxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+  }
+  conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
+
+  if(!conn->bits.proxy) {
     /* we aren't using the proxy after all... */
     conn->bits.proxy = FALSE;
     conn->bits.httpproxy = FALSE;
+    conn->bits.socksproxy = FALSE;
     conn->bits.proxy_user_passwd = FALSE;
     conn->bits.tunnel_proxy = FALSE;
   }
@@ -6021,18 +6302,18 @@
   /*************************************************************
    * IDN-fix the hostnames
    *************************************************************/
-  fix_hostname(data, conn, &conn->host);
+  fix_hostname(conn, &conn->host);
   if(conn->bits.conn_to_host)
-    fix_hostname(data, conn, &conn->conn_to_host);
+    fix_hostname(conn, &conn->conn_to_host);
   if(conn->proxy.name && *conn->proxy.name)
-    fix_hostname(data, conn, &conn->proxy);
+    fix_hostname(conn, &conn->proxy);
 
   /*************************************************************
    * Check whether the host and the "connect to host" are equal.
    * Do this after the hostnames have been IDN-fixed .
    *************************************************************/
   if(conn->bits.conn_to_host &&
-      Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) {
+     strcasecompare(conn->conn_to_host.name, conn->host.name)) {
     conn->bits.conn_to_host = FALSE;
   }
 
@@ -6116,20 +6397,51 @@
      that will be freed as part of the Curl_easy struct, but all cloned
      copies will be separately allocated.
   */
-  data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
-  data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
-  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
-  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
-  data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
-  data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
-  data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
-  data->set.ssl.clientcert = data->set.str[STRING_CERT];
+  data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
+  data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
+  data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
+  data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+  data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.proxy_ssl.primary.random_file =
+    data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.ssl.primary.cipher_list =
+    data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
+  data->set.proxy_ssl.primary.cipher_list =
+    data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
+
+  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+  data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
+  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+  data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
+  data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
+  data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
+  data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
+  data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
+  data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
+  data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
+  data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
+  data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
+  data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
+  data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
+  data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
+  data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
 #ifdef USE_TLS_SRP
-  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
-  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
+  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
+  data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
+  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
+  data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
 #endif
 
-  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
+  if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
+     &conn->ssl_config)) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
+                                    &conn->proxy_ssl_config)) {
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
@@ -6186,7 +6498,9 @@
     infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
           conn->connection_id,
           conn->bits.proxy?"proxy":"host",
-          conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
+          conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
+          conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
+                                       conn->host.dispname);
   }
   else {
     /* We have decided that we want a new connection. However, we may not
@@ -6317,6 +6631,7 @@
   free(options);
   free(passwd);
   free(user);
+  free(socksproxy);
   free(proxy);
   return result;
 }
diff --git a/lib/url.h b/lib/url.h
index 90d9db3..c1254f5 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -76,5 +76,16 @@
 void Curl_verboseconnect(struct connectdata *conn);
 #endif
 
+#define CONNECT_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[sockindex])
+
+#define CONNECT_FIRSTSOCKET_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[FIRSTSOCKET])
+
+#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
 
 #endif /* HEADER_CURL_URL_H */
diff --git a/lib/urldata.h b/lib/urldata.h
index 3cf7ed9..05f6003 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -316,6 +316,8 @@
 #elif defined(USE_GSKIT)
   gsk_handle handle;
   int iocport;
+  int localfd;
+  int remotefd;
 #elif defined(USE_AXTLS)
   SSL_CTX* ssl_ctx;
   SSL*     ssl;
@@ -330,6 +332,7 @@
   CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
   bool recv_sspi_close_notify; /* true if connection closed by close_notify */
   bool recv_connection_closed; /* true if connection closed, regardless how */
+  bool use_alpn; /* true if ALPN is used for this connection */
 #elif defined(USE_DARWINSSL)
   SSLContextRef ssl_ctx;
   curl_socket_t ssl_sockfd;
@@ -340,28 +343,38 @@
 #endif
 };
 
-struct ssl_config_data {
+struct ssl_primary_config {
   long version;          /* what version the client wants to use */
-  long certverifyresult; /* result from the certificate verification */
-
   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 */
   char *CApath;          /* certificate dir (doesn't work on windows) */
   char *CAfile;          /* certificate to verify peer against */
-  const char *CRLfile;   /* CRL to check certificate revocation */
-  const char *issuercert;/* optional issuer certificate filename */
   char *clientcert;
   char *random_file;     /* path to file containing "random" data */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
-  size_t max_ssl_sessions; /* SSL session id cache size */
+};
+
+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 sessionid;        /* cache session IDs or not */
   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) */
@@ -369,16 +382,22 @@
 #endif
 };
 
+struct ssl_general_config {
+  bool sessionid; /* cache session IDs or not */
+  size_t max_ssl_sessions; /* SSL session id cache size */
+};
+
 /* information stored about one single SSL session */
 struct curl_ssl_session {
   char *name;       /* host name for which this ID was used */
   char *conn_to_host; /* host name for the connection (may be NULL) */
+  const char *scheme; /* protocol scheme used */
   void *sessionid;  /* as returned from the SSL layer */
   size_t idsize;    /* if known, otherwise 0 */
   long age;         /* just a number, the higher the more recent */
   int remote_port;  /* remote port */
   int conn_to_port; /* remote port for the connection (may be -1) */
-  struct ssl_config_data ssl_config; /* setup for this session */
+  struct ssl_primary_config ssl_config; /* setup for this session */
 };
 
 /* Struct used for Digest challenge-response authentication */
@@ -449,7 +468,7 @@
 #else
   unsigned int flags;
   unsigned char nonce[8];
-  void* target_info; /* TargetInfo received in the ntlm type-2 message */
+  void *target_info; /* TargetInfo received in the ntlm type-2 message */
   unsigned int target_info_len;
 #endif
 };
@@ -495,6 +514,7 @@
                         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
@@ -529,6 +549,7 @@
   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
@@ -545,6 +566,9 @@
   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 */
 };
 
 struct hostname {
@@ -730,7 +754,7 @@
  */
 
 struct Curl_handler {
-  const char * scheme;        /* URL scheme name. */
+  const char *scheme;        /* URL scheme name. */
 
   /* Complement to setup_connection_internals(). */
   CURLcode (*setup_connection)(struct connectdata *);
@@ -817,6 +841,7 @@
 #define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
                                           request instead of per connection */
 #define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
+#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
 
 /* return the count of bytes sent, or -1 on error */
 typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
@@ -846,6 +871,14 @@
 };
 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
 
+struct proxy_info {
+  struct hostname host;
+  long port;
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+  char *user;    /* proxy user name string, allocated */
+  char *passwd;  /* proxy password string, allocated */
+};
+
 /*
  * The connectdata struct contains all fields and variables that should be
  * unique for an entire connection.
@@ -895,14 +928,20 @@
   int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
 
   struct hostname host;
+  char *secondaryhostname; /* secondary socket host name (ftp) */
   struct hostname conn_to_host; /* the host to connect to. valid only if
                                    bits.conn_to_host is set */
   struct hostname proxy;
 
+  struct proxy_info socks_proxy;
+  struct proxy_info http_proxy;
+
   long port;       /* which port to use locally */
   int remote_port; /* the remote port, not the proxy port! */
   int conn_to_port; /* the remote port to connect to. valid only if
                        bits.conn_to_port is set */
+  unsigned short secondary_port; /* secondary socket remote port to connect to
+                                    (ftp) */
 
   /* 'primary_ip' and 'primary_port' get filled with peer's numerical
      ip address and port number whenever an outgoing connection is
@@ -927,10 +966,6 @@
 
   char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
 
-  char *proxyuser;    /* proxy user name string, allocated */
-  char *proxypasswd;  /* proxy password string, allocated */
-  curl_proxytype proxytype; /* what kind of proxy that is in use */
-
   int httpversion;        /* the HTTP version*10 reported by the server */
   int rtspversion;        /* the RTSP version*10 reported by the server */
 
@@ -948,7 +983,9 @@
   struct postponed_data postponed[2]; /* two buffers for two sockets */
 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
   struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
-  struct ssl_config_data ssl_config;
+  struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
+  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 */
@@ -959,8 +996,8 @@
   struct timeval connecttime;
   /* The two fields below get set in Curl_connecthost */
   int num_addr; /* number of addresses to try to connect to */
-  long timeoutms_per_addr; /* how long time in milliseconds to spend on
-                              trying to connect to each IP address */
+  time_t timeoutms_per_addr; /* how long time in milliseconds to spend on
+                                trying to connect to each IP address */
 
   const struct Curl_handler *handler; /* Connection's protocol handler */
   const struct Curl_handler *given;   /* The protocol first given */
@@ -1017,7 +1054,7 @@
                                    send on this pipeline */
   struct curl_llist *recv_pipe; /* List of handles waiting to read
                                    their responses on this pipeline */
-  char* master_buffer; /* The master buffer allocated on-demand;
+  char *master_buffer; /* The master buffer allocated on-demand;
                           used for pipelining. */
   size_t read_pos; /* Current read position in the master buffer */
   size_t buf_len; /* Length of the buffer?? */
@@ -1038,8 +1075,8 @@
   /* used for communication with Samba's winbind daemon helper ntlm_auth */
   curl_socket_t ntlm_auth_hlpr_socket;
   pid_t ntlm_auth_hlpr_pid;
-  char* challenge_header;
-  char* response_header;
+  char *challenge_header;
+  char *response_header;
 #endif
 #endif
 
@@ -1075,9 +1112,6 @@
   int socks5_gssapi_enctype;
 #endif
 
-  bool verifypeer;
-  bool verifyhost;
-
   /* When this connection is created, store the conditions for the local end
      bind. This is stored before the actual bind and before any connection is
      made and will serve the purpose of being used for comparison reasons so
@@ -1096,15 +1130,20 @@
   struct connectbundle *bundle; /* The bundle we are member of */
 
   int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
+
+#ifdef USE_UNIX_SOCKETS
+  char *unix_domain_socket;
+#endif
 };
 
 /* The end of connectdata. */
 
 /*
  * Struct to keep statistical and informational data.
+ * All variables in this struct must be initialized/reset in Curl_initinfo().
  */
 struct PureInfo {
-  int httpcode;  /* Recent HTTP, FTP, or RTSP response code */
+  int httpcode;  /* Recent HTTP, FTP, RTSP or SMTP response code */
   int httpproxycode; /* response code from proxy when received separate */
   int httpversion; /* the http version number X.Y = X*10+Y */
   long filetime; /* If requested, this is might get set. Set to -1 if the time
@@ -1135,6 +1174,9 @@
   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 */
@@ -1142,8 +1184,8 @@
 
 
 struct Progress {
-  long lastshow; /* time() of the last displayed progress meter or NULL to
-                    force redraw at next call */
+  time_t lastshow; /* time() of the last displayed progress meter or NULL to
+                      force redraw at next call */
   curl_off_t size_dl; /* total expected size */
   curl_off_t size_ul; /* total expected size */
   curl_off_t downloaded; /* transferred so far */
@@ -1171,6 +1213,14 @@
   struct timeval t_startsingle;
   struct timeval t_startop;
   struct timeval t_acceptdata;
+
+  /* upload speed limit */
+  struct timeval ul_limit_start;
+  curl_off_t ul_limit_size;
+  /* download speed limit */
+  struct timeval dl_limit_start;
+  curl_off_t dl_limit_size;
+
 #define CURR_TIME (5+1) /* 6 entries for 5 seconds */
 
   curl_off_t speeder[ CURR_TIME ];
@@ -1390,8 +1440,10 @@
 struct Curl_multi;    /* declared and used only in multi.c */
 
 enum dupstring {
-  STRING_CERT,            /* client certificate file name */
-  STRING_CERT_TYPE,       /* format for certificate (default: PEM)*/
+  STRING_CERT_ORIG,       /* client certificate file name */
+  STRING_CERT_PROXY,      /* client certificate file name */
+  STRING_CERT_TYPE_ORIG,  /* format for certificate (default: PEM)*/
+  STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/
   STRING_COOKIE,          /* HTTP cookie string to send */
   STRING_COOKIEJAR,       /* dump all cookies to this file */
   STRING_CUSTOMREQUEST,   /* HTTP/FTP/RTSP request/method to use */
@@ -1401,25 +1453,34 @@
   STRING_FTP_ACCOUNT,     /* ftp account data */
   STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
   STRING_FTPPORT,         /* port to send with the FTP PORT command */
-  STRING_KEY,             /* private key file name */
-  STRING_KEY_PASSWD,      /* plain text private key password */
-  STRING_KEY_TYPE,        /* format for private key (default: PEM) */
+  STRING_KEY_ORIG,        /* private key file name */
+  STRING_KEY_PROXY,       /* private key file name */
+  STRING_KEY_PASSWD_ORIG, /* plain text private key password */
+  STRING_KEY_PASSWD_PROXY, /* plain text private key password */
+  STRING_KEY_TYPE_ORIG,   /* format for private key (default: PEM) */
+  STRING_KEY_TYPE_PROXY,  /* format for private key (default: PEM) */
   STRING_KRB_LEVEL,       /* krb security level */
   STRING_NETRC_FILE,      /* if not NULL, use this instead of trying to find
                              $HOME/.netrc */
   STRING_PROXY,           /* proxy to use */
+  STRING_SOCKS_PROXY,     /* socks proxy to use */
   STRING_SET_RANGE,       /* range, if used */
   STRING_SET_REFERER,     /* custom string for the HTTP referer field */
   STRING_SET_URL,         /* what original URL to work on */
-  STRING_SSL_CAPATH,      /* CA directory name (doesn't work on windows) */
-  STRING_SSL_CAFILE,      /* certificate file to verify peer against */
+  STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */
+  STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */
+  STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */
+  STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */
   STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
-  STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
+  STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
+  STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
   STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
   STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
   STRING_USERAGENT,       /* User-Agent string */
-  STRING_SSL_CRLFILE,     /* crl file to check certificate */
-  STRING_SSL_ISSUERCERT,  /* issuer cert file to check certificate */
+  STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */
+  STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
+  STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
+  STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
   STRING_USERNAME,        /* <username>, if used */
   STRING_PASSWORD,        /* <password>, if used */
   STRING_OPTIONS,         /* <options>, if used */
@@ -1447,8 +1508,10 @@
   STRING_MAIL_AUTH,
 
 #ifdef USE_TLS_SRP
-  STRING_TLSAUTH_USERNAME,      /* TLS auth <username> */
-  STRING_TLSAUTH_PASSWORD,      /* TLS auth <password> */
+  STRING_TLSAUTH_USERNAME_ORIG,  /* TLS auth <username> */
+  STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
+  STRING_TLSAUTH_PASSWORD_ORIG,  /* TLS auth <password> */
+  STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
 #endif
   STRING_BEARER,                /* <bearer>, if used */
 #ifdef USE_UNIX_SOCKETS
@@ -1512,10 +1575,10 @@
   curl_opensocket_callback fopensocket; /* function for checking/translating
                                            the address and opening the
                                            socket */
-  void* opensocket_client;
+  void *opensocket_client;
   curl_closesocket_callback fclosesocket; /* function for closing the
                                              socket */
-  void* closesocket_client;
+  void *closesocket_client;
 
   void *seek_client;    /* pointer to pass to the seek callback */
   /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
@@ -1566,7 +1629,10 @@
   long httpversion; /* when non-zero, a specific HTTP version requested to
                        be used in the library's request(s) */
   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 */
   curl_proxytype proxytype; /* what kind of proxy that is in use */
+  curl_proxytype socks_proxytype; /* what kind of socks proxy that is in use */
   long dns_cache_timeout; /* DNS cache timeout */
   long buffer_size;      /* size of receive buffer to use */
   void *private_data; /* application-private data */
@@ -1600,6 +1666,7 @@
   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 http_disable_hostname_check_before_authentication;
@@ -1629,9 +1696,6 @@
   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 */
-  bool ssl_enable_beast; /* especially allow this flaw for interoperability's
-                            sake*/
-  bool ssl_no_revoke;    /* disable SSL certificate revocation checks */
   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) */
diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c
index 4e906bc..a761ae7 100644
--- a/lib/vauth/cleartext.c
+++ b/lib/vauth/cleartext.c
@@ -33,8 +33,6 @@
 #include "curl_md5.h"
 #include "warnless.h"
 #include "strtok.h"
-#include "strequal.h"
-#include "rawstr.h"
 #include "sendf.h"
 #include "curl_printf.h"
 
@@ -68,16 +66,27 @@
   char *plainauth;
   size_t ulen;
   size_t plen;
+  size_t plainlen;
 
+  *outlen = 0;
+  *outptr = NULL;
   ulen = strlen(userp);
   plen = strlen(passwdp);
 
-  plainauth = malloc(2 * ulen + plen + 2);
-  if(!plainauth) {
-    *outlen = 0;
-    *outptr = NULL;
+  /* Compute binary message length, checking for overflows. */
+  plainlen = 2 * ulen;
+  if(plainlen < ulen)
     return CURLE_OUT_OF_MEMORY;
-  }
+  plainlen += plen;
+  if(plainlen < plen)
+    return CURLE_OUT_OF_MEMORY;
+  plainlen += 2;
+  if(plainlen < 2)
+    return CURLE_OUT_OF_MEMORY;
+
+  plainauth = malloc(plainlen);
+  if(!plainauth)
+    return CURLE_OUT_OF_MEMORY;
 
   /* Calculate the reply */
   memcpy(plainauth, userp, ulen);
@@ -87,8 +96,7 @@
   memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
 
   /* Base64 encode the reply */
-  result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
-                              outlen);
+  result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen);
   free(plainauth);
 
   return result;
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index 26ea7b5..7d9200a 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -37,9 +37,10 @@
 #include "vtls/vtls.h"
 #include "warnless.h"
 #include "strtok.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "non-ascii.h" /* included for Curl_convert_... prototypes */
 #include "curl_printf.h"
+#include "rand.h"
 
 /* The last #include files should be: */
 #include "curl_memory.h"
@@ -59,7 +60,7 @@
    what ultimately goes over the network.
 */
 #define CURL_OUTPUT_DIGEST_CONV(a, b) \
-  result = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+  result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \
   if(result) { \
     free(b); \
     return result; \
@@ -217,11 +218,11 @@
 
   token = strtok_r(tmp, ",", &tok_buf);
   while(token != NULL) {
-    if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH))
+    if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
       *value |= DIGEST_QOP_VALUE_AUTH;
-    else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
+    else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
       *value |= DIGEST_QOP_VALUE_AUTH_INT;
-    else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
+    else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
       *value |= DIGEST_QOP_VALUE_AUTH_CONF;
 
     token = strtok_r(NULL, ",", &tok_buf);
@@ -306,6 +307,20 @@
 }
 
 /*
+ * Curl_auth_is_digest_supported()
+ *
+ * This is used to evaluate if DIGEST is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE as DIGEST as handled by libcurl.
+ */
+bool Curl_auth_is_digest_supported(void)
+{
+  return TRUE;
+}
+
+/*
  * Curl_auth_create_digest_md5_message()
  *
  * This is used to generate an already encoded DIGEST-MD5 response message
@@ -373,10 +388,9 @@
     return CURLE_BAD_CONTENT_ENCODING;
 
   /* Generate 16 bytes of random data */
-  entropy[0] = Curl_rand(data);
-  entropy[1] = Curl_rand(data);
-  entropy[2] = Curl_rand(data);
-  entropy[3] = Curl_rand(data);
+  result = Curl_rand(data, &entropy[0], 4);
+  if(result)
+    return result;
 
   /* Convert the random data into a 32 byte hex string */
   snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x",
@@ -524,31 +538,31 @@
 
     /* Extract a value=content pair */
     if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) {
-      if(Curl_raw_equal(value, "nonce")) {
+      if(strcasecompare(value, "nonce")) {
         free(digest->nonce);
         digest->nonce = strdup(content);
         if(!digest->nonce)
           return CURLE_OUT_OF_MEMORY;
       }
-      else if(Curl_raw_equal(value, "stale")) {
-        if(Curl_raw_equal(content, "true")) {
+      else if(strcasecompare(value, "stale")) {
+        if(strcasecompare(content, "true")) {
           digest->stale = TRUE;
           digest->nc = 1; /* we make a new nonce now */
         }
       }
-      else if(Curl_raw_equal(value, "realm")) {
+      else if(strcasecompare(value, "realm")) {
         free(digest->realm);
         digest->realm = strdup(content);
         if(!digest->realm)
           return CURLE_OUT_OF_MEMORY;
       }
-      else if(Curl_raw_equal(value, "opaque")) {
+      else if(strcasecompare(value, "opaque")) {
         free(digest->opaque);
         digest->opaque = strdup(content);
         if(!digest->opaque)
           return CURLE_OUT_OF_MEMORY;
       }
-      else if(Curl_raw_equal(value, "qop")) {
+      else if(strcasecompare(value, "qop")) {
         char *tok_buf;
         /* Tokenize the list and choose auth if possible, use a temporary
            clone of the buffer since strtok_r() ruins it */
@@ -558,10 +572,10 @@
 
         token = strtok_r(tmp, ",", &tok_buf);
         while(token != NULL) {
-          if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
+          if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
             foundAuth = TRUE;
           }
-          else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
+          else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
             foundAuthInt = TRUE;
           }
           token = strtok_r(NULL, ",", &tok_buf);
@@ -583,15 +597,15 @@
             return CURLE_OUT_OF_MEMORY;
         }
       }
-      else if(Curl_raw_equal(value, "algorithm")) {
+      else if(strcasecompare(value, "algorithm")) {
         free(digest->algorithm);
         digest->algorithm = strdup(content);
         if(!digest->algorithm)
           return CURLE_OUT_OF_MEMORY;
 
-        if(Curl_raw_equal(content, "MD5-sess"))
+        if(strcasecompare(content, "MD5-sess"))
           digest->algo = CURLDIGESTALGO_MD5SESS;
-        else if(Curl_raw_equal(content, "MD5"))
+        else if(strcasecompare(content, "MD5"))
           digest->algo = CURLDIGESTALGO_MD5;
         else
           return CURLE_BAD_CONTENT_ENCODING;
@@ -670,9 +684,12 @@
     digest->nc = 1;
 
   if(!digest->cnonce) {
+    unsigned int rnd[4];
+    result = Curl_rand(data, &rnd[0], 4);
+    if(result)
+      return result;
     snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
-             Curl_rand(data), Curl_rand(data),
-             Curl_rand(data), Curl_rand(data));
+             rnd[0], rnd[1], rnd[2], rnd[3]);
 
     result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
                                 &cnonce, &cnonce_sz);
@@ -730,7 +747,7 @@
 
   md5this = (unsigned char *) aprintf("%s:%s", request, uripath);
 
-  if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) {
+  if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
     /* We don't support auth-int for PUT or POST at the moment.
        TODO: replace md5 of empty string with entity-body for PUT/POST */
     unsigned char *md5this2 = (unsigned char *)
@@ -806,7 +823,7 @@
                        digest->qop,
                        request_digest);
 
-    if(Curl_raw_equal(digest->qop, "auth"))
+    if(strcasecompare(digest->qop, "auth"))
       digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
                        padded which tells to the server how many times you are
                        using the same nonce in the qop=auth mode */
diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c
index 6a7315e..b9ceb12 100644
--- a/lib/vauth/digest_sspi.c
+++ b/lib/vauth/digest_sspi.c
@@ -37,13 +37,34 @@
 #include "curl_multibyte.h"
 #include "sendf.h"
 #include "strdup.h"
-#include "rawstr.h"
+#include "strcase.h"
 
 /* The last #include files should be: */
 #include "curl_memory.h"
 #include "memdebug.h"
 
 /*
+* Curl_auth_is_digest_supported()
+*
+* This is used to evaluate if DIGEST is supported.
+*
+* Parameters: None
+*
+* Returns TRUE if DIGEST is supported by Windows SSPI.
+*/
+bool Curl_auth_is_digest_supported(void)
+{
+  PSecPkgInfo SecurityPackage;
+  SECURITY_STATUS status;
+
+  /* Query the security package for Digest */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              &SecurityPackage);
+
+  return (status == SEC_E_OK ? TRUE : FALSE);
+}
+
+/*
  * Curl_auth_create_digest_md5_message()
  *
  * This is used to generate an already encoded DIGEST-MD5 response message
@@ -256,7 +277,7 @@
 
       /* Extract a value=content pair */
       if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) {
-        if(Curl_raw_equal(value, "realm")) {
+        if(strcasecompare(value, "realm")) {
 
           /* Setup identity's domain and length */
           domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content);
@@ -393,7 +414,7 @@
       return CURLE_OUT_OF_MEMORY;
 
     /* Populate our identity domain */
-    if(Curl_override_sspi_http_realm((const char*) digest->input_token,
+    if(Curl_override_sspi_http_realm((const char *) digest->input_token,
                                      &identity))
       return CURLE_OUT_OF_MEMORY;
 
diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c
index 31c8c7d..c754fae 100644
--- a/lib/vauth/krb5_gssapi.c
+++ b/lib/vauth/krb5_gssapi.c
@@ -42,6 +42,20 @@
 #include "memdebug.h"
 
 /*
+ * Curl_auth_is_gssapi_supported()
+ *
+ * This is used to evaluate if GSSAPI (Kerberos V5) is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE if Kerberos V5 is supported by the GSS-API library.
+ */
+bool Curl_auth_is_gssapi_supported(void)
+{
+  return TRUE;
+}
+
+/*
  * Curl_auth_create_gssapi_user_message()
  *
  * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index 08774f6..151794e 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -40,6 +40,28 @@
 #include "memdebug.h"
 
 /*
+ * Curl_auth_is_gssapi_supported()
+ *
+ * This is used to evaluate if GSSAPI (Kerberos V5) is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE if Kerberos V5 is supported by Windows SSPI.
+ */
+bool Curl_auth_is_gssapi_supported(void)
+{
+  PSecPkgInfo SecurityPackage;
+  SECURITY_STATUS status;
+
+  /* Query the security package for Kerberos */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                              TEXT(SP_NAME_KERBEROS),
+                                              &SecurityPackage);
+
+  return (status == SEC_E_OK ? TRUE : FALSE);
+}
+
+/*
  * Curl_auth_create_gssapi_user_message()
  *
  * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index c85fe42..b4d345d 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -41,7 +41,7 @@
 #include "curl_gethostname.h"
 #include "curl_multibyte.h"
 #include "warnless.h"
-
+#include "rand.h"
 #include "vtls/vtls.h"
 
 #ifdef USE_NSS
@@ -217,6 +217,20 @@
 */
 
 /*
+ * Curl_auth_is_ntlm_supported()
+ *
+ * This is used to evaluate if NTLM is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE as NTLM as handled by libcurl.
+ */
+bool Curl_auth_is_ntlm_supported(void)
+{
+  return TRUE;
+}
+
+/*
  * Curl_auth_decode_ntlm_type2_message()
  *
  * This is used to decode an already encoded NTLM type-2 message. The message
@@ -544,8 +558,9 @@
     unsigned int entropy[2];
     unsigned char ntlmv2hash[0x18];
 
-    entropy[0] = Curl_rand(data);
-    entropy[1] = Curl_rand(data);
+    result = Curl_rand(data, &entropy[0], 2);
+    if(result)
+      return result;
 
     result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
     if(result)
@@ -584,8 +599,9 @@
     unsigned int entropy[2];
 
     /* Need to create 8 bytes random data */
-    entropy[0] = Curl_rand(data);
-    entropy[1] = Curl_rand(data);
+    result = Curl_rand(data, &entropy[0], 2);
+    if(result)
+      return result;
 
     /* 8 bytes random data as challenge in lmresp */
     memcpy(lmresp, entropy, 8);
diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c
index 982a9d3..c330517 100644
--- a/lib/vauth/ntlm_sspi.c
+++ b/lib/vauth/ntlm_sspi.c
@@ -38,6 +38,27 @@
 #include "memdebug.h"
 
 /*
+ * Curl_auth_is_ntlm_supported()
+ *
+ * This is used to evaluate if NTLM is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE if NTLM is supported by Windows SSPI.
+ */
+bool Curl_auth_is_ntlm_supported(void)
+{
+  PSecPkgInfo SecurityPackage;
+  SECURITY_STATUS status;
+
+  /* Query the security package for NTLM */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
+                                              &SecurityPackage);
+
+  return (status == SEC_E_OK ? TRUE : FALSE);
+}
+
+/*
  * Curl_auth_create_ntlm_type1_message()
  *
  * This is used to generate an already encoded NTLM type-1 message ready for
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index b256ee6..8840db8 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -41,6 +41,20 @@
 #include "memdebug.h"
 
 /*
+ * Curl_auth_is_spnego_supported()
+ *
+ * This is used to evaluate if SPNEGO (Negotiate) is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE if Negotiate supported by the GSS-API library.
+ */
+bool Curl_auth_is_spnego_supported(void)
+{
+  return TRUE;
+}
+
+/*
  * Curl_auth_decode_spnego_message()
  *
  * This is used to decode an already encoded SPNEGO (Negotiate) challenge
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index b6176ec..5fa95e2 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -40,6 +40,28 @@
 #include "memdebug.h"
 
 /*
+ * Curl_auth_is_spnego_supported()
+ *
+ * This is used to evaluate if SPNEGO (Negotiate) is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE if Negotiate is supported by Windows SSPI.
+ */
+bool Curl_auth_is_spnego_supported(void)
+{
+  PSecPkgInfo SecurityPackage;
+  SECURITY_STATUS status;
+
+  /* Query the security package for Negotiate */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                              TEXT(SP_NAME_NEGOTIATE),
+                                              &SecurityPackage);
+
+  return (status == SEC_E_OK ? TRUE : FALSE);
+}
+
+/*
  * Curl_auth_decode_spnego_message()
  *
  * This is used to decode an already encoded SPNEGO (Negotiate) challenge
@@ -242,15 +264,17 @@
 
   /* Base64 encode the already generated response */
   result = Curl_base64_encode(data,
-                              (const char*) nego->output_token,
+                              (const char *) nego->output_token,
                               nego->output_token_length,
                               outptr, outlen);
 
   if(result)
     return result;
 
-  if(!*outptr || !*outlen)
+  if(!*outptr || !*outlen) {
+    free(*outptr);
     return CURLE_REMOTE_ACCESS_DENIED;
+  }
 
   return CURLE_OK;
 }
diff --git a/lib/vauth/vauth.c b/lib/vauth/vauth.c
index 702e2d4..b995f34 100644
--- a/lib/vauth/vauth.c
+++ b/lib/vauth/vauth.c
@@ -104,3 +104,44 @@
 }
 #endif /* USE_WINDOWS_SSPI */
 
+/*
+* Curl_auth_user_contains_domain()
+*
+* This is used to test if the specified user contains a Windows domain name as
+* follows:
+*
+* User\Domain (Down-level Logon Name)
+* User/Domain (curl Down-level format - for compatibility with existing code)
+* User@Domain (User Principal Name)
+*
+* Note: The user name may be empty when using a GSS-API library or Windows SSPI
+* as the user and domain are either obtained from the credientals cache when
+* using GSS-API or via the currently logged in user's credientals when using
+* Windows SSPI.
+*
+* Parameters:
+*
+* user  [in] - The user name.
+*
+* Returns TRUE on success; otherwise FALSE.
+*/
+bool Curl_auth_user_contains_domain(const char *user)
+{
+  bool valid = FALSE;
+
+  if(user && *user) {
+    /* Check we have a domain name or UPN present */
+    char *p = strpbrk(user, "\\/@");
+
+    valid = (p != NULL && p > user && p < user + strlen(user) - 1 ? TRUE :
+                                                                    FALSE);
+  }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  else
+    /* User and domain are obtained from the GSS-API credientials cache or the
+       currently logged in user from Windows */
+    valid = TRUE;
+#endif
+
+  return valid;
+}
diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h
index 38806ee..9d61228 100644
--- a/lib/vauth/vauth.h
+++ b/lib/vauth/vauth.h
@@ -55,6 +55,9 @@
                            const char *realm);
 #endif
 
+/* This is used to test if the user contains a Windows domain name */
+bool Curl_auth_user_contains_domain(const char *user);
+
 /* This is used to generate a base64 encoded PLAIN cleartext message */
 CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
                                         const char *userp,
@@ -83,6 +86,9 @@
                                            const char *passwdp,
                                            char **outptr, size_t *outlen);
 
+/* This is used to evaluate if DIGEST is supported */
+bool Curl_auth_is_digest_supported(void);
+
 /* This is used to generate a base64 encoded DIGEST-MD5 response message */
 CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
                                              const char *chlg64,
@@ -109,6 +115,9 @@
 #endif /* !CURL_DISABLE_CRYPTO_AUTH */
 
 #if defined(USE_NTLM)
+/* This is used to evaluate if NTLM is supported */
+bool Curl_auth_is_ntlm_supported(void);
+
 /* This is used to generate a base64 encoded NTLM type-1 message */
 CURLcode Curl_auth_create_ntlm_type1_message(const char *userp,
                                              const char *passwdp,
@@ -140,6 +149,9 @@
                                                const char *bearer,
                                                char **outptr, size_t *outlen);
 #if defined(USE_KERBEROS5)
+/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
+bool Curl_auth_is_gssapi_supported(void);
+
 /* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
    message */
 CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
@@ -165,6 +177,9 @@
 #endif /* USE_KERBEROS5 */
 
 #if defined(USE_SPNEGO)
+/* This is used to evaluate if SPNEGO (Negotiate) is supported */
+bool Curl_auth_is_spnego_supported(void);
+
 /* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge
    message */
 CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
diff --git a/lib/version.c b/lib/version.c
index 1292445..a434a62 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -36,8 +36,8 @@
 #  include <ares.h>
 #endif
 
-#ifdef USE_LIBIDN
-#include <stringprep.h>
+#ifdef USE_LIBIDN2
+#include <idn2.h>
 #endif
 
 #ifdef USE_LIBPSL
@@ -111,9 +111,9 @@
   left -= len;
   ptr += len;
 #endif
-#ifdef USE_LIBIDN
-  if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
-    len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
+#ifdef USE_LIBIDN2
+  if(idn2_check_version(IDN2_VERSION)) {
+    len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
     left -= len;
     ptr += len;
   }
@@ -365,10 +365,10 @@
     version_info.ares_num = aresnum;
   }
 #endif
-#ifdef USE_LIBIDN
+#ifdef USE_LIBIDN2
   /* This returns a version string if we use the given version or later,
      otherwise it returns NULL */
-  version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
+  version_info.libidn = idn2_check_version(IDN2_VERSION);
   if(version_info.libidn)
     version_info.features |= CURL_VERSION_IDN;
 #elif defined(USE_WIN32_IDN)
diff --git a/lib/vtls/axtls.c b/lib/vtls/axtls.c
index b6c69ad..8a5029f 100644
--- a/lib/vtls/axtls.c
+++ b/lib/vtls/axtls.c
@@ -158,7 +158,7 @@
 
   /* axTLS only supports TLSv1 */
   /* check to see if we've been told to use an explicit SSL/TLS version */
-  switch(data->set.ssl.version) {
+  switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
     break;
@@ -183,17 +183,17 @@
   conn->ssl[sockindex].ssl = NULL;
 
   /* Load the trusted CA cert bundle file */
-  if(data->set.ssl.CAfile) {
-    if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
-       != SSL_OK) {
+  if(SSL_CONN_CONFIG(CAfile)) {
+    if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
+                    SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
       infof(data, "error reading ca cert file %s \n",
-            data->set.ssl.CAfile);
-      if(data->set.ssl.verifypeer) {
+            SSL_CONN_CONFIG(CAfile));
+      if(SSL_CONN_CONFIG(verifypeer)) {
         return CURLE_SSL_CACERT_BADFILE;
       }
     }
     else
-      infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
+      infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
   }
 
   /* gtls.c tasks we're skipping for now:
@@ -205,15 +205,15 @@
    */
 
   /* Load client certificate */
-  if(data->set.str[STRING_CERT]) {
+  if(SSL_SET_OPTION(cert)) {
     i=0;
     /* Instead of trying to analyze cert type here, let axTLS try them all. */
     while(cert_types[i] != 0) {
       ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
-                                    data->set.str[STRING_CERT], NULL);
+                                    SSL_SET_OPTION(cert), NULL);
       if(ssl_fcn_return == SSL_OK) {
         infof(data, "successfully read cert file %s \n",
-              data->set.str[STRING_CERT]);
+              SSL_SET_OPTION(cert));
         break;
       }
       i++;
@@ -221,7 +221,7 @@
     /* Tried all cert types, none worked. */
     if(cert_types[i] == 0) {
       failf(data, "%s is not x509 or pkcs12 format",
-            data->set.str[STRING_CERT]);
+            SSL_SET_OPTION(cert));
       return CURLE_SSL_CERTPROBLEM;
     }
   }
@@ -229,15 +229,15 @@
   /* Load client key.
      If a pkcs12 file successfully loaded a cert, then there's nothing to do
      because the key has already been loaded. */
-  if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
+  if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
     i=0;
     /* Instead of trying to analyze key type here, let axTLS try them all. */
     while(key_types[i] != 0) {
       ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
-                                    data->set.str[STRING_KEY], NULL);
+                                    SSL_SET_OPTION(key), NULL);
       if(ssl_fcn_return == SSL_OK) {
         infof(data, "successfully read key file %s \n",
-              data->set.str[STRING_KEY]);
+              SSL_SET_OPTION(key));
         break;
       }
       i++;
@@ -245,7 +245,7 @@
     /* Tried all key types, none worked. */
     if(key_types[i] == 0) {
       failf(data, "Failure: %s is not a supported key file",
-            data->set.str[STRING_KEY]);
+            SSL_SET_OPTION(key));
       return CURLE_SSL_CONNECT_ERROR;
     }
   }
@@ -256,13 +256,14 @@
    * 2) setting up callbacks.  these seem gnutls specific
    */
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     const uint8_t *ssl_sessionid;
     size_t ssl_idsize;
 
     /* In axTLS, handshaking happens inside ssl_client_new. */
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
+    if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
+                              sockindex)) {
       /* we got a session id, use it! */
       infof (data, "SSL re-using session ID\n");
       ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
@@ -291,13 +292,17 @@
   const char *dns_altname;
   int8_t found_subject_alt_names = 0;
   int8_t found_subject_alt_name_matching_conn = 0;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
 
   /* Here, gtls.c gets the peer certificates and fails out depending on
    * settings in "data."  axTLS api doesn't have get cert chain fcn, so omit?
    */
 
   /* Verify server's certificate */
-  if(data->set.ssl.verifypeer) {
+  if(SSL_CONN_CONFIG(verifypeer)) {
     if(ssl_verify_cert(ssl) != SSL_OK) {
       Curl_axtls_close(conn, sockindex);
       failf(data, "server cert verify failed");
@@ -328,8 +333,8 @@
     found_subject_alt_names = 1;
 
     infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
-          dns_altname, conn->host.name);
-    if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
+          dns_altname, hostname);
+    if(Curl_cert_hostcheck(dns_altname, hostname)) {
       found_subject_alt_name_matching_conn = 1;
       break;
     }
@@ -337,23 +342,21 @@
 
   /* RFC2818 checks */
   if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
-    if(data->set.ssl.verifyhost) {
+    if(SSL_CONN_CONFIG(verifyhost)) {
       /* Break connection ! */
       Curl_axtls_close(conn, sockindex);
-      failf(data, "\tsubjectAltName(s) do not match %s\n",
-            conn->host.dispname);
+      failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
       return CURLE_PEER_FAILED_VERIFICATION;
     }
     else
-      infof(data, "\tsubjectAltName(s) do not match %s\n",
-            conn->host.dispname);
+      infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
   }
   else if(found_subject_alt_names == 0) {
     /* Per RFC2818, when no Subject Alt Names were available, examine the peer
        CN as a legacy fallback */
     peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
     if(peer_CN == NULL) {
-      if(data->set.ssl.verifyhost) {
+      if(SSL_CONN_CONFIG(verifyhost)) {
         Curl_axtls_close(conn, sockindex);
         failf(data, "unable to obtain common name from peer certificate");
         return CURLE_PEER_FAILED_VERIFICATION;
@@ -362,17 +365,17 @@
         infof(data, "unable to obtain common name from peer certificate");
     }
     else {
-      if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
-        if(data->set.ssl.verifyhost) {
+      if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
+        if(SSL_CONN_CONFIG(verifyhost)) {
           /* Break connection ! */
           Curl_axtls_close(conn, sockindex);
           failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
-                peer_CN, conn->host.dispname);
+                peer_CN, dispname);
           return CURLE_PEER_FAILED_VERIFICATION;
         }
         else
           infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
-                peer_CN, conn->host.dispname);
+                peer_CN, dispname);
       }
     }
   }
@@ -383,12 +386,12 @@
   conn->send[sockindex] = axtls_send;
 
   /* Put our freshly minted SSL session in cache */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
     size_t ssl_idsize = ssl_get_session_id(ssl);
     Curl_ssl_sessionid_lock(conn);
-    if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
-       != CURLE_OK)
+    if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
+                             sockindex) != CURLE_OK)
       infof (data, "failed to add session to cache\n");
     Curl_ssl_sessionid_unlock(conn);
   }
@@ -579,8 +582,7 @@
   */
 
   if(connssl->ssl) {
-    int what = Curl_socket_ready(conn->sock[sockindex],
-                                 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+    int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
     if(what > 0) {
       /* Something to read, let's do it and hope that it is the close
          notify alert from the server.  buf is managed internally by
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index 7994b3e..5570760 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -55,7 +55,7 @@
 #include "parsedate.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "x509asn1.h"
 #include "curl_printf.h"
 
@@ -118,9 +118,9 @@
 {
   if(!type || !type[0])
     return SSL_FILETYPE_PEM;
-  if(Curl_raw_equal(type, "PEM"))
+  if(strcasecompare(type, "PEM"))
     return SSL_FILETYPE_PEM;
-  if(Curl_raw_equal(type, "DER"))
+  if(strcasecompare(type, "DER"))
     return SSL_FILETYPE_ASN1;
   return -1;
 }
@@ -149,7 +149,7 @@
     return CURLE_OK;
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
-  switch(data->set.ssl.version) {
+  switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
 #if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
@@ -174,12 +174,15 @@
     req_method = TLSv1_2_client_method();
     use_sni(TRUE);
     break;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "CyaSSL: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
   case CURL_SSLVERSION_SSLv3:
 #ifdef WOLFSSL_ALLOW_SSLV3
     req_method = SSLv3_client_method();
     use_sni(FALSE);
 #else
-    failf(data, "No support for SSLv3");
+    failf(data, "CyaSSL does not support SSLv3");
     return CURLE_NOT_BUILT_IN;
 #endif
     break;
@@ -205,7 +208,7 @@
     return CURLE_OUT_OF_MEMORY;
   }
 
-  switch(data->set.ssl.version) {
+  switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
 #if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
@@ -228,18 +231,18 @@
 
 #ifndef NO_FILESYSTEM
   /* load trusted cacert */
-  if(data->set.str[STRING_SSL_CAFILE]) {
+  if(SSL_CONN_CONFIG(CAfile)) {
     if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
-                                          data->set.str[STRING_SSL_CAFILE],
-                                          data->set.str[STRING_SSL_CAPATH])) {
-      if(data->set.ssl.verifypeer) {
+                                      SSL_CONN_CONFIG(CAfile),
+                                      SSL_CONN_CONFIG(CApath))) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         /* Fail if we insist on successfully verifying the server. */
         failf(data, "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
-              data->set.str[STRING_SSL_CAFILE]?
-              data->set.str[STRING_SSL_CAFILE]: "none",
-              data->set.str[STRING_SSL_CAPATH]?
-              data->set.str[STRING_SSL_CAPATH] : "none");
+              SSL_CONN_CONFIG(CAfile)?
+              SSL_CONN_CONFIG(CAfile): "none",
+              SSL_CONN_CONFIG(CApath)?
+              SSL_CONN_CONFIG(CApath) : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
       else {
@@ -256,25 +259,25 @@
     infof(data,
           "  CAfile: %s\n"
           "  CApath: %s\n",
-          data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
+          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
           "none",
-          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
+          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
           "none");
   }
 
   /* Load the client certificate, and private key */
-  if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
-    int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
+  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
 
-    if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
+    if(SSL_CTX_use_certificate_file(conssl->ctx, SSL_SET_OPTION(cert),
                                      file_type) != 1) {
       failf(data, "unable to use client certificate (no key or wrong pass"
             " phrase?)");
       return CURLE_SSL_CONNECT_ERROR;
     }
 
-    file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
-    if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
+    file_type = do_file_type(SSL_SET_OPTION(key_type));
+    if(SSL_CTX_use_PrivateKey_file(conssl->ctx, SSL_SET_OPTION(key),
                                     file_type) != 1) {
       failf(data, "unable to set private key");
       return CURLE_SSL_CONNECT_ERROR;
@@ -287,7 +290,8 @@
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
   SSL_CTX_set_verify(conssl->ctx,
-                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
+                     SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
+                                                 SSL_VERIFY_NONE,
                      NULL);
 
 #ifdef HAVE_SNI
@@ -296,13 +300,15 @@
 #ifdef ENABLE_IPV6
     struct in6_addr addr6;
 #endif
-    size_t hostname_len = strlen(conn->host.name);
+    const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+      conn->host.name;
+    size_t hostname_len = strlen(hostname);
     if((hostname_len < USHRT_MAX) &&
-       (0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) &&
+       (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
 #ifdef ENABLE_IPV6
-       (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) &&
+       (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
 #endif
-       (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name,
+       (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, hostname,
                           (unsigned short)hostname_len) != 1)) {
       infof(data, "WARNING: failed to configure server name indication (SNI) "
             "TLS extension\n");
@@ -331,7 +337,7 @@
     }
   }
 #ifdef NO_FILESYSTEM
-  else if(data->set.ssl.verifypeer) {
+  else if(SSL_CONN_CONFIG(verifypeer)) {
     failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
           " with \"no filesystem\". Either disable peer verification"
           " (insecure) or if you are building an application with libcurl you"
@@ -377,11 +383,11 @@
 #endif /* HAVE_ALPN */
 
   /* Check if there's a cached ID we can/should use here! */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     void *ssl_sessionid = NULL;
 
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
       if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(conn);
@@ -414,13 +420,17 @@
   int ret = -1;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* conssl = &conn->ssl[sockindex];
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
 
   conn->recv[sockindex] = cyassl_recv;
   conn->send[sockindex] = cyassl_send;
 
   /* Enable RFC2818 checks */
-  if(data->set.ssl.verifyhost) {
-    ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
+  if(SSL_CONN_CONFIG(verifyhost)) {
+    ret = CyaSSL_check_domain_name(conssl->handle, hostname);
     if(ret == SSL_FAILURE)
       return CURLE_OUT_OF_MEMORY;
   }
@@ -444,31 +454,31 @@
     else if(DOMAIN_NAME_MISMATCH == detail) {
 #if 1
       failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
-            conn->host.dispname);
+            dispname);
       return CURLE_PEER_FAILED_VERIFICATION;
 #else
       /* When the CyaSSL_check_domain_name() is used and you desire to continue
-       * on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0',
+       * on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost == 0',
        * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
        * way to do this is currently to switch the CyaSSL_check_domain_name()
-       * in and out based on the 'data->set.ssl.verifyhost' value. */
-      if(data->set.ssl.verifyhost) {
+       * in and out based on the 'conn->ssl_config.verifyhost' value. */
+      if(SSL_CONN_CONFIG(verifyhost)) {
         failf(data,
               "\tsubject alt name(s) or common name do not match \"%s\"\n",
-              conn->host.dispname);
+              dispname);
         return CURLE_PEER_FAILED_VERIFICATION;
       }
       else {
         infof(data,
               "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
-              conn->host.dispname);
+              dispname);
         return CURLE_OK;
       }
 #endif
     }
 #if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
     else if(ASN_NO_SIGNER_E == detail) {
-      if(data->set.ssl.verifypeer) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "\tCA signer not available for verification\n");
         return CURLE_SSL_CACERT_BADFILE;
       }
@@ -509,7 +519,8 @@
     }
 
     memset(&x509_parsed, 0, sizeof x509_parsed);
-    Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
+    if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
 
     pubkey = &x509_parsed.subjectPublicKeyInfo;
     if(!pubkey->header || pubkey->end <= pubkey->header) {
@@ -583,7 +594,7 @@
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     bool incache;
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -591,7 +602,8 @@
     our_ssl_sessionid = SSL_get_session(connssl->handle);
 
     Curl_ssl_sessionid_lock(conn);
-    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+                                      sockindex));
     if(incache) {
       if(old_ssl_sessionid != our_ssl_sessionid) {
         infof(data, "old SSL session ID is stale, removing\n");
@@ -602,7 +614,7 @@
 
     if(!incache) {
       result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
-                                     0 /* unknown size */);
+                                     0 /* unknown size */, sockindex);
       if(result) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "failed to store ssl session");
@@ -803,7 +815,8 @@
       curl_socket_t readfd = ssl_connect_2_reading==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index ebb9e30..0602cdb 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2016, 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
@@ -197,7 +197,7 @@
 
   do {
     length = write(sock,
-                   (char*)dataPtr + bytesSent,
+                   (char *)dataPtr + bytesSent,
                    dataLen - bytesSent);
   } while((length > 0) &&
            ( (bytesSent += length) < dataLen) );
@@ -219,7 +219,8 @@
   return ortn;
 }
 
-CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
+CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
+{
   switch (cipher) {
     /* SSL version 3.0 */
     case SSL_RSA_WITH_NULL_MD5:
@@ -364,7 +365,8 @@
   return "SSL_NULL_WITH_NULL_NULL";
 }
 
-CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
+CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
+{
   switch(cipher) {
     /* TLS 1.0 with AES (RFC 3268) */
     case TLS_RSA_WITH_AES_128_CBC_SHA:
@@ -883,14 +885,18 @@
                                       SecIdentityRef *out_cert_and_key)
 {
   OSStatus status = errSecItemNotFound;
+  CFArrayRef keys_list;
+  CFIndex keys_list_count;
+  CFIndex i;
+  CFStringRef common_name;
 
 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
      kSecClassIdentity was introduced in Lion. If both exist, let's use them
      to find the certificate. */
   if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
-    CFTypeRef keys[4];
-    CFTypeRef values[4];
+    CFTypeRef keys[5];
+    CFTypeRef values[5];
     CFDictionaryRef query_dict;
     CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
       kCFStringEncodingUTF8);
@@ -900,27 +906,59 @@
     keys[0] = kSecClass;
     values[1] = kCFBooleanTrue;    /* we want a reference */
     keys[1] = kSecReturnRef;
-    values[2] = kSecMatchLimitOne; /* one is enough, thanks */
+    values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
+                                    * label matching below worked correctly */
     keys[2] = kSecMatchLimit;
     /* identity searches need a SecPolicyRef in order to work */
-    values[3] = SecPolicyCreateSSL(false, label_cf);
+    values[3] = SecPolicyCreateSSL(false, NULL);
     keys[3] = kSecMatchPolicy;
+    /* match the name of the certificate (doesn't work in macOS 10.12.1) */
+    values[4] = label_cf;
+    keys[4] = kSecAttrLabel;
     query_dict = CFDictionaryCreate(NULL, (const void **)keys,
-                                   (const void **)values, 4L,
-                                   &kCFCopyStringDictionaryKeyCallBacks,
-                                   &kCFTypeDictionaryValueCallBacks);
+                                    (const void **)values, 5L,
+                                    &kCFCopyStringDictionaryKeyCallBacks,
+                                    &kCFTypeDictionaryValueCallBacks);
     CFRelease(values[3]);
-    CFRelease(label_cf);
 
     /* Do we have a match? */
-    status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
+    status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
+
+    /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
+     * we need to find the correct identity ourselves */
+    if(status == noErr) {
+      keys_list_count = CFArrayGetCount(keys_list);
+      *out_cert_and_key = NULL;
+      for(i=0; i<keys_list_count; i++) {
+        OSStatus err = noErr;
+        SecCertificateRef cert = NULL;
+        *out_cert_and_key =
+          (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
+        err = SecIdentityCopyCertificate(*out_cert_and_key, &cert);
+        if(err == noErr) {
+          SecCertificateCopyCommonName(cert, &common_name);
+          if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
+            CFRelease(cert);
+            CFRelease(common_name);
+            status = noErr;
+            break;
+          }
+          CFRelease(common_name);
+        }
+        *out_cert_and_key = NULL;
+        status = 1;
+        CFRelease(cert);
+      }
+    }
+
     CFRelease(query_dict);
+    CFRelease(label_cf);
   }
   else {
 #if CURL_SUPPORT_MAC_10_6
     /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
     status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
-#endif /* CURL_SUPPORT_MAC_10_7 */
+#endif /* CURL_SUPPORT_MAC_10_6 */
   }
 #elif CURL_SUPPORT_MAC_10_6
   /* For developers building on older cats, we have no choice but to fall back
@@ -955,7 +993,7 @@
 
     /* Here we go: */
     status = SecPKCS12Import(pkcs_data, options, &items);
-    if(status == noErr && items && CFArrayGetCount(items)) {
+    if(status == errSecSuccess && items && CFArrayGetCount(items)) {
       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
         kSecImportItemIdentity);
@@ -1002,6 +1040,12 @@
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
@@ -1052,40 +1096,46 @@
   /* check to see if we've been told to use an explicit SSL/TLS version */
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
   if(SSLSetProtocolVersionMax != NULL) {
-    switch(data->set.ssl.version) {
-      default:
-      case CURL_SSLVERSION_DEFAULT:
-      case CURL_SSLVERSION_TLSv1:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-        break;
-      case CURL_SSLVERSION_TLSv1_0:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-        break;
-      case CURL_SSLVERSION_SSLv3:
-        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv3");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
-        break;
-      case CURL_SSLVERSION_SSLv2:
-        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv2");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+    switch(conn->ssl_config.version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+      break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_SSLv3:
+      err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv3");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
     }
   }
   else {
@@ -1093,82 +1143,37 @@
     (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                        kSSLProtocolAll,
                                        false);
-    switch (data->set.ssl.version) {
-      default:
-      case CURL_SSLVERSION_DEFAULT:
-      case CURL_SSLVERSION_TLSv1:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol1,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol11,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol12,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_0:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol1,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol11,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol12,
-                                           true);
-        break;
-      case CURL_SSLVERSION_SSLv3:
-        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kSSLProtocol3,
-                                           true);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv3");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        break;
-      case CURL_SSLVERSION_SSLv2:
-        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kSSLProtocol2,
-                                           true);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv2");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        break;
-    }
-#endif  /* CURL_SUPPORT_MAC_10_8 */
-  }
-#else
-  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
-  switch(data->set.ssl.version) {
-    default:
+    switch (conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol1,
+                                         true);
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol11,
+                                         true);
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol12,
+                                         true);
+      break;
     case CURL_SSLVERSION_TLSv1_0:
       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                          kTLSProtocol1,
                                          true);
       break;
     case CURL_SSLVERSION_TLSv1_1:
-      failf(data, "Your version of the OS does not support TLSv1.1");
-      return CURLE_SSL_CONNECT_ERROR;
-    case CURL_SSLVERSION_TLSv1_2:
-      failf(data, "Your version of the OS does not support TLSv1.2");
-      return CURLE_SSL_CONNECT_ERROR;
-    case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kSSLProtocol2,
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol11,
                                          true);
-      if(err != noErr) {
-        failf(data, "Your version of the OS does not support SSLv2");
-        return CURLE_SSL_CONNECT_ERROR;
-      }
       break;
+    case CURL_SSLVERSION_TLSv1_2:
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol12,
+                                         true);
+      break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
     case CURL_SSLVERSION_SSLv3:
       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                          kSSLProtocol3,
@@ -1178,36 +1183,91 @@
         return CURLE_SSL_CONNECT_ERROR;
       }
       break;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kSSLProtocol2,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
+  switch(conn->ssl_config.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+  case CURL_SSLVERSION_TLSv1_0:
+    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kTLSProtocol1,
+                                       true);
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    failf(data, "Your version of the OS does not support TLSv1.1");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_2:
+    failf(data, "Your version of the OS does not support TLSv1.2");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "Your version of the OS does not support TLSv1.3");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_SSLv2:
+    err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kSSLProtocol2,
+                                       true);
+    if(err != noErr) {
+      failf(data, "Your version of the OS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kSSLProtocol3,
+                                       true);
+    if(err != noErr) {
+      failf(data, "Your version of the OS does not support SSLv3");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    break;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
 
-  if(data->set.str[STRING_KEY]) {
+  if(SSL_SET_OPTION(key)) {
     infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
-                "Transport. The private key must be in the Keychain.\n");
+          "Transport. The private key must be in the Keychain.\n");
   }
 
-  if(data->set.str[STRING_CERT]) {
+  if(ssl_cert) {
     SecIdentityRef cert_and_key = NULL;
-    bool is_cert_file = is_file(data->set.str[STRING_CERT]);
+    bool is_cert_file = is_file(ssl_cert);
 
     /* User wants to authenticate with a client cert. Look for it:
        If we detect that this is a file on disk, then let's load it.
        Otherwise, assume that the user wants to use an identity loaded
        from the Keychain. */
     if(is_cert_file) {
-      if(!data->set.str[STRING_CERT_TYPE])
+      if(!SSL_SET_OPTION(cert_type))
         infof(data, "WARNING: SSL: Certificate type not set, assuming "
                     "PKCS#12 format.\n");
-      else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
-        strlen(data->set.str[STRING_CERT_TYPE])) != 0)
+      else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
+        strlen(SSL_SET_OPTION(cert_type))) != 0)
         infof(data, "WARNING: SSL: The Security framework only supports "
                     "loading identities that are in PKCS#12 format.\n");
 
-      err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
-        data->set.str[STRING_KEY_PASSWD], &cert_and_key);
+      err = CopyIdentityFromPKCS12File(ssl_cert,
+        SSL_SET_OPTION(key_passwd), &cert_and_key);
     }
     else
-      err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
+      err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
 
     if(err == noErr) {
       SecCertificateRef cert = NULL;
@@ -1246,27 +1306,27 @@
     }
     else {
       switch(err) {
-        case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
-          failf(data, "SSL: Incorrect password for the certificate \"%s\" "
-                      "and its private key.", data->set.str[STRING_CERT]);
-          break;
-        case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
-          failf(data, "SSL: Couldn't make sense of the data in the "
-                      "certificate \"%s\" and its private key.",
-                      data->set.str[STRING_CERT]);
-          break;
-        case -25260: /* errSecPassphraseRequired */
-          failf(data, "SSL The certificate \"%s\" requires a password.",
-                      data->set.str[STRING_CERT]);
-          break;
-        case errSecItemNotFound:
-          failf(data, "SSL: Can't find the certificate \"%s\" and its private "
-                      "key in the Keychain.", data->set.str[STRING_CERT]);
-          break;
-        default:
-          failf(data, "SSL: Can't load the certificate \"%s\" and its private "
-                      "key: OSStatus %d", data->set.str[STRING_CERT], err);
-          break;
+      case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
+        failf(data, "SSL: Incorrect password for the certificate \"%s\" "
+                    "and its private key.", ssl_cert);
+        break;
+      case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
+        failf(data, "SSL: Couldn't make sense of the data in the "
+                    "certificate \"%s\" and its private key.",
+                    ssl_cert);
+        break;
+      case -25260: /* errSecPassphraseRequired */
+        failf(data, "SSL The certificate \"%s\" requires a password.",
+                    ssl_cert);
+        break;
+      case errSecItemNotFound:
+        failf(data, "SSL: Can't find the certificate \"%s\" and its private "
+                    "key in the Keychain.", ssl_cert);
+        break;
+      default:
+        failf(data, "SSL: Can't load the certificate \"%s\" and its private "
+                    "key: OSStatus %d", ssl_cert, err);
+        break;
       }
       return CURLE_SSL_CERTPROBLEM;
     }
@@ -1297,8 +1357,7 @@
 #else
   if(SSLSetSessionOption != NULL) {
 #endif /* CURL_BUILD_MAC */
-    bool break_on_auth = !data->set.ssl.verifypeer ||
-      data->set.str[STRING_SSL_CAFILE];
+    bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
     err = SSLSetSessionOption(connssl->ssl_ctx,
                               kSSLSessionOptionBreakOnServerAuth,
                               break_on_auth);
@@ -1310,7 +1369,7 @@
   else {
 #if CURL_SUPPORT_MAC_10_8
     err = SSLSetEnableCertVerify(connssl->ssl_ctx,
-                                 data->set.ssl.verifypeer?true:false);
+                                 conn->ssl_config.verifypeer?true:false);
     if(err != noErr) {
       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
       return CURLE_SSL_CONNECT_ERROR;
@@ -1319,22 +1378,21 @@
   }
 #else
   err = SSLSetEnableCertVerify(connssl->ssl_ctx,
-                               data->set.ssl.verifypeer?true:false);
+                               conn->ssl_config.verifypeer?true:false);
   if(err != noErr) {
     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
     return CURLE_SSL_CONNECT_ERROR;
   }
 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
 
-  if(data->set.str[STRING_SSL_CAFILE]) {
-    bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
+  if(ssl_cafile) {
+    bool is_cert_file = is_file(ssl_cafile);
 
     if(!is_cert_file) {
-      failf(data, "SSL: can't load CA certificate file %s",
-            data->set.str[STRING_SSL_CAFILE]);
+      failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
       return CURLE_SSL_CACERT_BADFILE;
     }
-    if(!data->set.ssl.verifypeer) {
+    if(!verifypeer) {
       failf(data, "SSL: CA certificate set, but certificate verification "
             "is disabled");
       return CURLE_SSL_CONNECT_ERROR;
@@ -1344,22 +1402,22 @@
   /* Configure hostname check. SNI is used if available.
    * Both hostname check and SNI require SSLSetPeerDomainName().
    * Also: the verifyhost setting influences SNI usage */
-  if(data->set.ssl.verifyhost) {
-    err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
-    strlen(conn->host.name));
+  if(conn->ssl_config.verifyhost) {
+    err = SSLSetPeerDomainName(connssl->ssl_ctx, hostname,
+    strlen(hostname));
 
     if(err != noErr) {
       infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
             err);
     }
 
-    if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
+    if((Curl_inet_pton(AF_INET, hostname, &addr))
   #ifdef ENABLE_IPV6
-    || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+    || (Curl_inet_pton(AF_INET6, hostname, &addr))
   #endif
        ) {
-         infof(data, "WARNING: using IP address, SNI is being disabled by "
-         "the OS.\n");
+      infof(data, "WARNING: using IP address, SNI is being disabled by "
+            "the OS.\n");
     }
   }
 
@@ -1382,7 +1440,7 @@
         running in an affected version of OS X. */
       if(darwinver_maj == 12 && darwinver_min <= 3 &&
          all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
-           continue;
+        continue;
       }
 #endif /* CURL_BUILD_MAC */
       switch(all_ciphers[i]) {
@@ -1438,6 +1496,16 @@
         /* Disable IDEA: */
         case SSL_RSA_WITH_IDEA_CBC_SHA:
         case SSL_RSA_WITH_IDEA_CBC_MD5:
+        /* Disable RC4: */
+        case SSL_RSA_WITH_RC4_128_MD5:
+        case SSL_RSA_WITH_RC4_128_SHA:
+        case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
+        case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
+        case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
+        case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+        case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
+        case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
+        case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
           break;
         default: /* enable everything else */
           allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
@@ -1464,21 +1532,22 @@
   /* We want to enable 1/n-1 when using a CBC cipher unless the user
      specifically doesn't want us doing that: */
   if(SSLSetSessionOption != NULL) {
+    /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
     SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
-                      !data->set.ssl_enable_beast);
+                      !data->set.ssl.enable_beast);
     SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
                       data->set.ssl.falsestart); /* false start support */
   }
 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
 
   /* Check if there's a cached ID we can/should use here! */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     char *ssl_sessionid;
     size_t ssl_sessionid_len;
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
-                              &ssl_sessionid_len)) {
+                              &ssl_sessionid_len, sockindex)) {
       /* we got a session id, use it! */
       err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
       Curl_ssl_sessionid_unlock(conn);
@@ -1494,9 +1563,8 @@
     else {
       CURLcode result;
       ssl_sessionid =
-        aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
-                data->set.ssl.verifypeer, data->set.ssl.verifyhost,
-                conn->host.name, conn->remote_port);
+        aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
+                verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
       ssl_sessionid_len = strlen(ssl_sessionid);
 
       err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
@@ -1506,7 +1574,8 @@
         return CURLE_SSL_CONNECT_ERROR;
       }
 
-      result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
+      result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
+                                     sockindex);
       Curl_ssl_sessionid_unlock(conn);
       if(result) {
         failf(data, "failed to store ssl session");
@@ -1832,6 +1901,8 @@
   OSStatus err;
   SSLCipherSuite cipher;
   SSLProtocol protocol = 0;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
               || ssl_connect_2_reading == connssl->connecting_state
@@ -1850,8 +1921,8 @@
       /* The below is errSSLServerAuthCompleted; it's not defined in
         Leopard's headers */
       case -9841:
-        if(data->set.str[STRING_SSL_CAFILE]) {
-          int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
+        if(SSL_CONN_CONFIG(CAfile)) {
+          int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
                                 connssl->ssl_ctx);
           if(res != CURLE_OK)
             return res;
@@ -1920,7 +1991,7 @@
         return CURLE_SSL_CONNECT_ERROR;
       default:
         failf(data, "Unknown SSL protocol error in connection to %s:%d",
-              conn->host.name, err);
+              hostname, err);
         return CURLE_SSL_CONNECT_ERROR;
     }
   }
@@ -2140,7 +2211,8 @@
       curl_socket_t readfd = ssl_connect_2_reading ==
       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -2262,8 +2334,7 @@
 
   rc = 0;
 
-  what = Curl_socket_ready(conn->sock[sockindex],
-                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+  what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
 
   for(;;) {
     if(what < 0) {
@@ -2291,7 +2362,7 @@
     if(nread <= 0)
       break;
 
-    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+    what = SOCKET_READABLE(conn->sock[sockindex], 0);
   }
 
   return rc;
@@ -2380,7 +2451,8 @@
   (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
 }
 
-bool Curl_darwinssl_false_start(void) {
+bool Curl_darwinssl_false_start(void)
+{
 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
   if(SSLSetSessionOption != NULL)
     return TRUE;
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 55a55ef..6cac957 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,7 +72,7 @@
 #include "vtls.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "x509asn1.h"
 #include "curl_printf.h"
 
@@ -81,6 +81,10 @@
 #include "memdebug.h"
 
 
+/* Directions. */
+#define SOS_READ        0x01
+#define SOS_WRITE       0x02
+
 /* SSL version flags. */
 #define CURL_GSKPROTO_SSLV2     0
 #define CURL_GSKPROTO_SSLV2_MASK        (1 << CURL_GSKPROTO_SSLV2)
@@ -289,10 +293,11 @@
 }
 
 
-static CURLcode set_ciphers(struct Curl_easy *data,
+static CURLcode set_ciphers(struct connectdata *conn,
                                         gsk_handle h, unsigned int *protoflags)
 {
-  const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
+  struct Curl_easy *data = conn->data;
+  const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
   const char *clp;
   const gskit_cipher *ctp;
   int i;
@@ -340,7 +345,7 @@
       break;
     /* Search the cipher in our table. */
     for(ctp = ciphertable; ctp->name; ctp++)
-      if(strnequal(ctp->name, clp, l) && !ctp->name[l])
+      if(strncasecompare(ctp->name, clp, l) && !ctp->name[l])
         break;
     if(!ctp->name) {
       failf(data, "Unknown cipher %.*s", l, clp);
@@ -500,17 +505,195 @@
   connssl->iocport = -1;
 }
 
+/* SSL over SSL
+ * Problems:
+ * 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To
+ *    pipe an SSL stream into another, it is therefore needed to have a pair
+ *    of such communicating sockets and handle the pipelining explicitly.
+ * 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot
+ *    be used to produce the pipeline.
+ * The solution is to simulate socketpair() for AF_INET with low-level API
+ *    listen(), bind() and connect().
+ */
 
-static void close_one(struct ssl_connect_data *conn,
-                      struct Curl_easy *data)
+static int
+inetsocketpair(int sv[2])
 {
-  if(conn->handle) {
-    gskit_status(data, gsk_secure_soc_close(&conn->handle),
-              "gsk_secure_soc_close()", 0);
-    conn->handle = (gsk_handle) NULL;
+  int lfd;      /* Listening socket. */
+  int sfd;      /* Server socket. */
+  int cfd;      /* Client socket. */
+  int len;
+  struct sockaddr_in addr1;
+  struct sockaddr_in addr2;
+
+  /* Create listening socket on a local dynamic port. */
+  lfd = socket(AF_INET, SOCK_STREAM, 0);
+  if(lfd < 0)
+    return -1;
+  memset((char *) &addr1, 0, sizeof addr1);
+  addr1.sin_family = AF_INET;
+  addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  addr1.sin_port = 0;
+  if(bind(lfd, (struct sockaddr *) &addr1, sizeof addr1) ||
+     listen(lfd, 2) < 0) {
+    close(lfd);
+    return -1;
   }
-  if(conn->iocport >= 0)
-    close_async_handshake(conn);
+
+  /* Get the allocated port. */
+  len = sizeof addr1;
+  if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
+    close(lfd);
+    return -1;
+  }
+
+  /* Create the client socket. */
+  cfd = socket(AF_INET, SOCK_STREAM, 0);
+  if(cfd < 0) {
+    close(lfd);
+    return -1;
+  }
+
+  /* Request unblocking connection to the listening socket. */
+  curlx_nonblock(cfd, TRUE);
+  if(connect(cfd, (struct sockaddr *) &addr1, sizeof addr1) < 0 &&
+     errno != EINPROGRESS) {
+    close(lfd);
+    close(cfd);
+    return -1;
+  }
+
+  /* Get the client dynamic port for intrusion check below. */
+  len = sizeof addr2;
+  if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
+    close(lfd);
+    close(cfd);
+    return -1;
+  }
+
+  /* Accept the incoming connection and get the server socket. */
+  curlx_nonblock(lfd, TRUE);
+  for(;;) {
+    len = sizeof addr1;
+    sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
+    if(sfd < 0) {
+      close(lfd);
+      close(cfd);
+      return -1;
+    }
+
+    /* Check for possible intrusion from an external process. */
+    if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr &&
+       addr1.sin_port == addr2.sin_port)
+      break;
+
+    /* Intrusion: reject incoming connection. */
+    close(sfd);
+  }
+
+  /* Done, return sockets and succeed. */
+  close(lfd);
+  curlx_nonblock(cfd, FALSE);
+  sv[0] = cfd;
+  sv[1] = sfd;
+  return 0;
+}
+
+static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
+                           int directions)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
+  fd_set fds_read;
+  fd_set fds_write;
+  int n;
+  int m;
+  int i;
+  int ret = 0;
+  struct timeval tv = {0, 0};
+  char buf[CURL_MAX_WRITE_SIZE];
+
+  if(!connssl->use || !connproxyssl->use)
+    return 0;   /* No SSL over SSL: OK. */
+
+  FD_ZERO(&fds_read);
+  FD_ZERO(&fds_write);
+  n = -1;
+  if(directions & SOS_READ) {
+    FD_SET(connssl->remotefd, &fds_write);
+    n = connssl->remotefd;
+  }
+  if(directions & SOS_WRITE) {
+    FD_SET(connssl->remotefd, &fds_read);
+    n = connssl->remotefd;
+    FD_SET(conn->sock[sockindex], &fds_write);
+    if(n < conn->sock[sockindex])
+      n = conn->sock[sockindex];
+  }
+  i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
+  if(i < 0)
+    return -1;  /* Select error. */
+
+  if(FD_ISSET(connssl->remotefd, &fds_write)) {
+    /* Try getting data from HTTPS proxy and pipe it upstream. */
+    n = 0;
+    i = gsk_secure_soc_read(connproxyssl->handle, buf, sizeof buf, &n);
+    switch(i) {
+    case GSK_OK:
+      if(n) {
+        i = write(connssl->remotefd, buf, n);
+        if(i < 0)
+          return -1;
+        ret = 1;
+      }
+      break;
+    case GSK_OS400_ERROR_TIMED_OUT:
+    case GSK_WOULD_BLOCK:
+      break;
+    default:
+      return -1;
+    }
+  }
+
+  if(FD_ISSET(connssl->remotefd, &fds_read) &&
+     FD_ISSET(conn->sock[sockindex], &fds_write)) {
+    /* Pipe data to HTTPS proxy. */
+    n = read(connssl->remotefd, buf, sizeof buf);
+    if(n < 0)
+      return -1;
+    if(n) {
+      i = gsk_secure_soc_write(connproxyssl->handle, buf, n, &m);
+      if(i != GSK_OK || n != m)
+        return -1;
+      ret = 1;
+    }
+  }
+
+  return ret;  /* OK */
+}
+
+
+static void close_one(struct ssl_connect_data *connssl,
+                      struct connectdata *conn, int sockindex)
+{
+  if(connssl->handle) {
+    gskit_status(conn->data, gsk_secure_soc_close(&connssl->handle),
+              "gsk_secure_soc_close()", 0);
+    /* Last chance to drain output. */
+    while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
+      ;
+    connssl->handle = (gsk_handle) NULL;
+    if(connssl->localfd >= 0) {
+      close(connssl->localfd);
+      connssl->localfd = -1;
+    }
+    if(connssl->remotefd >= 0) {
+      close(connssl->remotefd);
+      connssl->remotefd = -1;
+    }
+  }
+  if(connssl->iocport >= 0)
+    close_async_handshake(connssl);
 }
 
 
@@ -518,13 +701,18 @@
                            const void *mem, size_t len, CURLcode *curlcode)
 {
   struct Curl_easy *data = conn->data;
-  CURLcode cc;
+  CURLcode cc = CURLE_SEND_ERROR;
   int written;
 
-  cc = gskit_status(data,
-                    gsk_secure_soc_write(conn->ssl[sockindex].handle,
-                                         (char *) mem, (int) len, &written),
-                    "gsk_secure_soc_write()", CURLE_SEND_ERROR);
+  if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
+    cc = gskit_status(data,
+                      gsk_secure_soc_write(conn->ssl[sockindex].handle,
+                                           (char *) mem, (int) len, &written),
+                      "gsk_secure_soc_write()", CURLE_SEND_ERROR);
+    if(cc == CURLE_OK)
+      if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
+        cc = CURLE_SEND_ERROR;
+  }
   if(cc != CURLE_OK) {
     *curlcode = cc;
     written = -1;
@@ -539,15 +727,23 @@
   struct Curl_easy *data = conn->data;
   int buffsize;
   int nread;
-  CURLcode cc;
+  CURLcode cc = CURLE_RECV_ERROR;
 
-  buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
-  cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
-                                              buf, buffsize, &nread),
-                    "gsk_secure_soc_read()", CURLE_RECV_ERROR);
-  if(cc != CURLE_OK) {
+  if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
+    buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
+    cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
+                                                buf, buffsize, &nread),
+                      "gsk_secure_soc_read()", CURLE_RECV_ERROR);
+  }
+  switch(cc) {
+  case CURLE_OK:
+    break;
+  case CURLE_OPERATION_TIMEDOUT:
+    cc = CURLE_AGAIN;
+  default:
     *curlcode = cc;
     nread = -1;
+    break;
   }
   return (ssize_t) nread;
 }
@@ -560,18 +756,26 @@
   gsk_handle envir;
   CURLcode result;
   int rc;
-  char *keyringfile;
-  char *keyringpwd;
-  char *keyringlabel;
-  char *sni;
+  const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
+  const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
+  const char * const keyringlabel = SSL_SET_OPTION(cert);
+  const long int ssl_version = SSL_CONN_CONFIG(version);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
+    conn->host.name;
+  const char *sni;
   unsigned int protoflags;
   long timeout;
   Qso_OverlappedIO_t commarea;
+  int sockpair[2];
+  static const int sobufsize = CURL_MAX_WRITE_SIZE;
 
   /* Create SSL environment, start (preferably asynchronous) handshake. */
 
   connssl->handle = (gsk_handle) NULL;
   connssl->iocport = -1;
+  connssl->localfd = -1;
+  connssl->remotefd = -1;
 
   /* GSKit supports two ways of specifying an SSL context: either by
    *  application identifier (that should have been defined at the system
@@ -586,9 +790,6 @@
    *  application identifier mode is tried first, as recommended in IBM doc.
    */
 
-  keyringfile = data->set.str[STRING_SSL_CAFILE];
-  keyringpwd = data->set.str[STRING_KEY_PASSWD];
-  keyringlabel = data->set.str[STRING_CERT];
   envir = (gsk_handle) NULL;
 
   if(keyringlabel && *keyringlabel && !keyringpwd &&
@@ -613,19 +814,36 @@
   if(result)
     return result;
 
+  /* Establish a pipelining socket pair for SSL over SSL. */
+  if(conn->proxy_ssl[sockindex].use) {
+    if(inetsocketpair(sockpair))
+      return CURLE_SSL_CONNECT_ERROR;
+    connssl->localfd = sockpair[0];
+    connssl->remotefd = sockpair[1];
+    setsockopt(connssl->localfd, SOL_SOCKET, SO_RCVBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(connssl->remotefd, SOL_SOCKET, SO_RCVBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(connssl->localfd, SOL_SOCKET, SO_SNDBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(connssl->remotefd, SOL_SOCKET, SO_SNDBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    curlx_nonblock(connssl->localfd, TRUE);
+    curlx_nonblock(connssl->remotefd, TRUE);
+  }
+
   /* Determine which SSL/TLS version should be enabled. */
-  protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
-               CURL_GSKPROTO_TLSV12_MASK;
-  sni = conn->host.name;
-  switch (data->set.ssl.version) {
+  sni = hostname;
+  switch (ssl_version) {
   case CURL_SSLVERSION_SSLv2:
     protoflags = CURL_GSKPROTO_SSLV2_MASK;
-    sni = (char *) NULL;
+    sni = NULL;
     break;
   case CURL_SSLVERSION_SSLv3:
     protoflags = CURL_GSKPROTO_SSLV3_MASK;
-    sni = (char *) NULL;
+    sni = NULL;
     break;
+  case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
     protoflags = CURL_GSKPROTO_TLSV10_MASK |
                  CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
@@ -639,6 +857,12 @@
   case CURL_SSLVERSION_TLSv1_2:
     protoflags = CURL_GSKPROTO_TLSV12_MASK;
     break;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "GSKit: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
@@ -661,9 +885,12 @@
                            (timeout + 999) / 1000);
   }
   if(!result)
-    result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
+    result = set_numeric(data, connssl->handle, GSK_OS400_READ_TIMEOUT, 1);
   if(!result)
-    result = set_ciphers(data, connssl->handle, &protoflags);
+    result = set_numeric(data, connssl->handle, GSK_FD, connssl->localfd >= 0?
+                         connssl->localfd: conn->sock[sockindex]);
+  if(!result)
+    result = set_ciphers(conn, connssl->handle, &protoflags);
   if(!protoflags) {
     failf(data, "No SSL protocol/cipher combination enabled");
     result = CURLE_SSL_CIPHER;
@@ -706,7 +933,7 @@
   }
   if(!result)
     result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
-                      data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
+                      verifypeer? GSK_SERVER_AUTH_FULL:
                       GSK_SERVER_AUTH_PASSTHRU, FALSE);
 
   if(!result) {
@@ -730,6 +957,10 @@
     else if(errno != ENOBUFS)
       result = gskit_status(data, GSK_ERROR_IO,
                             "QsoCreateIOCompletionPort()", 0);
+    else if(conn->proxy_ssl[sockindex].use) {
+      /* Cannot pipeline while handshaking synchronously. */
+      result = CURLE_SSL_CONNECT_ERROR;
+    }
     else {
       /* No more completion port available. Use synchronous IO. */
       result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
@@ -742,7 +973,7 @@
   }
 
   /* Error: rollback. */
-  close_one(connssl, data);
+  close_one(connssl, conn, sockindex);
   return result;
 }
 
@@ -870,9 +1101,8 @@
     curl_X509certificate x509;
     curl_asn1Element *p;
 
-    if(!cert)
+    if(Curl_parseX509(&x509, cert, certend))
       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    Curl_parseX509(&x509, cert, certend);
     p = &x509.subjectPublicKeyInfo;
     result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
     if(result) {
@@ -913,6 +1143,11 @@
       result = gskit_connect_step1(conn, sockindex);
   }
 
+  /* Handle handshake pipelining. */
+  if(!result)
+    if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+      result = CURLE_SSL_CONNECT_ERROR;
+
   /* Step 2: check if handshake is over. */
   if(!result && connssl->connecting_state == ssl_connect_2) {
     /* check allowed time left */
@@ -927,12 +1162,17 @@
       result = gskit_connect_step2(conn, sockindex, nonblocking);
   }
 
+  /* Handle handshake pipelining. */
+  if(!result)
+    if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+      result = CURLE_SSL_CONNECT_ERROR;
+
   /* Step 3: gather certificate info, verify host. */
   if(!result && connssl->connecting_state == ssl_connect_3)
     result = gskit_connect_step3(conn, sockindex);
 
   if(result)
-    close_one(connssl, data);
+    close_one(connssl, conn, sockindex);
   else if(connssl->connecting_state == ssl_connect_done) {
     connssl->state = ssl_connection_complete;
     connssl->connecting_state = ssl_connect_1;
@@ -976,11 +1216,8 @@
 
 void Curl_gskit_close(struct connectdata *conn, int sockindex)
 {
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(connssl->use)
-    close_one(connssl, data);
+  close_one(&conn->ssl[sockindex], conn, sockindex);
+  close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
 }
 
 
@@ -999,10 +1236,10 @@
   if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
     return 0;
 
-  close_one(connssl, data);
+  close_one(connssl, conn, sockindex);
   rc = 0;
-  what = Curl_socket_ready(conn->sock[sockindex],
-                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+  what = SOCKET_READABLE(conn->sock[sockindex],
+                         SSL_SHUTDOWN_TIMEOUT);
 
   for(;;) {
     if(what < 0) {
@@ -1031,7 +1268,7 @@
     if(nread <= 0)
       break;
 
-    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+    what = SOCKET_READABLE(conn->sock[sockindex], 0);
   }
 
   return rc;
diff --git a/lib/vtls/gskit.h b/lib/vtls/gskit.h
index 41483cb..e258a29 100644
--- a/lib/vtls/gskit.h
+++ b/lib/vtls/gskit.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +64,7 @@
 #define curlssl_version Curl_gskit_version
 #define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
 #define curlssl_data_pending(x,y) 0
-#define curlssl_random(x,y,z) -1
+#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
 
 #endif /* USE_GSKIT */
 
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 1c3e6b1..5249dd4 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -52,7 +52,7 @@
 #include "parsedate.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "warnless.h"
 #include "x509asn1.h"
 #include "curl_printf.h"
@@ -68,7 +68,7 @@
 #define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
 #endif
 #ifndef GNUTLS_INT_TO_POINTER_CAST
-#define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i))
+#define GNUTLS_INT_TO_POINTER_CAST(i) ((void *) (long) (i))
 #endif
 
 /* Enable GnuTLS debugging by defining GTLSDEBUG */
@@ -171,6 +171,16 @@
   return ret;
 }
 
+static ssize_t Curl_gtls_push_ssl(void *s, const void *buf, size_t len)
+{
+  return gnutls_record_send((gnutls_session_t) s, buf, len);
+}
+
+static ssize_t Curl_gtls_pull_ssl(void *s, void *buf, size_t len)
+{
+  return gnutls_record_recv((gnutls_session_t) s, buf, len);
+}
+
 /* Curl_gtls_init()
  *
  * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
@@ -251,7 +261,8 @@
   return loaded_file;
 }
 
-static void unload_file(gnutls_datum_t data) {
+static void unload_file(gnutls_datum_t data)
+{
   free(data.data);
 }
 
@@ -289,7 +300,7 @@
       curl_socket_t readfd = ssl_connect_2_reading==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd,
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
                                nonblocking?0:
                                timeout_ms?timeout_ms:1000);
       if(what < 0) {
@@ -356,9 +367,9 @@
 {
   if(!type || !type[0])
     return GNUTLS_X509_FMT_PEM;
-  if(Curl_raw_equal(type, "PEM"))
+  if(strcasecompare(type, "PEM"))
     return GNUTLS_X509_FMT_PEM;
-  if(Curl_raw_equal(type, "DER"))
+  if(strcasecompare(type, "DER"))
     return GNUTLS_X509_FMT_DER;
   return -1;
 }
@@ -371,6 +382,9 @@
   gnutls_session_t session;
   int rc;
   bool sni = TRUE; /* default is SNI enabled */
+  void *transport_ptr = NULL;
+  gnutls_push_func gnutls_transport_push = NULL;
+  gnutls_pull_func gnutls_transport_pull = NULL;
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
@@ -397,10 +411,13 @@
    requested in the priority string, so treat it specially
  */
 #define GNUTLS_SRP "+SRP"
-  const char* prioritylist;
+  const char *prioritylist;
   const char *err = NULL;
 #endif
 
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
   if(conn->ssl[sockindex].state == ssl_connection_complete)
     /* to make us tolerant against being called more than once for the
        same connection */
@@ -409,12 +426,11 @@
   if(!gtls_inited)
     Curl_gtls_init();
 
-  /* GnuTLS only supports SSLv3 and TLSv1 */
-  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
     failf(data, "GnuTLS does not support SSLv2");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+  else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
     sni = FALSE; /* SSLv3 has no SNI */
 
   /* allocate a cred struct */
@@ -425,8 +441,8 @@
   }
 
 #ifdef USE_TLS_SRP
-  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
-    infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+    infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
 
     rc = gnutls_srp_allocate_client_credentials(
            &conn->ssl[sockindex].srp_client_cred);
@@ -438,8 +454,8 @@
 
     rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
                                            srp_client_cred,
-                                           data->set.ssl.username,
-                                           data->set.ssl.password);
+                                           SSL_SET_OPTION(username),
+                                           SSL_SET_OPTION(password));
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_srp_set_client_cred() failed: %s",
             gnutls_strerror(rc));
@@ -448,64 +464,64 @@
   }
 #endif
 
-  if(data->set.ssl.CAfile) {
+  if(SSL_CONN_CONFIG(CAfile)) {
     /* set the trusted CA cert bundle file */
     gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
 
     rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
-                                                data->set.ssl.CAfile,
+                                                SSL_CONN_CONFIG(CAfile),
                                                 GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       infof(data, "error reading ca cert file %s (%s)\n",
-            data->set.ssl.CAfile, gnutls_strerror(rc));
-      if(data->set.ssl.verifypeer)
+            SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
+      if(SSL_CONN_CONFIG(verifypeer))
         return CURLE_SSL_CACERT_BADFILE;
     }
     else
-      infof(data, "found %d certificates in %s\n",
-            rc, data->set.ssl.CAfile);
+      infof(data, "found %d certificates in %s\n", rc,
+            SSL_CONN_CONFIG(CAfile));
   }
 
 #ifdef HAS_CAPATH
-  if(data->set.ssl.CApath) {
+  if(SSL_CONN_CONFIG(CApath)) {
     /* set the trusted CA cert directory */
     rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
-                                                data->set.ssl.CApath,
-                                                GNUTLS_X509_FMT_PEM);
+                                               SSL_CONN_CONFIG(CApath),
+                                               GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       infof(data, "error reading ca cert file %s (%s)\n",
-            data->set.ssl.CAfile, gnutls_strerror(rc));
-      if(data->set.ssl.verifypeer)
+            SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
+      if(SSL_CONN_CONFIG(verifypeer))
         return CURLE_SSL_CACERT_BADFILE;
     }
     else
       infof(data, "found %d certificates in %s\n",
-            rc, data->set.ssl.CApath);
+            rc, SSL_CONN_CONFIG(CApath));
   }
 #endif
 
 #ifdef CURL_CA_FALLBACK
   /* use system ca certificate store as fallback */
-  if(data->set.ssl.verifypeer &&
-     !(data->set.ssl.CAfile || data->set.ssl.CApath)) {
+  if(SSL_CONN_CONFIG(verifypeer) &&
+     !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
     gnutls_certificate_set_x509_system_trust(conn->ssl[sockindex].cred);
   }
 #endif
 
-  if(data->set.ssl.CRLfile) {
+  if(SSL_SET_OPTION(CRLfile)) {
     /* set the CRL list file */
     rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
-                                              data->set.ssl.CRLfile,
+                                              SSL_SET_OPTION(CRLfile),
                                               GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       failf(data, "error reading crl file %s (%s)",
-            data->set.ssl.CRLfile, gnutls_strerror(rc));
+            SSL_SET_OPTION(CRLfile), gnutls_strerror(rc));
       return CURLE_SSL_CRL_BADFILE;
     }
     else
       infof(data, "found %d CRL in %s\n",
-            rc, data->set.ssl.CRLfile);
+            rc, SSL_SET_OPTION(CRLfile));
   }
 
   /* Initialize TLS session as a client */
@@ -518,13 +534,13 @@
   /* convenient assign */
   session = conn->ssl[sockindex].session;
 
-  if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+  if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
-     (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+     (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
 #endif
      sni &&
-     (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
-                             strlen(conn->host.name)) < 0))
+     (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname,
+                             strlen(hostname)) < 0))
     infof(data, "WARNING: failed to configure server name indication (SNI) "
           "TLS extension\n");
 
@@ -545,13 +561,13 @@
   if(rc != GNUTLS_E_SUCCESS)
     return CURLE_SSL_CONNECT_ERROR;
 
-  if(data->set.ssl.cipher_list != NULL) {
+  if(SSL_CONN_CONFIG(cipher_list) != NULL) {
     failf(data, "can't pass a custom cipher list to older GnuTLS"
           " versions");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  switch (data->set.ssl.version) {
+  switch (SSL_CONN_CONFIG(version) {
     case CURL_SSLVERSION_SSLv3:
       protocol_priority[0] = GNUTLS_SSL3;
       break;
@@ -569,12 +585,16 @@
       break;
     case CURL_SSLVERSION_TLSv1_2:
       protocol_priority[0] = GNUTLS_TLS1_2;
-    break;
-      case CURL_SSLVERSION_SSLv2:
-    default:
+      break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_SSLv2:
       failf(data, "GnuTLS does not support SSLv2");
       return CURLE_SSL_CONNECT_ERROR;
-      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
   }
   rc = gnutls_protocol_set_priority(session, protocol_priority);
   if(rc != GNUTLS_E_SUCCESS) {
@@ -586,7 +606,7 @@
   /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
    * removed if a run-time error indicates that SRP is not supported by this
    * GnuTLS version */
-  switch (data->set.ssl.version) {
+  switch (SSL_CONN_CONFIG(version)) {
     case CURL_SSLVERSION_SSLv3:
       prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
       sni = false;
@@ -607,11 +627,15 @@
       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
                      "+VERS-TLS1.2:" GNUTLS_SRP;
       break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
     case CURL_SSLVERSION_SSLv2:
-    default:
       failf(data, "GnuTLS does not support SSLv2");
       return CURLE_SSL_CONNECT_ERROR;
-      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
   }
   rc = gnutls_priority_set_direct(session, prioritylist, &err);
   if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
@@ -661,8 +685,8 @@
   }
 #endif
 
-  if(data->set.str[STRING_CERT]) {
-    if(data->set.str[STRING_KEY_PASSWD]) {
+  if(SSL_SET_OPTION(cert)) {
+    if(SSL_SET_OPTION(key_passwd)) {
 #if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
       const unsigned int supported_key_encryption_algorithms =
         GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
@@ -671,11 +695,11 @@
         GNUTLS_PKCS_USE_PBES2_AES_256;
       rc = gnutls_certificate_set_x509_key_file2(
            conn->ssl[sockindex].cred,
-           data->set.str[STRING_CERT],
-           data->set.str[STRING_KEY] ?
-           data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
-           do_file_type(data->set.str[STRING_CERT_TYPE]),
-           data->set.str[STRING_KEY_PASSWD],
+           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) ?
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           do_file_type(SSL_SET_OPTION(cert_type)),
+           SSL_SET_OPTION(key_passwd),
            supported_key_encryption_algorithms);
       if(rc != GNUTLS_E_SUCCESS) {
         failf(data,
@@ -689,15 +713,14 @@
 #endif
     }
     else {
-      rc = gnutls_certificate_set_x509_key_file(
+      if(gnutls_certificate_set_x509_key_file(
            conn->ssl[sockindex].cred,
-           data->set.str[STRING_CERT],
-           data->set.str[STRING_KEY] ?
-           data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
-           do_file_type(data->set.str[STRING_CERT_TYPE]) );
-      if(rc != GNUTLS_E_SUCCESS) {
-        failf(data, "error reading X.509 key or certificate file: %s",
-              gnutls_strerror(rc));
+           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) ?
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           do_file_type(SSL_SET_OPTION(cert_type)) ) !=
+         GNUTLS_E_SUCCESS) {
+        failf(data, "error reading X.509 key or certificate file");
         return CURLE_SSL_CONNECT_ERROR;
       }
     }
@@ -705,7 +728,7 @@
 
 #ifdef USE_TLS_SRP
   /* put the credentials to the current session */
-  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
                                 conn->ssl[sockindex].srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
@@ -724,19 +747,30 @@
     }
   }
 
-  /* set the connection handle (file descriptor for the socket) */
-  gnutls_transport_set_ptr(session,
-                           GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
+  if(conn->proxy_ssl[sockindex].use) {
+    transport_ptr = conn->proxy_ssl[sockindex].session;
+    gnutls_transport_push = Curl_gtls_push_ssl;
+    gnutls_transport_pull = Curl_gtls_pull_ssl;
+  }
+  else {
+    /* file descriptor for the socket */
+    transport_ptr = GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]);
+    gnutls_transport_push = Curl_gtls_push;
+    gnutls_transport_pull = Curl_gtls_pull;
+  }
+
+  /* set the connection handle */
+  gnutls_transport_set_ptr(session, transport_ptr);
 
   /* register callback functions to send and receive data. */
-  gnutls_transport_set_push_function(session, Curl_gtls_push);
-  gnutls_transport_set_pull_function(session, Curl_gtls_pull);
+  gnutls_transport_set_push_function(session, gnutls_transport_push);
+  gnutls_transport_set_pull_function(session, gnutls_transport_pull);
 
   /* lowat must be set to zero when using custom push and pull functions. */
   gnutls_transport_set_lowat(session, 0);
 
 #ifdef HAS_OCSP
-  if(data->set.ssl.verifystatus) {
+  if(SSL_CONN_CONFIG(verifystatus)) {
     rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
@@ -747,12 +781,12 @@
 
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     void *ssl_sessionid;
     size_t ssl_idsize;
 
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) {
       /* we got a session id, use it! */
       gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
 
@@ -847,8 +881,9 @@
   gnutls_datum_t proto;
 #endif
   CURLcode result = CURLE_OK;
-
   gnutls_protocol_t version = gnutls_protocol_get_version(session);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 
   /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
   ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -866,13 +901,13 @@
 
   chainp = gnutls_certificate_get_peers(session, &cert_list_size);
   if(!chainp) {
-    if(data->set.ssl.verifypeer ||
-       data->set.ssl.verifyhost ||
-       data->set.ssl.issuercert) {
+    if(SSL_CONN_CONFIG(verifypeer) ||
+       SSL_CONN_CONFIG(verifyhost) ||
+       SSL_SET_OPTION(issuercert)) {
 #ifdef USE_TLS_SRP
-      if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
-         && data->set.ssl.username != NULL
-         && !data->set.ssl.verifypeer
+      if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
+         && SSL_SET_OPTION(username) != NULL
+         && !SSL_CONN_CONFIG(verifypeer)
          && gnutls_cipher_get(session)) {
         /* no peer cert, but auth is ok if we have SRP user and cipher and no
            peer verify */
@@ -905,7 +940,7 @@
     }
   }
 
-  if(data->set.ssl.verifypeer) {
+  if(SSL_CONN_CONFIG(verifypeer)) {
     /* This function will try to verify the peer's certificate and return its
        status (trusted, invalid etc.). The value of status should be one or
        more of the gnutls_certificate_status_t enumerated elements bitwise
@@ -921,10 +956,11 @@
 
     /* verify_status is a bitmask of gnutls_certificate_status bits */
     if(verify_status & GNUTLS_CERT_INVALID) {
-      if(data->set.ssl.verifypeer) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "server certificate verification failed. CAfile: %s "
-              "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
-              data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
+              "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
+              "none",
+              SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
         return CURLE_SSL_CACERT;
       }
       else
@@ -937,7 +973,7 @@
     infof(data, "\t server certificate verification SKIPPED\n");
 
 #ifdef HAS_OCSP
-  if(data->set.ssl.verifystatus) {
+  if(SSL_CONN_CONFIG(verifystatus)) {
     if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
       gnutls_datum_t status_request;
       gnutls_ocsp_resp_t ocsp_resp;
@@ -1049,21 +1085,21 @@
        gnutls_x509_crt_t format */
     gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
 
-  if(data->set.ssl.issuercert) {
+  if(SSL_SET_OPTION(issuercert)) {
     gnutls_x509_crt_init(&x509_issuer);
-    issuerp = load_file(data->set.ssl.issuercert);
+    issuerp = load_file(SSL_SET_OPTION(issuercert));
     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
     rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
     gnutls_x509_crt_deinit(x509_issuer);
     unload_file(issuerp);
     if(rc <= 0) {
       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
-            data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+            SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_ISSUER_ERROR;
     }
     infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
-          data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+          SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
   }
 
   size=sizeof(certbuf);
@@ -1082,7 +1118,7 @@
      in RFC2818 (HTTPS), which takes into account wildcards, and the subject
      alternative name PKIX extension. Returns non zero on success, and zero on
      failure. */
-  rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
+  rc = gnutls_x509_crt_check_hostname(x509_cert, hostname);
 #if GNUTLS_VERSION_NUMBER < 0x030306
   /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
      addresses. */
@@ -1098,10 +1134,10 @@
     int i;
     int ret = 0;
 
-    if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
+    if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
       addrlen = 4;
 #ifdef ENABLE_IPV6
-    else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
+    else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0)
       addrlen = 16;
 #endif
 
@@ -1126,15 +1162,18 @@
   }
 #endif
   if(!rc) {
-    if(data->set.ssl.verifyhost) {
+    const char * const dispname = SSL_IS_PROXY() ?
+      conn->http_proxy.host.dispname : conn->host.dispname;
+
+    if(SSL_CONN_CONFIG(verifyhost)) {
       failf(data, "SSL: certificate subject name (%s) does not match "
-            "target host name '%s'", certbuf, conn->host.dispname);
+            "target host name '%s'", certbuf, dispname);
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_PEER_FAILED_VERIFICATION;
     }
     else
       infof(data, "\t common name: %s (does not match '%s')\n",
-            certbuf, conn->host.dispname);
+            certbuf, dispname);
   }
   else
     infof(data, "\t common name: %s (matched)\n", certbuf);
@@ -1143,7 +1182,7 @@
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
 
   if(certclock == (time_t)-1) {
-    if(data->set.ssl.verifypeer) {
+    if(SSL_CONN_CONFIG(verifypeer)) {
       failf(data, "server cert expiration date verify failed");
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
@@ -1153,7 +1192,7 @@
   }
   else {
     if(certclock < time(NULL)) {
-      if(data->set.ssl.verifypeer) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "server certificate expiration date has passed.");
         gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
@@ -1168,7 +1207,7 @@
   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
 
   if(certclock == (time_t)-1) {
-    if(data->set.ssl.verifypeer) {
+    if(SSL_CONN_CONFIG(verifypeer)) {
       failf(data, "server cert activation date verify failed");
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
@@ -1178,7 +1217,7 @@
   }
   else {
     if(certclock > time(NULL)) {
-      if(data->set.ssl.verifypeer) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "server certificate not activated yet.");
         gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
@@ -1270,7 +1309,7 @@
   conn->recv[sockindex] = gtls_recv;
   conn->send[sockindex] = gtls_send;
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     /* we always unconditionally get the session id here, as even if we
        already got it from the cache and asked to use it in the connection, it
        might've been rejected and then a new one is in use now and we need to
@@ -1289,7 +1328,8 @@
       gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
 
       Curl_ssl_sessionid_lock(conn);
-      incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
+      incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL,
+                                        sockindex));
       if(incache) {
         /* there was one before in the cache, so instead of risking that the
            previous one was rejected, we just kill that and store the new */
@@ -1297,7 +1337,8 @@
       }
 
       /* store this session id */
-      result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
+      result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize,
+                                     sockindex);
       Curl_ssl_sessionid_unlock(conn);
       if(result) {
         free(connect_sessionid);
@@ -1379,6 +1420,20 @@
   return CURLE_OK;
 }
 
+bool Curl_gtls_data_pending(const struct connectdata *conn, int connindex)
+{
+  bool res = FALSE;
+  if(conn->ssl[connindex].session &&
+     0 != gnutls_record_check_pending(conn->ssl[connindex].session))
+    res = TRUE;
+
+  if(conn->proxy_ssl[connindex].session &&
+     0 != gnutls_record_check_pending(conn->proxy_ssl[connindex].session))
+    res = TRUE;
+
+  return res;
+}
+
 static ssize_t gtls_send(struct connectdata *conn,
                          int sockindex,
                          const void *mem,
@@ -1398,29 +1453,29 @@
   return rc;
 }
 
-static void close_one(struct connectdata *conn,
-                      int idx)
+static void close_one(struct ssl_connect_data *ssl)
 {
-  if(conn->ssl[idx].session) {
-    gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
-    gnutls_deinit(conn->ssl[idx].session);
-    conn->ssl[idx].session = NULL;
+  if(ssl->session) {
+    gnutls_bye(ssl->session, GNUTLS_SHUT_RDWR);
+    gnutls_deinit(ssl->session);
+    ssl->session = NULL;
   }
-  if(conn->ssl[idx].cred) {
-    gnutls_certificate_free_credentials(conn->ssl[idx].cred);
-    conn->ssl[idx].cred = NULL;
+  if(ssl->cred) {
+    gnutls_certificate_free_credentials(ssl->cred);
+    ssl->cred = NULL;
   }
 #ifdef USE_TLS_SRP
-  if(conn->ssl[idx].srp_client_cred) {
-    gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
-    conn->ssl[idx].srp_client_cred = NULL;
+  if(ssl->srp_client_cred) {
+    gnutls_srp_free_client_credentials(ssl->srp_client_cred);
+    ssl->srp_client_cred = NULL;
   }
 #endif
 }
 
 void Curl_gtls_close(struct connectdata *conn, int sockindex)
 {
-  close_one(conn, sockindex);
+  close_one(&conn->ssl[sockindex]);
+  close_one(&conn->proxy_ssl[sockindex]);
 }
 
 /*
@@ -1445,8 +1500,8 @@
 
   if(conn->ssl[sockindex].session) {
     while(!done) {
-      int what = Curl_socket_ready(conn->sock[sockindex],
-                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+      int what = SOCKET_READABLE(conn->sock[sockindex],
+                                 SSL_SHUTDOWN_TIMEOUT);
       if(what > 0) {
         /* Something to read, let's do it and hope that it is the close
            notify alert from the server */
@@ -1486,8 +1541,8 @@
   gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
 
 #ifdef USE_TLS_SRP
-  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
-     && data->set.ssl.username != NULL)
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
+     && SSL_SET_OPTION(username) != NULL)
     gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
 #endif
 
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index e0a95a7..e3d5853 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -34,6 +34,8 @@
 CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
                                        int sockindex,
                                        bool *done);
+bool Curl_gtls_data_pending(const struct connectdata *conn,
+                            int connindex);
 
  /* close a SSL connection */
 void Curl_gtls_close(struct connectdata *conn, int sockindex);
@@ -81,7 +83,7 @@
 #define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_gtls_version
 #define curlssl_check_cxn(x) ((void)x, -1)
-#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_data_pending(x,y) Curl_gtls_data_pending(x,y)
 #define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
 #define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index a1e7d23..c428a21 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -31,11 +31,15 @@
 
 #ifdef USE_MBEDTLS
 
+#include <mbedtls/version.h>
+#if MBEDTLS_VERSION_NUMBER >= 0x02040000
+#include <mbedtls/net_sockets.h>
+#else
 #include <mbedtls/net.h>
+#endif
 #include <mbedtls/ssl.h>
 #include <mbedtls/certs.h>
 #include <mbedtls/x509.h>
-#include <mbedtls/version.h>
 
 #include <mbedtls/error.h>
 #include <mbedtls/entropy.h>
@@ -50,7 +54,6 @@
 #include "parsedate.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#include "rawstr.h"
 #include "polarssl_threadlock.h"
 
 /* The last 3 #include files should be in this order */
@@ -160,13 +163,21 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
 
   int ret = -1;
   char errorbuf[128];
   errorbuf[0]=0;
 
   /* mbedTLS only supports SSLv3 and TLSv1 */
-  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
     failf(data, "mbedTLS does not support SSLv2");
     return CURLE_SSL_CONNECT_ERROR;
   }
@@ -202,34 +213,32 @@
   /* Load the trusted CA */
   mbedtls_x509_crt_init(&connssl->cacert);
 
-  if(data->set.str[STRING_SSL_CAFILE]) {
-    ret = mbedtls_x509_crt_parse_file(&connssl->cacert,
-                                      data->set.str[STRING_SSL_CAFILE]);
+  if(ssl_cafile) {
+    ret = mbedtls_x509_crt_parse_file(&connssl->cacert, ssl_cafile);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
 #endif /* MBEDTLS_ERROR_C */
       failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+            ssl_cafile, -ret, errorbuf);
 
-      if(data->set.ssl.verifypeer)
+      if(verifypeer)
         return CURLE_SSL_CACERT_BADFILE;
     }
   }
 
-  if(data->set.str[STRING_SSL_CAPATH]) {
-    ret = mbedtls_x509_crt_parse_path(&connssl->cacert,
-                                      data->set.str[STRING_SSL_CAPATH]);
+  if(ssl_capath) {
+    ret = mbedtls_x509_crt_parse_path(&connssl->cacert, ssl_capath);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
 #endif /* MBEDTLS_ERROR_C */
       failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+            ssl_capath, -ret, errorbuf);
 
-      if(data->set.ssl.verifypeer)
+      if(verifypeer)
         return CURLE_SSL_CACERT_BADFILE;
     }
   }
@@ -237,16 +246,15 @@
   /* Load the client certificate */
   mbedtls_x509_crt_init(&connssl->clicert);
 
-  if(data->set.str[STRING_CERT]) {
-    ret = mbedtls_x509_crt_parse_file(&connssl->clicert,
-                                      data->set.str[STRING_CERT]);
+  if(ssl_cert) {
+    ret = mbedtls_x509_crt_parse_file(&connssl->clicert, ssl_cert);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
 #endif /* MBEDTLS_ERROR_C */
       failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
-            data->set.str[STRING_CERT], -ret, errorbuf);
+            ssl_cert, -ret, errorbuf);
 
       return CURLE_SSL_CERTPROBLEM;
     }
@@ -255,9 +263,9 @@
   /* Load the client private key */
   mbedtls_pk_init(&connssl->pk);
 
-  if(data->set.str[STRING_KEY]) {
-    ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY],
-                                   data->set.str[STRING_KEY_PASSWD]);
+  if(SSL_SET_OPTION(key)) {
+    ret = mbedtls_pk_parse_keyfile(&connssl->pk, SSL_SET_OPTION(key),
+                                   SSL_SET_OPTION(key_passwd));
     if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
       ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
 
@@ -266,7 +274,7 @@
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
 #endif /* MBEDTLS_ERROR_C */
       failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
-            data->set.str[STRING_KEY], -ret, errorbuf);
+            SSL_SET_OPTION(key), -ret, errorbuf);
 
       return CURLE_SSL_CERTPROBLEM;
     }
@@ -275,23 +283,21 @@
   /* Load the CRL */
   mbedtls_x509_crl_init(&connssl->crl);
 
-  if(data->set.str[STRING_SSL_CRLFILE]) {
-    ret = mbedtls_x509_crl_parse_file(&connssl->crl,
-                                      data->set.str[STRING_SSL_CRLFILE]);
+  if(ssl_crlfile) {
+    ret = mbedtls_x509_crl_parse_file(&connssl->crl, ssl_crlfile);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
 #endif /* MBEDTLS_ERROR_C */
       failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+            ssl_crlfile, -ret, errorbuf);
 
       return CURLE_SSL_CRL_BADFILE;
     }
   }
 
-  infof(data, "mbedTLS: Connecting to %s:%d\n",
-        conn->host.name, conn->remote_port);
+  infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port);
 
   mbedtls_ssl_config_init(&connssl->config);
 
@@ -313,7 +319,7 @@
   mbedtls_ssl_conf_cert_profile(&connssl->config,
                                 &mbedtls_x509_crt_profile_fr);
 
-  switch(data->set.ssl.version) {
+  switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
@@ -348,8 +354,11 @@
                                  MBEDTLS_SSL_MINOR_VERSION_3);
     infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
     break;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "mbedTLS: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
   default:
-    failf(data, "mbedTLS: Unsupported SSL protocol version");
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
@@ -366,11 +375,11 @@
                                 mbedtls_ssl_list_ciphersuites());
 
   /* Check if there's a cached ID we can/should use here! */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     void *old_session = NULL;
 
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
+    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
       ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
       if(ret) {
         Curl_ssl_sessionid_unlock(conn);
@@ -386,11 +395,11 @@
                             &connssl->cacert,
                             &connssl->crl);
 
-  if(data->set.str[STRING_KEY]) {
+  if(SSL_SET_OPTION(key)) {
     mbedtls_ssl_conf_own_cert(&connssl->config,
                               &connssl->clicert, &connssl->pk);
   }
-  if(mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+  if(mbedtls_ssl_set_hostname(&connssl->ssl, hostname)) {
     /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
        the name to set in the SNI extension. So even if curl connects to a
        host specified as an IP address, this function must be used. */
@@ -420,7 +429,15 @@
 #endif
 
 #ifdef MBEDTLS_DEBUG
+  /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
   mbedtls_ssl_conf_dbg(&connssl->config, mbed_debug, data);
+  /* - 0 No debug
+   * - 1 Error
+   * - 2 State change
+   * - 3 Informational
+   * - 4 Verbose
+   */
+  mbedtls_debug_set_threshold(4);
 #endif
 
   connssl->connecting_state = ssl_connect_2;
@@ -438,7 +455,7 @@
   const mbedtls_x509_crt *peercert;
 
 #ifdef HAS_ALPN
-  const char* next_protocol;
+  const char *next_protocol;
 #endif
 
   char errorbuf[128];
@@ -472,7 +489,7 @@
 
   ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
 
-  if(ret && data->set.ssl.verifypeer) {
+  if(ret && SSL_CONN_CONFIG(verifypeer)) {
     if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
       failf(data, "Cert verify failed: BADCERT_EXPIRED");
 
@@ -599,7 +616,7 @@
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     int ret;
     mbedtls_ssl_session *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -618,10 +635,10 @@
 
     /* If there's already a matching session in the cache, delete it */
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
+    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
       Curl_ssl_delsessionid(conn, old_ssl_sessionid);
 
-    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
+    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
     Curl_ssl_sessionid_unlock(conn);
     if(retcode) {
       free(our_ssl_sessionid);
@@ -765,7 +782,8 @@
       curl_socket_t readfd = ssl_connect_2_reading==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking ? 0 : timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index ad33f25..91b8e05 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -34,7 +34,7 @@
 #include "formdata.h" /* for the boundary function */
 #include "url.h" /* for the ssl config check function */
 #include "connect.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "select.h"
 #include "vtls.h"
 #include "llist.h"
@@ -64,7 +64,7 @@
 #include <ocsp.h>
 #endif
 
-#include "rawstr.h"
+#include "strcase.h"
 #include "warnless.h"
 #include "x509asn1.h"
 
@@ -78,13 +78,12 @@
 #define SLOTSIZE 13
 
 PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
-
-PRLock * nss_initlock = NULL;
-PRLock * nss_crllock = NULL;
-struct curl_llist *nss_crl_list = NULL;
-NSSInitContext * nss_context = NULL;
-
-volatile int initialized = 0;
+static PRLock *nss_initlock = NULL;
+static PRLock *nss_crllock = NULL;
+static PRLock *nss_findslot_lock = NULL;
+static struct curl_llist *nss_crl_list = NULL;
+static NSSInitContext *nss_context = NULL;
+static volatile int initialized = 0;
 
 typedef struct {
   const char *name;
@@ -150,7 +149,7 @@
   {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
   {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
   {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
-  {"echde_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
+  {"ecdhe_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
   {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
   {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
   {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
@@ -180,16 +179,35 @@
   {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
   {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
 #endif
+#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+  /* cipher suites using SHA384 */
+  {"rsa_aes_256_gcm_sha_384",         TLS_RSA_WITH_AES_256_GCM_SHA384},
+  {"dhe_rsa_aes_256_gcm_sha_384",     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
+  {"dhe_dss_aes_256_gcm_sha_384",     TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
+  {"ecdhe_ecdsa_aes_256_sha_384",     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
+  {"ecdhe_rsa_aes_256_sha_384",       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
+  {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
+  {"ecdhe_rsa_aes_256_gcm_sha_384",   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+#endif
+#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+  /* chacha20-poly1305 cipher suites */
+ {"ecdhe_rsa_chacha20_poly1305_sha_256",
+     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"ecdhe_ecdsa_chacha20_poly1305_sha_256",
+     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"dhe_rsa_chacha20_poly1305_sha_256",
+     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+#endif
 };
 
-static const char* pem_library = "libnsspem.so";
-SECMODModule* mod = NULL;
+static const char *pem_library = "libnsspem.so";
+static SECMODModule *mod = NULL;
 
 /* NSPR I/O layer we use to detect blocking direction during SSL handshake */
 static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
 static PRIOMethods nspr_io_methods;
 
-static const char* nss_error_to_name(PRErrorCode code)
+static const char *nss_error_to_name(PRErrorCode code)
 {
   const char *name = PR_ErrorToName(code);
   if(name)
@@ -243,7 +261,7 @@
     found = PR_FALSE;
 
     for(i=0; i<NUM_OF_CIPHERS; i++) {
-      if(Curl_raw_equal(cipher, cipherlist[i].name)) {
+      if(strcasecompare(cipher, cipherlist[i].name)) {
         cipher_state[i] = PR_TRUE;
         found = PR_TRUE;
         break;
@@ -319,9 +337,8 @@
  * should be later deallocated using free().  If the OOM failure occurs, we
  * return NULL, too.
  */
-static char* dup_nickname(struct Curl_easy *data, enum dupstring cert_kind)
+static char *dup_nickname(struct Curl_easy *data, const char *str)
 {
-  const char *str = data->set.str[cert_kind];
   const char *n;
 
   if(!is_file(str))
@@ -340,6 +357,19 @@
   return NULL;
 }
 
+/* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
+ * in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN.  For more
+ * details, go to <https://bugzilla.mozilla.org/1297397>.
+ */
+static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
+{
+  PK11SlotInfo *slot;
+  PR_Lock(nss_initlock);
+  slot = PK11_FindSlotByName(slot_name);
+  PR_Unlock(nss_initlock);
+  return slot;
+}
+
 /* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
  * the call succeeds, append the object handle to the list of objects so that
  * the object can be destroyed in Curl_nss_close(). */
@@ -362,7 +392,7 @@
   if(!slot_name)
     return CURLE_OUT_OF_MEMORY;
 
-  slot = PK11_FindSlotByName(slot_name);
+  slot = nss_find_slot_by_name(slot_name);
   free(slot_name);
   if(!slot)
     return result;
@@ -483,7 +513,7 @@
   return CURLE_OK;
 }
 
-static CURLcode nss_load_crl(const char* crlfilename)
+static CURLcode nss_load_crl(const char *crlfilename)
 {
   PRFileDesc *infile;
   PRFileInfo  info;
@@ -509,7 +539,7 @@
     goto fail;
 
   /* place a trailing zero right after the visible data */
-  body = (char*)filedata.data;
+  body = (char *)filedata.data;
   body[--filedata.len] = '\0';
 
   body = strstr(body, "-----BEGIN");
@@ -554,6 +584,7 @@
   SECStatus status;
   CURLcode result;
   struct ssl_connect_data *ssl = conn->ssl;
+  struct Curl_easy *data = conn->data;
 
   (void)sockindex; /* unused */
 
@@ -563,7 +594,7 @@
     return result;
   }
 
-  slot = PK11_FindSlotByName("PEM Token #1");
+  slot = nss_find_slot_by_name("PEM Token #1");
   if(!slot)
     return CURLE_SSL_CERTPROBLEM;
 
@@ -571,8 +602,7 @@
   SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
   PK11_IsPresent(slot);
 
-  status = PK11_Authenticate(slot, PR_TRUE,
-                             conn->data->set.str[STRING_KEY_PASSWD]);
+  status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
   PK11_FreeSlot(slot);
 
   return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
@@ -633,7 +663,7 @@
   return CURLE_OK;
 }
 
-static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
+static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
 {
   (void)slot; /* unused */
 
@@ -651,7 +681,7 @@
   struct connectdata *conn = (struct connectdata *)arg;
 
 #ifdef SSL_ENABLE_OCSP_STAPLING
-  if(conn->data->set.ssl.verifystatus) {
+  if(SSL_CONN_CONFIG(verifystatus)) {
     SECStatus cacheResult;
 
     const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
@@ -677,7 +707,7 @@
   }
 #endif
 
-  if(!conn->data->set.ssl.verifypeer) {
+  if(!SSL_CONN_CONFIG(verifypeer)) {
     infof(conn->data, "skipping SSL peer certificate verification\n");
     return SECSuccess;
   }
@@ -703,6 +733,11 @@
   if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
 
     switch(state) {
+#if NSSVERNUM >= 0x031a00 /* 3.26.0 */
+    /* used by NSS internally to implement 0-RTT */
+    case SSL_NEXT_PROTO_EARLY_VALUE:
+      /* fall through! */
+#endif
     case SSL_NEXT_PROTO_NO_SUPPORT:
     case SSL_NEXT_PROTO_NO_OVERLAP:
       infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
@@ -897,9 +932,12 @@
   CERTCertificate *cert;
 
   /* remember the cert verification result */
-  data->set.ssl.certverifyresult = err;
+  if(SSL_IS_PROXY())
+    data->set.proxy_ssl.certverifyresult = err;
+  else
+    data->set.ssl.certverifyresult = err;
 
-  if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost)
+  if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
     /* we are asked not to verify the host name */
     return SECSuccess;
 
@@ -1004,16 +1042,16 @@
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
   struct Curl_easy *data = connssl->data;
   const char *nickname = connssl->client_nickname;
+  static const char pem_slotname[] = "PEM Token #1";
 
   if(connssl->obj_clicert) {
     /* use the cert/key provided by PEM reader */
-    static const char pem_slotname[] = "PEM Token #1";
     SECItem cert_der = { 0, NULL, 0 };
     void *proto_win = SSL_RevealPinArg(sock);
     struct CERTCertificateStr *cert;
     struct SECKEYPrivateKeyStr *key;
 
-    PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
+    PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
     if(NULL == slot) {
       failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
       return SECFailure;
@@ -1069,6 +1107,12 @@
   if(NULL == nickname)
     nickname = "[unknown]";
 
+  if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
+    failf(data, "NSS: refusing previously loaded certificate from file: %s",
+          nickname);
+    return SECFailure;
+  }
+
   if(NULL == *pRetKey) {
     failf(data, "NSS: private key not found for certificate: %s", nickname);
     return SECFailure;
@@ -1243,6 +1287,7 @@
     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
     nss_initlock = PR_NewLock();
     nss_crllock = PR_NewLock();
+    nss_findslot_lock = PR_NewLock();
   }
 
   /* We will actually initialize NSS later */
@@ -1297,6 +1342,7 @@
 
   PR_DestroyLock(nss_initlock);
   PR_DestroyLock(nss_crllock);
+  PR_DestroyLock(nss_findslot_lock);
   nss_initlock = NULL;
 
   initialized = 0;
@@ -1328,38 +1374,57 @@
   return -1;  /* connection status unknown */
 }
 
-/*
- * This function is called when an SSL connection is closed.
- */
-void Curl_nss_close(struct connectdata *conn, int sockindex)
+static void nss_close(struct ssl_connect_data *connssl)
 {
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  /* before the cleanup, check whether we are using a client certificate */
+  const bool client_cert = (connssl->client_nickname != NULL)
+    || (connssl->obj_clicert != NULL);
+
+  free(connssl->client_nickname);
+  connssl->client_nickname = NULL;
+
+  /* destroy all NSS objects in order to avoid failure of NSS shutdown */
+  Curl_llist_destroy(connssl->obj_list, NULL);
+  connssl->obj_list = NULL;
+  connssl->obj_clicert = NULL;
 
   if(connssl->handle) {
-    /* NSS closes the socket we previously handed to it, so we must mark it
-       as closed to avoid double close */
-    fake_sclose(conn->sock[sockindex]);
-    conn->sock[sockindex] = CURL_SOCKET_BAD;
-
-    if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
+    if(client_cert)
       /* A server might require different authentication based on the
        * particular path being requested by the client.  To support this
        * scenario, we must ensure that a connection will never reuse the
        * authentication data from a previous connection. */
       SSL_InvalidateSession(connssl->handle);
 
-    free(connssl->client_nickname);
-    connssl->client_nickname = NULL;
-    /* destroy all NSS objects in order to avoid failure of NSS shutdown */
-    Curl_llist_destroy(connssl->obj_list, NULL);
-    connssl->obj_list = NULL;
-    connssl->obj_clicert = NULL;
-
     PR_Close(connssl->handle);
     connssl->handle = NULL;
   }
 }
 
+/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_nss_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
+
+  if(connssl->handle || connssl_proxy->handle) {
+    /* NSS closes the socket we previously handed to it, so we must mark it
+       as closed to avoid double close */
+    fake_sclose(conn->sock[sockindex]);
+    conn->sock[sockindex] = CURL_SOCKET_BAD;
+  }
+
+  if(connssl->handle)
+    /* nss_close(connssl) will transitively close also connssl_proxy->handle
+       if both are used. Clear it to avoid a double close leading to crash. */
+    connssl_proxy->handle = NULL;
+
+  nss_close(connssl);
+  nss_close(connssl_proxy);
+}
+
 /* return true if NSS can provide error code (and possibly msg) for the
    error */
 static bool is_nss_error(CURLcode err)
@@ -1398,8 +1463,8 @@
                                          int sockindex)
 {
   struct Curl_easy *data = conn->data;
-  const char *cafile = data->set.ssl.CAfile;
-  const char *capath = data->set.ssl.CApath;
+  const char *cafile = SSL_CONN_CONFIG(CAfile);
+  const char *capath = SSL_CONN_CONFIG(CApath);
 
   if(cafile) {
     CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
@@ -1447,13 +1512,22 @@
 }
 
 static CURLcode nss_init_sslver(SSLVersionRange *sslver,
-                                struct Curl_easy *data)
+                                struct Curl_easy *data,
+                                struct connectdata *conn)
 {
-  switch(data->set.ssl.version) {
-  default:
+  switch (SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
+    /* map CURL_SSLVERSION_DEFAULT to NSS default */
+    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
+      return CURLE_SSL_CONNECT_ERROR;
+    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
+    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
+      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
   case CURL_SSLVERSION_TLSv1:
     sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    /* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
     sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
 #elif defined SSL_LIBRARY_VERSION_TLS_1_1
@@ -1493,6 +1567,18 @@
     return CURLE_OK;
 #endif
     break;
+
+  case CURL_SSLVERSION_TLSv1_3:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_3;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_3;
+    return CURLE_OK;
+#endif
+    break;
+
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   failf(data, "TLS minor version cannot be set");
@@ -1550,6 +1636,7 @@
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   CURLcode result;
+  bool second_layer = FALSE;
 
   SSLVersionRange sslver = {
     SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
@@ -1608,18 +1695,18 @@
     goto error;
 
   /* do not use SSL cache if disabled or we are not going to verify peer */
-  ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
-    PR_FALSE : PR_TRUE;
+  ssl_no_cache = (data->set.general_ssl.sessionid
+                  && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
   if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
     goto error;
 
   /* enable/disable the requested SSL version(s) */
-  if(nss_init_sslver(&sslver, data) != CURLE_OK)
+  if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
     goto error;
   if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
     goto error;
 
-  ssl_cbc_random_iv = !data->set.ssl_enable_beast;
+  ssl_cbc_random_iv = !SSL_SET_OPTION(enable_beast);
 #ifdef SSL_CBC_RANDOM_IV
   /* unless the user explicitly asks to allow the protocol vulnerability, we
      use the work-around */
@@ -1631,14 +1718,14 @@
     infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
 #endif
 
-  if(data->set.ssl.cipher_list) {
-    if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
+  if(SSL_CONN_CONFIG(cipher_list)) {
+    if(set_ciphers(data, model, SSL_CONN_CONFIG(cipher_list)) != SECSuccess) {
       result = CURLE_SSL_CIPHER;
       goto error;
     }
   }
 
-  if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
+  if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost))
     infof(data, "warning: ignoring value of ssl.verifyhost\n");
 
   /* bypass the default SSL_AuthCertificate() hook in case we do not want to
@@ -1646,14 +1733,19 @@
   if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
     goto error;
 
-  data->set.ssl.certverifyresult=0; /* not checked yet */
+  /* not checked yet */
+  if(SSL_IS_PROXY())
+    data->set.proxy_ssl.certverifyresult = 0;
+  else
+    data->set.ssl.certverifyresult = 0;
+
   if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
     goto error;
 
   if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
     goto error;
 
-  if(data->set.ssl.verifypeer) {
+  if(SSL_CONN_CONFIG(verifypeer)) {
     const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
     if(rv) {
       result = rv;
@@ -1661,24 +1753,24 @@
     }
   }
 
-  if(data->set.ssl.CRLfile) {
-    const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
+  if(SSL_SET_OPTION(CRLfile)) {
+    const CURLcode rv = nss_load_crl(SSL_SET_OPTION(CRLfile));
     if(rv) {
       result = rv;
       goto error;
     }
-    infof(data, "  CRLfile: %s\n", data->set.ssl.CRLfile);
+    infof(data, "  CRLfile: %s\n", SSL_SET_OPTION(CRLfile));
   }
 
-  if(data->set.str[STRING_CERT]) {
-    char *nickname = dup_nickname(data, STRING_CERT);
+  if(SSL_SET_OPTION(cert)) {
+    char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
     if(nickname) {
       /* we are not going to use libnsspem.so to read the client cert */
       connssl->obj_clicert = NULL;
     }
     else {
-      CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
-                               data->set.str[STRING_KEY]);
+      CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
+                               SSL_SET_OPTION(key));
       if(rv) {
         /* failf() is already done in cert_stuff() */
         result = rv;
@@ -1698,15 +1790,24 @@
     goto error;
   }
 
-  /* wrap OS file descriptor by NSPR's file descriptor abstraction */
-  nspr_io = PR_ImportTCPSocket(sockfd);
-  if(!nspr_io)
-    goto error;
+  if(conn->proxy_ssl[sockindex].use) {
+    DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
+    DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
+    nspr_io = conn->proxy_ssl[sockindex].handle;
+    second_layer = TRUE;
+  }
+  else {
+    /* wrap OS file descriptor by NSPR's file descriptor abstraction */
+    nspr_io = PR_ImportTCPSocket(sockfd);
+    if(!nspr_io)
+      goto error;
+  }
 
   /* create our own NSPR I/O layer */
   nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
   if(!nspr_io_stub) {
-    PR_Close(nspr_io);
+    if(!second_layer)
+      PR_Close(nspr_io);
     goto error;
   }
 
@@ -1715,7 +1816,8 @@
 
   /* push our new layer to the NSPR I/O stack */
   if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
-    PR_Close(nspr_io);
+    if(!second_layer)
+      PR_Close(nspr_io);
     PR_Close(nspr_io_stub);
     goto error;
   }
@@ -1723,7 +1825,8 @@
   /* import our model socket onto the current I/O stack */
   connssl->handle = SSL_ImportFD(model, nspr_io);
   if(!connssl->handle) {
-    PR_Close(nspr_io);
+    if(!second_layer)
+      PR_Close(nspr_io);
     goto error;
   }
 
@@ -1731,12 +1834,12 @@
   model = NULL;
 
   /* This is the password associated with the cert that we're using */
-  if(data->set.str[STRING_KEY_PASSWD]) {
-    SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
+  if(SSL_SET_OPTION(key_passwd)) {
+    SSL_SetPKCS11PinArg(connssl->handle, SSL_SET_OPTION(key_passwd));
   }
 
 #ifdef SSL_ENABLE_OCSP_STAPLING
-  if(data->set.ssl.verifystatus) {
+  if(SSL_CONN_CONFIG(verifystatus)) {
     if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
         != SECSuccess)
       goto error;
@@ -1796,11 +1899,14 @@
     goto error;
 
   /* propagate hostname to the TLS layer */
-  if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
+  if(SSL_SetURL(connssl->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
+                conn->host.name) != SECSuccess)
     goto error;
 
   /* prevent NSS from re-using the session for a different hostname */
-  if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess)
+  if(SSL_SetSockPeerID(connssl->handle, SSL_IS_PROXY() ?
+                       conn->http_proxy.host.name : conn->host.name)
+     != SECSuccess)
     goto error;
 
   return CURLE_OK;
@@ -1818,6 +1924,8 @@
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_SSL_CONNECT_ERROR;
   PRUint32 timeout;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
 
   /* check timeout situation */
   const long time_left = Curl_timeleft(data, NULL, TRUE);
@@ -1833,9 +1941,9 @@
     if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
       /* blocking direction is updated by nss_update_connecting_state() */
       return CURLE_AGAIN;
-    else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+    else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
       result = CURLE_PEER_FAILED_VERIFICATION;
-    else if(conn->data->set.ssl.certverifyresult!=0)
+    else if(*certverifyresult != 0)
       result = CURLE_SSL_CACERT;
     goto error;
   }
@@ -1844,11 +1952,11 @@
   if(result)
     goto error;
 
-  if(data->set.str[STRING_SSL_ISSUERCERT]) {
+  if(SSL_SET_OPTION(issuercert)) {
     SECStatus ret = SECFailure;
-    char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
+    char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
     if(nickname) {
-      /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
+      /* we support only nicknames in case of issuercert for now */
       ret = check_issuer_cert(connssl->handle, nickname);
       free(nickname);
     }
@@ -1882,8 +1990,11 @@
   const bool blocking = (done == NULL);
   CURLcode result;
 
-  if(connssl->state == ssl_connection_complete)
+  if(connssl->state == ssl_connection_complete) {
+    if(!blocking)
+      *done = TRUE;
     return CURLE_OK;
+  }
 
   if(connssl->connecting_state == ssl_connect_1) {
     result = nss_setup_connect(conn, sockindex);
@@ -2070,7 +2181,8 @@
 #endif
 }
 
-bool Curl_nss_false_start(void) {
+bool Curl_nss_false_start(void)
+{
 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
   return TRUE;
 #else
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 3027ca3..af4afe8 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -46,10 +46,9 @@
 #include "openssl.h"
 #include "connect.h"
 #include "slist.h"
-#include "strequal.h"
 #include "select.h"
 #include "vtls.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "hostcheck.h"
 #include "curl_printf.h"
 
@@ -95,11 +94,6 @@
 
 #if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
 #define HAVE_ERR_REMOVE_THREAD_STATE 1
-#if (OPENSSL_VERSION_NUMBER >= 0x10100004L) && \
-  !defined(LIBRESSL_VERSION_NUMBER)
-/* OpenSSL 1.1.0 deprecates the function */
-#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1
-#endif
 #endif
 
 #if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
@@ -110,11 +104,28 @@
 
 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
   !defined(LIBRESSL_VERSION_NUMBER)
-#define SSLeay_add_ssl_algorithms() SSL_library_init()
 #define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
 #define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
 #define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */
 #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
+#define CONST_EXTS const
+#define CONST_ASN1_BIT_STRING const
+#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1
+#else
+/* For OpenSSL before 1.1.0 */
+#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
+#define X509_get0_notBefore(x) X509_get_notBefore(x)
+#define X509_get0_notAfter(x) X509_get_notAfter(x)
+#define CONST_EXTS /* nope */
+#define CONST_ASN1_BIT_STRING /* nope */
+#ifdef LIBRESSL_VERSION_NUMBER
+static unsigned long OpenSSL_version_num(void)
+{
+  return LIBRESSL_VERSION_NUMBER;
+}
+#else
+#define OpenSSL_version_num() SSLeay()
+#endif
 #endif
 
 #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
@@ -165,39 +176,34 @@
 }
 
 /*
- * rand_enough() is a function that returns TRUE if we have seeded the random
- * engine properly. We use some preprocessor magic to provide a seed_enough()
- * macro to use, just to prevent a compiler warning on this function if we
- * pass in an argument that is never used.
+ * rand_enough() returns TRUE if we have seeded the random engine properly.
  */
-
-#ifdef HAVE_RAND_STATUS
-#define seed_enough(x) rand_enough()
 static bool rand_enough(void)
 {
   return (0 != RAND_status()) ? TRUE : FALSE;
 }
-#else
-#define seed_enough(x) rand_enough(x)
-static bool rand_enough(int nread)
-{
-  /* this is a very silly decision to make */
-  return (nread > 500) ? TRUE : FALSE;
-}
-#endif
 
-static int ossl_seed(struct Curl_easy *data)
+static CURLcode Curl_ossl_seed(struct Curl_easy *data)
 {
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
   char *buf = data->state.buffer; /* point to the big buffer */
   int nread=0;
 
-  /* Q: should we add support for a random file name as a libcurl option?
-     A: Yes, it is here */
+  if(ssl_seeded)
+    return CURLE_OK;
+
+  if(rand_enough()) {
+    /* OpenSSL 1.1.0+ will return here */
+    ssl_seeded = TRUE;
+    return CURLE_OK;
+  }
 
 #ifndef RANDOM_FILE
   /* if RANDOM_FILE isn't defined, we only perform this if an option tells
      us to! */
-  if(data->set.ssl.random_file)
+  if(data->set.str[STRING_SSL_RANDOM_FILE])
 #define RANDOM_FILE "" /* doesn't matter won't be used */
 #endif
   {
@@ -206,7 +212,7 @@
                              data->set.str[STRING_SSL_RANDOM_FILE]:
                              RANDOM_FILE),
                             RAND_LOAD_LENGTH);
-    if(seed_enough(nread))
+    if(rand_enough())
       return nread;
   }
 
@@ -226,7 +232,7 @@
                        data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
     if(-1 != ret) {
       nread += ret;
-      if(seed_enough(nread))
+      if(rand_enough())
         return nread;
     }
   }
@@ -237,9 +243,10 @@
   do {
     unsigned char randb[64];
     int len = sizeof(randb);
-    RAND_bytes(randb, len);
+    if(!RAND_bytes(randb, len))
+      break;
     RAND_add(randb, len, (len >> 1));
-  } while(!RAND_status());
+  } while(!rand_enough());
 
   /* generates a default path for the random seed file */
   buf[0]=0; /* blank it first */
@@ -247,25 +254,12 @@
   if(buf[0]) {
     /* we got a file name to try */
     nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
-    if(seed_enough(nread))
+    if(rand_enough())
       return nread;
   }
 
   infof(data, "libcurl is now using a weak random seed!\n");
-  return nread;
-}
-
-static void Curl_ossl_seed(struct Curl_easy *data)
-{
-  /* we have the "SSL is seeded" boolean static to prevent multiple
-     time-consuming seedings in vain */
-  static bool ssl_seeded = FALSE;
-
-  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
-     data->set.str[STRING_SSL_EGDSOCKET]) {
-    ossl_seed(data);
-    ssl_seeded = TRUE;
-  }
+  return CURLE_SSL_CONNECT_ERROR; /* confusing error code */
 }
 
 #ifndef SSL_FILETYPE_ENGINE
@@ -278,13 +272,13 @@
 {
   if(!type || !type[0])
     return SSL_FILETYPE_PEM;
-  if(Curl_raw_equal(type, "PEM"))
+  if(strcasecompare(type, "PEM"))
     return SSL_FILETYPE_PEM;
-  if(Curl_raw_equal(type, "DER"))
+  if(strcasecompare(type, "DER"))
     return SSL_FILETYPE_ASN1;
-  if(Curl_raw_equal(type, "ENG"))
+  if(strcasecompare(type, "ENG"))
     return SSL_FILETYPE_ENGINE;
-  if(Curl_raw_equal(type, "P12"))
+  if(strcasecompare(type, "P12"))
     return SSL_FILETYPE_PKCS12;
   return -1;
 }
@@ -301,7 +295,7 @@
   switch(UI_get_string_type(uis)) {
   case UIT_PROMPT:
   case UIT_VERIFY:
-    password = (const char*)UI_get0_user_data(ui);
+    password = (const char *)UI_get0_user_data(ui);
     if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
       UI_set_result(ui, uis, password);
       return 1;
@@ -337,7 +331,8 @@
                char *cert_file,
                const char *cert_type,
                char *key_file,
-               const char *key_type)
+               const char *key_type,
+               char *key_passwd)
 {
   struct Curl_easy *data = conn->data;
 
@@ -348,10 +343,9 @@
     X509 *x509;
     int cert_done = 0;
 
-    if(data->set.str[STRING_KEY_PASSWD]) {
+    if(key_passwd) {
       /* set the password in the callback userdata */
-      SSL_CTX_set_default_passwd_cb_userdata(ctx,
-                                             data->set.str[STRING_KEY_PASSWD]);
+      SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd);
       /* Set passwd callback: */
       SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
     }
@@ -462,7 +456,7 @@
 
       PKCS12_PBE_add();
 
-      if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
+      if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
                        &ca)) {
         failf(data,
               "could not parse PKCS12 file, check password, " OSSL_PACKAGE
@@ -560,7 +554,7 @@
         EVP_PKEY *priv_key = NULL;
         if(data->state.engine) {
           UI_METHOD *ui_method =
-            UI_create_method((char *)"cURL user interface");
+            UI_create_method((char *)"curl user interface");
           if(!ui_method) {
             failf(data, "unable do create " OSSL_PACKAGE
                   " user-interface method");
@@ -574,7 +568,7 @@
           priv_key = (EVP_PKEY *)
             ENGINE_load_private_key(data->state.engine, key_file,
                                     ui_method,
-                                    data->set.str[STRING_KEY_PASSWD]);
+                                    key_passwd);
           UI_destroy_method(ui_method);
           if(!priv_key) {
             failf(data, "failed to load private key from crypto engine");
@@ -711,6 +705,10 @@
                          CONF_MFLAGS_DEFAULT_SECTION|
                          CONF_MFLAGS_IGNORE_MISSING_FILE);
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER)
+  /* OpenSSL 1.1.0+ takes care of initialization itself */
+#else
   /* Lets get nice error messages */
   SSL_load_error_strings();
 
@@ -719,6 +717,7 @@
     return 0;
 
   OpenSSL_add_all_algorithms();
+#endif
 
   return 1;
 }
@@ -726,6 +725,11 @@
 /* Global cleanup */
 void Curl_ossl_cleanup(void)
 {
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER)
+  /* OpenSSL 1.1 deprecates all these cleanup functions and
+     turns them into no-ops in OpenSSL 1.0 compatibility mode */
+#else
   /* Free ciphers and digests lists */
   EVP_cleanup();
 
@@ -734,18 +738,11 @@
   ENGINE_cleanup();
 #endif
 
-#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
-  /* Free OpenSSL ex_data table */
-  CRYPTO_cleanup_all_ex_data();
-#endif
-
   /* Free OpenSSL error strings */
   ERR_free_strings();
 
   /* Free thread local error state, destroying hash upon zero refcount */
-#ifdef HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED
-
-#elif defined(HAVE_ERR_REMOVE_THREAD_STATE)
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
   ERR_remove_thread_state(NULL);
 #else
   ERR_remove_state(0);
@@ -757,6 +754,7 @@
 #ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS
   SSL_COMP_free_compression_methods();
 #endif
+#endif
 }
 
 /*
@@ -901,13 +899,8 @@
 }
 
 
-/*
- * This function is called when an SSL connection is closed.
- */
-void Curl_ossl_close(struct connectdata *conn, int sockindex)
+static void ossl_close(struct ssl_connect_data *connssl)
 {
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
   if(connssl->handle) {
     (void)SSL_shutdown(connssl->handle);
     SSL_set_connect_state(connssl->handle);
@@ -922,6 +915,15 @@
 }
 
 /*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_ossl_close(struct connectdata *conn, int sockindex)
+{
+  ossl_close(&conn->ssl[sockindex]);
+  ossl_close(&conn->proxy_ssl[sockindex]);
+}
+
+/*
  * This function is called to shut down the SSL layer but keep the
  * socket open (CCC - Clear Command Channel)
  */
@@ -949,8 +951,8 @@
   if(connssl->handle) {
     buffsize = (int)sizeof(buf);
     while(!done) {
-      int what = Curl_socket_ready(conn->sock[sockindex],
-                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+      int what = SOCKET_READABLE(conn->sock[sockindex],
+                                 SSL_SHUTDOWN_TIMEOUT);
       if(what > 0) {
         ERR_clear_error();
 
@@ -1043,6 +1045,14 @@
 #else
   (void)data;
 #endif
+#if !defined(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED) && \
+  defined(HAVE_ERR_REMOVE_THREAD_STATE)
+  /* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread
+     so we need to clean it here in case the thread will be killed. All OpenSSL
+     code should extract the error in association with the error so clearing
+     this queue here should be harmless at worst. */
+  ERR_remove_thread_state(NULL);
+#endif
 }
 
 /* ====================================================== */
@@ -1083,16 +1093,21 @@
 #endif
   CURLcode result = CURLE_OK;
   bool dNSName = FALSE; /* if a dNSName field exists in the cert */
+  bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
 
 #ifdef ENABLE_IPV6
   if(conn->bits.ipv6_ip &&
-     Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
+     Curl_inet_pton(AF_INET6, hostname, &addr)) {
     target = GEN_IPADD;
     addrlen = sizeof(struct in6_addr);
   }
   else
 #endif
-    if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
+    if(Curl_inet_pton(AF_INET, hostname, &addr)) {
       target = GEN_IPADD;
       addrlen = sizeof(struct in_addr);
     }
@@ -1115,15 +1130,15 @@
       /* get a handle to alternative name number i */
       const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
 
-      /* If a subjectAltName extension of type dNSName is present, that MUST
-         be used as the identity. / RFC2818 section 3.1 */
       if(check->type == GEN_DNS)
         dNSName = TRUE;
+      else if(check->type == GEN_IPADD)
+        iPAddress = TRUE;
 
       /* only check alternatives of the same type the target is */
       if(check->type == target) {
         /* get data and length */
-        const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
+        const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5);
         size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
 
         switch(target) {
@@ -1141,11 +1156,11 @@
           if((altlen == strlen(altptr)) &&
              /* if this isn't true, there was an embedded zero in the name
                 string and we cannot match it. */
-             Curl_cert_hostcheck(altptr, conn->host.name)) {
+             Curl_cert_hostcheck(altptr, hostname)) {
             dnsmatched = TRUE;
             infof(data,
                   " subjectAltName: host \"%s\" matched cert's \"%s\"\n",
-                  conn->host.dispname, altptr);
+                  dispname, altptr);
           }
           break;
 
@@ -1156,7 +1171,7 @@
             ipmatched = TRUE;
             infof(data,
                   " subjectAltName: host \"%s\" matched cert's IP address!\n",
-                  conn->host.dispname);
+                  dispname);
           }
           break;
         }
@@ -1164,21 +1179,17 @@
     }
     GENERAL_NAMES_free(altnames);
 
-    if(dnsmatched || (!dNSName && ipmatched)) {
-      /* count as a match if the dnsname matched or if there was no dnsname
-         fields at all AND there was an IP field match */
+    if(dnsmatched || ipmatched)
       matched = TRUE;
-    }
   }
 
   if(matched)
     /* an alternative name matched */
     ;
-  else if(dNSName) {
-    /* an dNSName field existed, but didn't match and then we MUST fail */
-    infof(data, " subjectAltName does not match %s\n", conn->host.dispname);
+  else if(dNSName || iPAddress) {
+    infof(data, " subjectAltName does not match %s\n", dispname);
     failf(data, "SSL: no alternative certificate subject name matches "
-          "target host name '%s'", conn->host.dispname);
+          "target host name '%s'", dispname);
     result = CURLE_PEER_FAILED_VERIFICATION;
   }
   else {
@@ -1215,7 +1226,7 @@
           if(j >= 0) {
             peer_CN = OPENSSL_malloc(j+1);
             if(peer_CN) {
-              memcpy(peer_CN, ASN1_STRING_data(tmp), j);
+              memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j);
               peer_CN[j] = '\0';
             }
           }
@@ -1252,9 +1263,9 @@
             "SSL: unable to obtain common name from peer certificate");
       result = CURLE_PEER_FAILED_VERIFICATION;
     }
-    else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+    else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
       failf(data, "SSL: certificate subject name '%s' does not match "
-            "target host name '%s'", peer_CN, conn->host.dispname);
+            "target host name '%s'", peer_CN, dispname);
       result = CURLE_PEER_FAILED_VERIFICATION;
     }
     else {
@@ -1529,6 +1540,11 @@
     verstr = "TLSv1.2";
     break;
 #endif
+#ifdef TLS1_3_VERSION
+  case TLS1_3_VERSION:
+    verstr = "TLSv1.3";
+    break;
+#endif
   case 0:
     break;
   default:
@@ -1551,7 +1567,7 @@
     else
       tls_rt_name = "";
 
-    msg_type = *(char*)buf;
+    msg_type = *(char *)buf;
     msg_name = ssl_msg_type(ssl_ver, msg_type);
 
     txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
@@ -1657,6 +1673,10 @@
     return "";
 
   switch(SSL_version(ssl)) {
+#ifdef TLS1_3_VERSION
+  case TLS1_3_VERSION:
+    return "TLSv1.3";
+#endif
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
   case TLS1_2_VERSION:
     return "TLSv1.2";
@@ -1691,23 +1711,39 @@
   struct in_addr addr;
 #endif
 #endif
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  const long int ssl_version = SSL_CONN_CONFIG(version);
+#ifdef USE_TLS_SRP
+  const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+#endif
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
   /* Make funny stuff to get random input */
-  Curl_ossl_seed(data);
+  result = Curl_ossl_seed(data);
+  if(result)
+    return result;
 
-  data->set.ssl.certverifyresult = !X509_V_OK;
+  *certverifyresult = !X509_V_OK;
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
 
-  switch(data->set.ssl.version) {
-  default:
+  switch(ssl_version) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
   case CURL_SSLVERSION_TLSv1_0:
   case CURL_SSLVERSION_TLSv1_1:
   case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
     /* it will be handled later with the context options */
 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
     !defined(LIBRESSL_VERSION_NUMBER)
@@ -1723,7 +1759,7 @@
     return CURLE_NOT_BUILT_IN;
 #else
 #ifdef USE_TLS_SRP
-    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+    if(ssl_authtype == CURL_TLSAUTH_SRP)
       return CURLE_SSL_CONNECT_ERROR;
 #endif
     req_method = SSLv2_client_method();
@@ -1736,13 +1772,16 @@
     return CURLE_NOT_BUILT_IN;
 #else
 #ifdef USE_TLS_SRP
-    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+    if(ssl_authtype == CURL_TLSAUTH_SRP)
       return CURLE_SSL_CONNECT_ERROR;
 #endif
     req_method = SSLv3_client_method();
     use_sni(FALSE);
     break;
 #endif
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   if(connssl->ctx)
@@ -1821,14 +1860,14 @@
 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
   /* unless the user explicitly ask to allow the protocol vulnerability we
      use the work-around */
-  if(!conn->data->set.ssl_enable_beast)
+  if(!SSL_SET_OPTION(enable_beast))
     ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
 #endif
 
-  switch(data->set.ssl.version) {
+  switch(ssl_version) {
   case CURL_SSLVERSION_SSLv3:
 #ifdef USE_TLS_SRP
-    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+    if(ssl_authtype == CURL_TLSAUTH_SRP) {
       infof(data, "Set version TLSv1.x for SRP authorisation\n");
     }
 #endif
@@ -1837,6 +1876,9 @@
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
     ctx_options |= SSL_OP_NO_TLSv1_1;
     ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
 #endif
     break;
 
@@ -1852,38 +1894,75 @@
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
     ctx_options |= SSL_OP_NO_TLSv1_1;
     ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
 #endif
     break;
 
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
   case CURL_SSLVERSION_TLSv1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
     ctx_options |= SSL_OP_NO_SSLv2;
     ctx_options |= SSL_OP_NO_SSLv3;
     ctx_options |= SSL_OP_NO_TLSv1;
     ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
     break;
+#else
+    failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
+    return CURLE_NOT_BUILT_IN;
+#endif
 
   case CURL_SSLVERSION_TLSv1_2:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
     ctx_options |= SSL_OP_NO_SSLv2;
     ctx_options |= SSL_OP_NO_SSLv3;
     ctx_options |= SSL_OP_NO_TLSv1;
     ctx_options |= SSL_OP_NO_TLSv1_1;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
     break;
+#else
+    failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
+    return CURLE_NOT_BUILT_IN;
 #endif
 
-#ifndef OPENSSL_NO_SSL2
+  case CURL_SSLVERSION_TLSv1_3:
+#ifdef TLS1_3_VERSION
+    SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+    break;
+#else
+    failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
+    return CURLE_NOT_BUILT_IN;
+#endif
+
   case CURL_SSLVERSION_SSLv2:
+#ifndef OPENSSL_NO_SSL2
     ctx_options |= SSL_OP_NO_SSLv3;
     ctx_options |= SSL_OP_NO_TLSv1;
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
     ctx_options |= SSL_OP_NO_TLSv1_1;
     ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
 #endif
     break;
+#else
+    failf(data, OSSL_PACKAGE " was built without SSLv2 support");
+    return CURLE_NOT_BUILT_IN;
 #endif
 
   default:
-    failf(data, "Unsupported SSL protocol version");
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
@@ -1922,19 +2001,16 @@
   }
 #endif
 
-  if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
-    if(!cert_stuff(conn,
-                   connssl->ctx,
-                   data->set.str[STRING_CERT],
-                   data->set.str[STRING_CERT_TYPE],
-                   data->set.str[STRING_KEY],
-                   data->set.str[STRING_KEY_TYPE])) {
+  if(ssl_cert || ssl_cert_type) {
+    if(!cert_stuff(conn, connssl->ctx, ssl_cert, ssl_cert_type,
+                   SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
+                   SSL_SET_OPTION(key_passwd))) {
       /* failf() is already done in cert_stuff() */
       return CURLE_SSL_CERTPROBLEM;
     }
   }
 
-  ciphers = data->set.str[STRING_SSL_CIPHER_LIST];
+  ciphers = SSL_CONN_CONFIG(cipher_list);
   if(!ciphers)
     ciphers = (char *)DEFAULT_CIPHER_SELECTION;
   if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
@@ -1944,18 +2020,20 @@
   infof(data, "Cipher selection: %s\n", ciphers);
 
 #ifdef USE_TLS_SRP
-  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
-    infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+  if(ssl_authtype == CURL_TLSAUTH_SRP) {
+    char * const ssl_username = SSL_SET_OPTION(username);
 
-    if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
+    infof(data, "Using TLS-SRP username: %s\n", ssl_username);
+
+    if(!SSL_CTX_set_srp_username(connssl->ctx, ssl_username)) {
       failf(data, "Unable to set SRP user name");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
+    if(!SSL_CTX_set_srp_password(connssl->ctx, SSL_SET_OPTION(password))) {
       failf(data, "failed setting SRP password");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
+    if(!SSL_CONN_CONFIG(cipher_list)) {
       infof(data, "Setting cipher list SRP\n");
 
       if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
@@ -1965,20 +2043,17 @@
     }
   }
 #endif
-  if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
+
+  if(ssl_cafile || ssl_capath) {
     /* tell SSL where to find CA certificates that are used to verify
        the servers certificate. */
-    if(!SSL_CTX_load_verify_locations(connssl->ctx,
-                                       data->set.str[STRING_SSL_CAFILE],
-                                       data->set.str[STRING_SSL_CAPATH])) {
-      if(data->set.ssl.verifypeer) {
+    if(!SSL_CTX_load_verify_locations(connssl->ctx, ssl_cafile, ssl_capath)) {
+      if(verifypeer) {
         /* Fail if we insist on successfully verifying the server. */
         failf(data, "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
-              data->set.str[STRING_SSL_CAFILE]?
-              data->set.str[STRING_SSL_CAFILE]: "none",
-              data->set.str[STRING_SSL_CAPATH]?
-              data->set.str[STRING_SSL_CAPATH] : "none");
+              ssl_cafile ? ssl_cafile : "none",
+              ssl_capath ? ssl_capath : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
       else {
@@ -1995,29 +2070,25 @@
     infof(data,
           "  CAfile: %s\n"
           "  CApath: %s\n",
-          data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
-          "none",
-          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
-          "none");
+          ssl_cafile ? ssl_cafile : "none",
+          ssl_capath ? ssl_capath : "none");
   }
 #ifdef CURL_CA_FALLBACK
-  else if(data->set.ssl.verifypeer) {
+  else if(verifypeer) {
     /* verfying the peer without any CA certificates won't
        work so use openssl's built in default as fallback */
     SSL_CTX_set_default_verify_paths(connssl->ctx);
   }
 #endif
 
-  if(data->set.str[STRING_SSL_CRLFILE]) {
+  if(ssl_crlfile) {
     /* tell SSL where to find CRL file that is used to check certificate
      * revocation */
     lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
                                  X509_LOOKUP_file());
     if(!lookup ||
-       (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
-                            X509_FILETYPE_PEM)) ) {
-      failf(data, "error loading CRL file: %s",
-            data->set.str[STRING_SSL_CRLFILE]);
+       (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
+      failf(data, "error loading CRL file: %s", ssl_crlfile);
       return CURLE_SSL_CRL_BADFILE;
     }
     else {
@@ -2026,9 +2097,7 @@
       X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
                            X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
     }
-    infof(data,
-          "  CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
-          data->set.str[STRING_SSL_CRLFILE]: "none");
+    infof(data, "  CRLfile: %s\n", ssl_crlfile);
   }
 
   /* Try building a chain using issuers in the trusted store first to avoid
@@ -2039,7 +2108,7 @@
   https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
   */
 #if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
-  if(data->set.ssl.verifypeer) {
+  if(verifypeer) {
     X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
                          X509_V_FLAG_TRUSTED_FIRST);
   }
@@ -2050,8 +2119,7 @@
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
   SSL_CTX_set_verify(connssl->ctx,
-                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
-                     NULL);
+                     verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
@@ -2074,31 +2142,30 @@
 
 #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
     !defined(OPENSSL_NO_OCSP)
-  if(data->set.ssl.verifystatus)
+  if(SSL_CONN_CONFIG(verifystatus))
     SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
 #endif
 
   SSL_set_connect_state(connssl->handle);
 
   connssl->server_cert = 0x0;
-
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-  if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+  if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
-     (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+     (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
 #endif
      sni &&
-     !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
+     !SSL_set_tlsext_host_name(connssl->handle, hostname))
     infof(data, "WARNING: failed to configure server name indication (SNI) "
           "TLS extension\n");
 #endif
 
   /* Check if there's a cached ID we can/should use here! */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     void *ssl_sessionid = NULL;
 
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
       if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(conn);
@@ -2112,8 +2179,16 @@
     Curl_ssl_sessionid_unlock(conn);
   }
 
-  /* pass the raw socket into the SSL layers */
-  if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+  if(conn->proxy_ssl[sockindex].use) {
+    BIO *const bio = BIO_new(BIO_f_ssl());
+    DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
+    DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
+    DEBUGASSERT(bio != NULL);
+    BIO_set_ssl(bio, conn->proxy_ssl[sockindex].handle, FALSE);
+    SSL_set_bio(connssl->handle, bio, bio);
+  }
+  else if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+    /* pass the raw socket into the SSL layers */
     failf(data, "SSL: SSL_set_fd failed: %s",
           ERR_error_string(ERR_get_error(), NULL));
     return CURLE_SSL_CONNECT_ERROR;
@@ -2129,9 +2204,11 @@
   struct Curl_easy *data = conn->data;
   int err;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
-             || ssl_connect_2_reading == connssl->connecting_state
-             || ssl_connect_2_writing == connssl->connecting_state);
+              || ssl_connect_2_reading == connssl->connecting_state
+              || ssl_connect_2_writing == connssl->connecting_state);
 
   ERR_clear_error();
 
@@ -2178,6 +2255,7 @@
 
         lerr = SSL_get_verify_result(connssl->handle);
         if(lerr != X509_V_OK) {
+          *certverifyresult = lerr;
           snprintf(error_buffer, sizeof(error_buffer),
                    "SSL certificate problem: %s",
                    X509_verify_cert_error_string(lerr));
@@ -2199,8 +2277,11 @@
        * the SO_ERROR is also lost.
        */
       if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+        const char * const hostname = SSL_IS_PROXY() ?
+          conn->http_proxy.host.name : conn->host.name;
+        const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
         failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
-              conn->host.name, conn->remote_port);
+              hostname, port);
         return result;
       }
 
@@ -2224,7 +2305,7 @@
      * negotiated
      */
     if(conn->bits.tls_enable_alpn) {
-      const unsigned char* neg_protocol;
+      const unsigned char *neg_protocol;
       unsigned int len;
       SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
       if(len != 0) {
@@ -2309,7 +2390,7 @@
 
 static int X509V3_ext(struct Curl_easy *data,
                       int certnum,
-                      STACK_OF(X509_EXTENSION) *exts)
+                      CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
 {
   int i;
   size_t j;
@@ -2391,7 +2472,7 @@
     EVP_PKEY *pubkey=NULL;
     int j;
     char *ptr;
-    ASN1_BIT_STRING *psig = NULL;
+    CONST_ASN1_BIT_STRING ASN1_BIT_STRING *psig = NULL;
 
     X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
     push_certinfo("Subject", i);
@@ -2411,7 +2492,7 @@
 
 #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
     {
-      X509_ALGOR *palg = NULL;
+      const X509_ALGOR *palg = NULL;
       ASN1_STRING *a = ASN1_STRING_new();
       if(a) {
         X509_get0_signature(&psig, &palg, x);
@@ -2442,10 +2523,10 @@
     }
 #endif
 
-    ASN1_TIME_print(mem, X509_get_notBefore(x));
+    ASN1_TIME_print(mem, X509_get0_notBefore(x));
     push_certinfo("Start date", i);
 
-    ASN1_TIME_print(mem, X509_get_notAfter(x));
+    ASN1_TIME_print(mem, X509_get0_notAfter(x));
     push_certinfo("Expire date", i);
 
     pubkey = X509_get_pubkey(x);
@@ -2629,7 +2710,7 @@
       break; /* failed */
 
     /* https://www.openssl.org/docs/crypto/buffer.html */
-    buff1 = temp = OPENSSL_malloc(len1);
+    buff1 = temp = malloc(len1);
     if(!buff1)
       break; /* failed */
 
@@ -2652,7 +2733,7 @@
 
   /* https://www.openssl.org/docs/crypto/buffer.html */
   if(buff1)
-    OPENSSL_free(buff1);
+    free(buff1);
 
   return result;
 }
@@ -2677,6 +2758,8 @@
   FILE *fp;
   char *buffer = data->state.buffer;
   const char *ptr;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
   BIO *mem = BIO_new(BIO_s_mem());
 
   if(data->set.ssl.certinfo)
@@ -2692,25 +2775,25 @@
     return CURLE_PEER_FAILED_VERIFICATION;
   }
 
-  infof(data, "Server certificate:\n");
+  infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
 
   rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
                          buffer, BUFSIZE);
   infof(data, " subject: %s\n", rc?"[NONE]":buffer);
 
-  ASN1_TIME_print(mem, X509_get_notBefore(connssl->server_cert));
+  ASN1_TIME_print(mem, X509_get0_notBefore(connssl->server_cert));
   len = BIO_get_mem_data(mem, (char **) &ptr);
   infof(data, " start date: %.*s\n", len, ptr);
   rc = BIO_reset(mem);
 
-  ASN1_TIME_print(mem, X509_get_notAfter(connssl->server_cert));
+  ASN1_TIME_print(mem, X509_get0_notAfter(connssl->server_cert));
   len = BIO_get_mem_data(mem, (char **) &ptr);
   infof(data, " expire date: %.*s\n", len, ptr);
   rc = BIO_reset(mem);
 
   BIO_free(mem);
 
-  if(data->set.ssl.verifyhost) {
+  if(SSL_CONN_CONFIG(verifyhost)) {
     result = verifyhost(conn, connssl->server_cert);
     if(result) {
       X509_free(connssl->server_cert);
@@ -2733,12 +2816,12 @@
        deallocating the certificate. */
 
     /* e.g. match issuer name with provided issuer certificate */
-    if(data->set.str[STRING_SSL_ISSUERCERT]) {
-      fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
+    if(SSL_SET_OPTION(issuercert)) {
+      fp = fopen(SSL_SET_OPTION(issuercert), FOPEN_READTEXT);
       if(!fp) {
         if(strict)
           failf(data, "SSL: Unable to open issuer cert (%s)",
-                data->set.str[STRING_SSL_ISSUERCERT]);
+                SSL_SET_OPTION(issuercert));
         X509_free(connssl->server_cert);
         connssl->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
@@ -2748,7 +2831,7 @@
       if(!issuer) {
         if(strict)
           failf(data, "SSL: Unable to read issuer cert (%s)",
-                data->set.str[STRING_SSL_ISSUERCERT]);
+                SSL_SET_OPTION(issuercert));
         X509_free(connssl->server_cert);
         X509_free(issuer);
         fclose(fp);
@@ -2760,7 +2843,7 @@
       if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
         if(strict)
           failf(data, "SSL: Certificate issuer check failed (%s)",
-                data->set.str[STRING_SSL_ISSUERCERT]);
+                SSL_SET_OPTION(issuercert));
         X509_free(connssl->server_cert);
         X509_free(issuer);
         connssl->server_cert = NULL;
@@ -2768,15 +2851,14 @@
       }
 
       infof(data, " SSL certificate issuer check ok (%s)\n",
-            data->set.str[STRING_SSL_ISSUERCERT]);
+            SSL_SET_OPTION(issuercert));
       X509_free(issuer);
     }
 
-    lerr = data->set.ssl.certverifyresult =
-      SSL_get_verify_result(connssl->handle);
+    lerr = *certverifyresult = SSL_get_verify_result(connssl->handle);
 
-    if(data->set.ssl.certverifyresult != X509_V_OK) {
-      if(data->set.ssl.verifypeer) {
+    if(*certverifyresult != X509_V_OK) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         /* We probably never reach this, because SSL_connect() will fail
            and we return earlier if verifypeer is set? */
         if(strict)
@@ -2795,7 +2877,7 @@
 
 #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
     !defined(OPENSSL_NO_OCSP)
-  if(data->set.ssl.verifystatus) {
+  if(SSL_CONN_CONFIG(verifystatus)) {
     result = verifystatus(conn, connssl);
     if(result) {
       X509_free(connssl->server_cert);
@@ -2831,7 +2913,7 @@
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     bool incache;
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -2843,7 +2925,8 @@
         regardless of its state. */
 
     Curl_ssl_sessionid_lock(conn);
-    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+                                      sockindex));
     if(incache) {
       if(old_ssl_sessionid != our_ssl_sessionid) {
         infof(data, "old SSL session ID is stale, removing\n");
@@ -2854,7 +2937,7 @@
 
     if(!incache) {
       result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
-                                      0 /* unknown size */);
+                                      0 /* unknown size */, sockindex);
       if(result) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "failed to store ssl session");
@@ -2878,8 +2961,8 @@
    * operations.
    */
 
-  result = servercert(conn, connssl,
-                      (data->set.ssl.verifypeer || data->set.ssl.verifyhost));
+  result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) ||
+                                      SSL_CONN_CONFIG(verifyhost)));
 
   if(!result)
     connssl->connecting_state = ssl_connect_done;
@@ -2899,7 +2982,7 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
+  time_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -2945,7 +3028,8 @@
       curl_socket_t readfd = ssl_connect_2_reading==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -3026,7 +3110,10 @@
 {
   if(conn->ssl[connindex].handle)
     /* SSL is in use */
-    return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+    return (0 != SSL_pending(conn->ssl[connindex].handle) ||
+           (conn->proxy_ssl[connindex].handle &&
+            0 != SSL_pending(conn->proxy_ssl[connindex].handle))) ?
+           TRUE : FALSE;
   else
     return FALSE;
 }
@@ -3071,8 +3158,18 @@
       /*  A failure in the SSL library occurred, usually a protocol error.
           The OpenSSL error queue contains more information on the error. */
       sslerror = ERR_get_error();
-      failf(conn->data, "SSL_write() error: %s",
-            ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
+      if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
+         ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
+         conn->ssl[sockindex].state == ssl_connection_complete &&
+         conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
+        char ver[120];
+        Curl_ossl_version(ver, 120);
+        failf(conn->data, "Error: %s does not support double SSL tunneling.",
+              ver);
+      }
+      else
+        failf(conn->data, "SSL_write() error: %s",
+              ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
       *curlcode = CURLE_SEND_ERROR;
       return -1;
     }
@@ -3142,7 +3239,7 @@
   unsigned long ssleay_value;
   sub[2]='\0';
   sub[1]='\0';
-  ssleay_value=SSLeay();
+  ssleay_value=OpenSSL_version_num();
   if(ssleay_value < 0x906000) {
     ssleay_value=SSLEAY_VERSION_NUMBER;
     sub[0]='\0';
@@ -3177,7 +3274,12 @@
                      size_t length)
 {
   if(data) {
-    Curl_ossl_seed(data); /* Initiate the seed if not already done */
+    if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */
+      return 1; /* couldn't seed for some reason */
+  }
+  else {
+    if(!rand_enough())
+      return 1;
   }
   RAND_bytes(entropy, curlx_uztosi(length));
   return 0; /* 0 as in no problem */
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index d33f548..f2f973c 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -54,7 +54,7 @@
 #include "parsedate.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "polarssl_threadlock.h"
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -75,6 +75,11 @@
 #define THREADING_SUPPORT
 #endif
 
+#ifndef POLARSSL_ERROR_C
+#define error_strerror(x,y,z)
+#endif /* POLARSSL_ERROR_C */
+
+
 #if defined(THREADING_SUPPORT)
 static entropy_context entropy;
 
@@ -96,13 +101,13 @@
 /* start of entropy_func_mutex() */
 static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
 {
-    int ret;
-    /* lock 1 = entropy_func_mutex() */
-    Curl_polarsslthreadlock_lock_function(1);
-    ret = entropy_func(data, output, len);
-    Curl_polarsslthreadlock_unlock_function(1);
+  int ret;
+  /* lock 1 = entropy_func_mutex() */
+  Curl_polarsslthreadlock_lock_function(1);
+  ret = entropy_func(data, output, len);
+  Curl_polarsslthreadlock_unlock_function(1);
 
-    return ret;
+  return ret;
 }
 /* end of entropy_func_mutex() */
 
@@ -138,84 +143,70 @@
 
 static CURLcode
 polarssl_connect_step1(struct connectdata *conn,
-                     int sockindex)
+                       int sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-
-  bool sni = TRUE; /* default is SNI enabled */
+  const char *capath = SSL_CONN_CONFIG(CApath);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
   int ret = -1;
-#ifdef ENABLE_IPV6
-  struct in6_addr addr;
-#else
-  struct in_addr addr;
-#endif
   char errorbuf[128];
   errorbuf[0]=0;
 
   /* PolarSSL only supports SSLv3 and TLSv1 */
-  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
     failf(data, "PolarSSL does not support SSLv2");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
-    sni = FALSE; /* SSLv3 has no SNI */
 
 #ifdef THREADING_SUPPORT
   entropy_init_mutex(&entropy);
 
   if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
                           NULL, 0)) != 0) {
-#ifdef POLARSSL_ERROR_C
-     error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
-     failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-                                                            -ret, errorbuf);
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
   }
 #else
   entropy_init(&connssl->entropy);
 
   if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
                           NULL, 0)) != 0) {
-#ifdef POLARSSL_ERROR_C
-     error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
-     failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-                                                            -ret, errorbuf);
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
   }
 #endif /* THREADING_SUPPORT */
 
   /* Load the trusted CA */
   memset(&connssl->cacert, 0, sizeof(x509_crt));
 
-  if(data->set.str[STRING_SSL_CAFILE]) {
+  if(SSL_CONN_CONFIG(CAfile)) {
     ret = x509_crt_parse_file(&connssl->cacert,
-                              data->set.str[STRING_SSL_CAFILE]);
+                              SSL_CONN_CONFIG(CAfile));
 
     if(ret<0) {
-#ifdef POLARSSL_ERROR_C
       error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
       failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+            SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
 
-      if(data->set.ssl.verifypeer)
+      if(SSL_CONN_CONFIG(verifypeer))
         return CURLE_SSL_CACERT_BADFILE;
     }
   }
 
-  if(data->set.str[STRING_SSL_CAPATH]) {
-    ret = x509_crt_parse_path(&connssl->cacert,
-                              data->set.str[STRING_SSL_CAPATH]);
+  if(capath) {
+    ret = x509_crt_parse_path(&connssl->cacert, capath);
 
     if(ret<0) {
-#ifdef POLARSSL_ERROR_C
       error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
       failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+            capath, -ret, errorbuf);
 
-      if(data->set.ssl.verifypeer)
+      if(SSL_CONN_CONFIG(verifypeer))
         return CURLE_SSL_CACERT_BADFILE;
     }
   }
@@ -223,27 +214,25 @@
   /* Load the client certificate */
   memset(&connssl->clicert, 0, sizeof(x509_crt));
 
-  if(data->set.str[STRING_CERT]) {
+  if(SSL_SET_OPTION(cert)) {
     ret = x509_crt_parse_file(&connssl->clicert,
-                              data->set.str[STRING_CERT]);
+                              SSL_SET_OPTION(cert));
 
     if(ret) {
-#ifdef POLARSSL_ERROR_C
       error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
       failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
-            data->set.str[STRING_CERT], -ret, errorbuf);
+            SSL_SET_OPTION(cert), -ret, errorbuf);
 
       return CURLE_SSL_CERTPROBLEM;
     }
   }
 
   /* Load the client private key */
-  if(data->set.str[STRING_KEY]) {
+  if(SSL_SET_OPTION(key)) {
     pk_context pk;
     pk_init(&pk);
-    ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
-                           data->set.str[STRING_KEY_PASSWD]);
+    ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
+                           SSL_SET_OPTION(key_passwd));
     if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
       ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
     if(ret == 0)
@@ -253,11 +242,9 @@
     pk_free(&pk);
 
     if(ret) {
-#ifdef POLARSSL_ERROR_C
       error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
       failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
-            data->set.str[STRING_KEY], -ret, errorbuf);
+            SSL_SET_OPTION(key), -ret, errorbuf);
 
       return CURLE_SSL_CERTPROBLEM;
     }
@@ -266,31 +253,27 @@
   /* Load the CRL */
   memset(&connssl->crl, 0, sizeof(x509_crl));
 
-  if(data->set.str[STRING_SSL_CRLFILE]) {
+  if(SSL_SET_OPTION(CRLfile)) {
     ret = x509_crl_parse_file(&connssl->crl,
-                              data->set.str[STRING_SSL_CRLFILE]);
+                              SSL_SET_OPTION(CRLfile));
 
     if(ret) {
-#ifdef POLARSSL_ERROR_C
       error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
       failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
-            data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+            SSL_SET_OPTION(CRLfile), -ret, errorbuf);
 
       return CURLE_SSL_CRL_BADFILE;
     }
   }
 
-  infof(data, "PolarSSL: Connecting to %s:%d\n",
-        conn->host.name, conn->remote_port);
+  infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
 
   if(ssl_init(&connssl->ssl)) {
     failf(data, "PolarSSL: ssl_init failed");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  switch(data->set.ssl.version) {
-  default:
+  switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
     ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
@@ -324,6 +307,12 @@
                         SSL_MINOR_VERSION_3);
     infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
     break;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "PolarSSL: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
@@ -338,30 +327,31 @@
   ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
 
   /* Check if there's a cached ID we can/should use here! */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     void *old_session = NULL;
 
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
+    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
       ret = ssl_set_session(&connssl->ssl, old_session);
-      Curl_ssl_sessionid_unlock(conn);
       if(ret) {
+        Curl_ssl_sessionid_unlock(conn);
         failf(data, "ssl_set_session returned -0x%x", -ret);
         return CURLE_SSL_CONNECT_ERROR;
       }
       infof(data, "PolarSSL re-using session\n");
     }
+    Curl_ssl_sessionid_unlock(conn);
   }
 
   ssl_set_ca_chain(&connssl->ssl,
                    &connssl->cacert,
                    &connssl->crl,
-                   conn->host.name);
+                   hostname);
 
   ssl_set_own_cert_rsa(&connssl->ssl,
                        &connssl->clicert, &connssl->rsa);
 
-  if(ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+  if(ssl_set_hostname(&connssl->ssl, hostname)) {
     /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
        to set in the SNI extension. So even if curl connects to a host
        specified as an IP address, this function must be used. */
@@ -371,7 +361,7 @@
 
 #ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
-    static const char* protocols[3];
+    static const char *protocols[3];
     int cur = 0;
 
 #ifdef USE_NGHTTP2
@@ -401,7 +391,7 @@
 
 static CURLcode
 polarssl_connect_step2(struct connectdata *conn,
-                     int sockindex)
+                       int sockindex)
 {
   int ret;
   struct Curl_easy *data = conn->data;
@@ -429,9 +419,7 @@
     return CURLE_OK;
 
   default:
-#ifdef POLARSSL_ERROR_C
     error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
     failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
           -ret, errorbuf);
     return CURLE_SSL_CONNECT_ERROR;
@@ -442,7 +430,7 @@
 
   ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
 
-  if(ret && data->set.ssl.verifypeer) {
+  if(ret && SSL_CONN_CONFIG(verifypeer)) {
     if(ret & BADCERT_EXPIRED)
       failf(data, "Cert verify failed: BADCERT_EXPIRED");
 
@@ -538,9 +526,9 @@
       }
       else
 #endif
-      if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
-        conn->negnpn = CURL_HTTP_VERSION_1_1;
-      }
+        if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
     }
     else
       infof(data, "ALPN, server did not agree to a protocol\n");
@@ -555,7 +543,7 @@
 
 static CURLcode
 polarssl_connect_step3(struct connectdata *conn,
-                     int sockindex)
+                       int sockindex)
 {
   CURLcode retcode = CURLE_OK;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -563,7 +551,7 @@
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     int ret;
     ssl_session *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -582,10 +570,10 @@
 
     /* If there's already a matching session in the cache, delete it */
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
+    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
       Curl_ssl_delsessionid(conn, old_ssl_sessionid);
 
-    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
+    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
     Curl_ssl_sessionid_unlock(conn);
     if(retcode) {
       free(our_ssl_sessionid);
@@ -727,7 +715,8 @@
       curl_socket_t readfd = ssl_connect_2_reading==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -786,8 +775,8 @@
 
 CURLcode
 Curl_polarssl_connect_nonblocking(struct connectdata *conn,
-                                int sockindex,
-                                bool *done)
+                                  int sockindex,
+                                  bool *done)
 {
   return polarssl_connect_common(conn, sockindex, TRUE, done);
 }
@@ -795,7 +784,7 @@
 
 CURLcode
 Curl_polarssl_connect(struct connectdata *conn,
-                    int sockindex)
+                      int sockindex)
 {
   CURLcode result;
   bool done = FALSE;
diff --git a/lib/vtls/polarssl_threadlock.c b/lib/vtls/polarssl_threadlock.c
index 3b0ebf8..b1eb7b7 100644
--- a/lib/vtls/polarssl_threadlock.c
+++ b/lib/vtls/polarssl_threadlock.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013-2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
  *
  * This software is licensed as described in the file COPYING, which
@@ -52,7 +52,7 @@
   int i;
   int ret;
 
-  mutex_buf = malloc(NUMT * sizeof(POLARSSL_MUTEX_T));
+  mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
   if(!mutex_buf)
     return 0;     /* error, no number of threads defined */
 
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index f991ec9..a72753e 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -123,16 +123,30 @@
 #endif
   TCHAR *host_name;
   CURLcode result;
+  const 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",
-        conn->host.name, conn->remote_port);
+        hostname, conn->remote_port);
+
+#ifdef HAS_ALPN
+  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
+     Also it doesn't seem to be supported for Wine, see curl bug #983. */
+  connssl->use_alpn = conn->bits.tls_enable_alpn &&
+                      !GetProcAddress(GetModuleHandleA("ntdll"),
+                                      "wine_get_version") &&
+                      Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
+                                                  VERSION_GREATER_THAN_EQUAL);
+#else
+  connssl->use_alpn = false;
+#endif
 
   connssl->cred = NULL;
 
   /* check for an existing re-usable credential handle */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) {
+    if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
       connssl->cred = old_cred;
       infof(data, "schannel: re-using existing credential handle\n");
 
@@ -149,7 +163,7 @@
     memset(&schannel_cred, 0, sizeof(schannel_cred));
     schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
 
-    if(data->set.ssl.verifypeer) {
+    if(conn->ssl_config.verifypeer) {
 #ifdef _WIN32_WCE
       /* certificate validation on CE doesn't seem to work right; we'll
          do it following a more manual process. */
@@ -158,13 +172,14 @@
         SCH_CRED_IGNORE_REVOCATION_OFFLINE;
 #else
       schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
-      if(data->set.ssl_no_revoke)
+      /* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */
+      if(data->set.ssl.no_revoke)
         schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
                                  SCH_CRED_IGNORE_REVOCATION_OFFLINE;
       else
         schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
 #endif
-      if(data->set.ssl_no_revoke)
+      if(data->set.ssl.no_revoke)
         infof(data, "schannel: disabled server certificate revocation "
                     "checks\n");
       else
@@ -177,15 +192,14 @@
       infof(data, "schannel: disabled server certificate revocation checks\n");
     }
 
-    if(!data->set.ssl.verifyhost) {
+    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. Also disables SNI.\n");
     }
 
-    switch(data->set.ssl.version) {
-    default:
+    switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
       schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
@@ -201,12 +215,18 @@
     case CURL_SSLVERSION_TLSv1_2:
       schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
       break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "Schannel: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
     case CURL_SSLVERSION_SSLv3:
       schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
       break;
     case CURL_SSLVERSION_SSLv2:
       schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
       break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
     }
 
     /* allocate memory for the re-usable credential handle */
@@ -241,32 +261,29 @@
   }
 
   /* Warn if SNI is disabled due to use of an IP address */
-  if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
+  if(Curl_inet_pton(AF_INET, hostname, &addr)
 #ifdef ENABLE_IPV6
-     || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
+     || Curl_inet_pton(AF_INET6, hostname, &addr6)
 #endif
     ) {
     infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
   }
 
 #ifdef HAS_ALPN
-  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above */
-  if(conn->bits.tls_enable_alpn &&
-     Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
-                                 VERSION_GREATER_THAN_EQUAL)) {
+  if(connssl->use_alpn) {
     int cur = 0;
     int list_start_index = 0;
-    unsigned int* extension_len = NULL;
+    unsigned int *extension_len = NULL;
     unsigned short* list_len = NULL;
 
     /* The first four bytes will be an unsigned int indicating number
        of bytes of data in the rest of the the buffer. */
-    extension_len = (unsigned int*)(&alpn_buffer[cur]);
+    extension_len = (unsigned int *)(&alpn_buffer[cur]);
     cur += sizeof(unsigned int);
 
     /* The next four bytes are an indicator that this buffer will contain
        ALPN data, as opposed to NPN, for example. */
-    *(unsigned int*)&alpn_buffer[cur] =
+    *(unsigned int *)&alpn_buffer[cur] =
       SecApplicationProtocolNegotiationExt_ALPN;
     cur += sizeof(unsigned int);
 
@@ -324,15 +341,21 @@
   }
   memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
 
-  host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+  host_name = Curl_convert_UTF8_to_tchar(hostname);
   if(!host_name)
     return CURLE_OUT_OF_MEMORY;
 
-  /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+  /* Schannel InitializeSecurityContext:
+     https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
 
+     At the moment we don't pass inbuf unless we're using ALPN since we only
+     use it for that, and Wine (for which we currently disable ALPN) is giving
+     us problems with inbuf regardless. https://github.com/curl/curl/issues/983
+  */
   sspi_status = s_pSecFn->InitializeSecurityContext(
-    &connssl->cred->cred_handle, NULL, host_name,
-    connssl->req_flags, 0, 0, &inbuf_desc, 0, &connssl->ctxt->ctxt_handle,
+    &connssl->cred->cred_handle, NULL, host_name, connssl->req_flags, 0, 0,
+    (connssl->use_alpn ? &inbuf_desc : NULL),
+    0, &connssl->ctxt->ctxt_handle,
     &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
 
   Curl_unicodefree(host_name);
@@ -391,11 +414,13 @@
   TCHAR *host_name;
   CURLcode result;
   bool doread;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 
   doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
 
   infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
-        conn->host.name, conn->remote_port);
+        hostname, conn->remote_port);
 
   if(!connssl->cred || !connssl->ctxt)
     return CURLE_SSL_CONNECT_ERROR;
@@ -491,7 +516,7 @@
     memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
            connssl->encdata_offset);
 
-    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    host_name = Curl_convert_UTF8_to_tchar(hostname);
     if(!host_name)
       return CURLE_OUT_OF_MEMORY;
 
@@ -608,7 +633,7 @@
 #ifdef _WIN32_WCE
   /* Windows CE doesn't do any server certificate validation.
      We have to do it manually. */
-  if(data->set.ssl.verifypeer)
+  if(conn->ssl_config.verifypeer)
     return verify_certificate(conn, sockindex);
 #endif
 
@@ -623,6 +648,8 @@
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CERT_CONTEXT *ccert_context = NULL;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 #ifdef HAS_ALPN
   SecPkgContext_ApplicationProtocol alpn_result;
 #endif
@@ -630,7 +657,7 @@
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
   infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
-        conn->host.name, conn->remote_port);
+        hostname, conn->remote_port);
 
   if(!connssl->cred)
     return CURLE_SSL_CONNECT_ERROR;
@@ -651,10 +678,7 @@
   }
 
 #ifdef HAS_ALPN
-  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above */
-  if(conn->bits.tls_enable_alpn &&
-     Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
-                                 VERSION_GREATER_THAN_EQUAL)) {
+  if(connssl->use_alpn) {
     sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
       SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
 
@@ -689,12 +713,13 @@
 #endif
 
   /* save the current session data for possible re-use */
-  if(conn->ssl_config.sessionid) {
+  if(data->set.general_ssl.sessionid) {
     bool incache;
     struct curl_schannel_cred *old_cred = NULL;
 
     Curl_ssl_sessionid_lock(conn);
-    incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL));
+    incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
+                                      sockindex));
     if(incache) {
       if(old_cred != connssl->cred) {
         infof(data, "schannel: old credential handle is stale, removing\n");
@@ -705,7 +730,8 @@
     }
     if(!incache) {
       result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
-                                     sizeof(struct curl_schannel_cred));
+                                     sizeof(struct curl_schannel_cred),
+                                     sockindex);
       if(result) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "schannel: failed to store credential handle");
@@ -757,7 +783,7 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
+  time_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -803,7 +829,8 @@
       curl_socket_t readfd = ssl_connect_2_reading ==
         connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
 
-      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking ? 0 : timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
@@ -944,7 +971,7 @@
     /* send entire message or fail */
     while(len > (size_t)written) {
       ssize_t this_write;
-      long timeleft;
+      time_t timeleft;
       int what;
 
       this_write = 0;
@@ -959,8 +986,7 @@
         break;
       }
 
-      what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex],
-                               timeleft);
+      what = SOCKET_WRITABLE(conn->sock[sockindex], timeleft);
       if(what < 0) {
         /* fatal error */
         failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -1364,9 +1390,11 @@
    */
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 
   infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
-        conn->host.name, conn->remote_port);
+        hostname, conn->remote_port);
 
   if(connssl->cred && connssl->ctxt) {
     SecBufferDesc BuffDesc;
@@ -1388,7 +1416,7 @@
       failf(data, "schannel: ApplyControlToken failure: %s",
             Curl_sspi_strerror(conn, sspi_status));
 
-    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    host_name = Curl_convert_UTF8_to_tchar(hostname);
     if(!host_name)
       return CURLE_OUT_OF_MEMORY;
 
@@ -1513,6 +1541,9 @@
   CURLcode result = CURLE_OK;
   CERT_CONTEXT *pCertContextServer = NULL;
   const CERT_CHAIN_CONTEXT *pChainContext = NULL;
+  const char * const conn_hostname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.name :
+    conn->host.name;
 
   status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
                                             SECPKG_ATTR_REMOTE_CERT_CONTEXT,
@@ -1534,7 +1565,7 @@
                                 NULL,
                                 pCertContextServer->hCertStore,
                                 &ChainPara,
-                                (data->set.ssl_no_revoke ? 0 :
+                                (data->set.ssl.no_revoke ? 0 :
                                  CERT_CHAIN_REVOCATION_CHECK_CHAIN),
                                 NULL,
                                 &pChainContext)) {
@@ -1570,14 +1601,14 @@
   }
 
   if(result == CURLE_OK) {
-    if(data->set.ssl.verifyhost) {
+    if(conn->ssl_config.verifyhost) {
       TCHAR cert_hostname_buff[128];
       xcharp_u hostname;
       xcharp_u cert_hostname;
       DWORD len;
 
       cert_hostname.const_tchar_ptr = cert_hostname_buff;
-      hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
+      hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn_hostname);
 
       /* TODO: Fix this for certificates with multiple alternative names.
       Right now we're only asking for the first preferred alternative name.
@@ -1595,7 +1626,7 @@
                               128);
       if(len > 0 && *cert_hostname.tchar_ptr == '*') {
         /* this is a wildcard cert.  try matching the last len - 1 chars */
-        int hostname_len = strlen(conn->host.name);
+        int hostname_len = strlen(conn_hostname);
         cert_hostname.tchar_ptr++;
         if(_tcsicmp(cert_hostname.const_tchar_ptr,
                     hostname.const_tchar_ptr + hostname_len - len + 2) != 0)
@@ -1610,7 +1641,7 @@
         _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr);
         failf(data, "schannel: CertGetNameString() certificate hostname "
               "(%s) did not match connection (%s)",
-              _cert_hostname, conn->host.name);
+              _cert_hostname, conn_hostname);
         Curl_unicodefree(_cert_hostname);
       }
       Curl_unicodefree(hostname.tchar_ptr);
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 3863777..e8fd3cf 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -61,10 +61,11 @@
 #include "vtls.h" /* generic SSL protos etc */
 #include "slist.h"
 #include "sendf.h"
-#include "rawstr.h"
+#include "strcase.h"
 #include "url.h"
 #include "progress.h"
 #include "share.h"
+#include "multiif.h"
 #include "timeval.h"
 #include "curl_md5.h"
 #include "warnless.h"
@@ -80,96 +81,49 @@
                                  (data->share->specifier &             \
                                   (1<<CURL_LOCK_DATA_SSL_SESSION)))
 
-static bool safe_strequal(char* str1, char* str2)
-{
-  if(str1 && str2)
-    /* both pointers point to something then compare them */
-    return (0 != Curl_raw_equal(str1, str2)) ? TRUE : FALSE;
-  else
-    /* if both pointers are NULL then treat them as equal */
-    return (!str1 && !str2) ? TRUE : FALSE;
-}
+#define CLONE_STRING(var)                    \
+  if(source->var) {                          \
+    dest->var = strdup(source->var);         \
+    if(!dest->var)                           \
+      return FALSE;                          \
+  }                                          \
+  else                                       \
+    dest->var = NULL;
 
 bool
-Curl_ssl_config_matches(struct ssl_config_data* data,
-                        struct ssl_config_data* needle)
+Curl_ssl_config_matches(struct ssl_primary_config* data,
+                        struct ssl_primary_config* needle)
 {
   if((data->version == needle->version) &&
      (data->verifypeer == needle->verifypeer) &&
      (data->verifyhost == needle->verifyhost) &&
-     safe_strequal(data->CApath, needle->CApath) &&
-     safe_strequal(data->CAfile, needle->CAfile) &&
-     safe_strequal(data->clientcert, needle->clientcert) &&
-     safe_strequal(data->random_file, needle->random_file) &&
-     safe_strequal(data->egdsocket, needle->egdsocket) &&
-     safe_strequal(data->cipher_list, needle->cipher_list))
+     Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
+     Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
+     Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
+     Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list))
     return TRUE;
 
   return FALSE;
 }
 
 bool
-Curl_clone_ssl_config(struct ssl_config_data *source,
-                      struct ssl_config_data *dest)
+Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
+                              struct ssl_primary_config *dest)
 {
-  dest->sessionid = source->sessionid;
   dest->verifyhost = source->verifyhost;
   dest->verifypeer = source->verifypeer;
   dest->version = source->version;
 
-  if(source->CAfile) {
-    dest->CAfile = strdup(source->CAfile);
-    if(!dest->CAfile)
-      return FALSE;
-  }
-  else
-    dest->CAfile = NULL;
-
-  if(source->CApath) {
-    dest->CApath = strdup(source->CApath);
-    if(!dest->CApath)
-      return FALSE;
-  }
-  else
-    dest->CApath = NULL;
-
-  if(source->cipher_list) {
-    dest->cipher_list = strdup(source->cipher_list);
-    if(!dest->cipher_list)
-      return FALSE;
-  }
-  else
-    dest->cipher_list = NULL;
-
-  if(source->egdsocket) {
-    dest->egdsocket = strdup(source->egdsocket);
-    if(!dest->egdsocket)
-      return FALSE;
-  }
-  else
-    dest->egdsocket = NULL;
-
-  if(source->random_file) {
-    dest->random_file = strdup(source->random_file);
-    if(!dest->random_file)
-      return FALSE;
-  }
-  else
-    dest->random_file = NULL;
-
-  if(source->clientcert) {
-    dest->clientcert = strdup(source->clientcert);
-    if(!dest->clientcert)
-      return FALSE;
-    dest->sessionid = FALSE;
-  }
-  else
-    dest->clientcert = NULL;
-
+  CLONE_STRING(CAfile);
+  CLONE_STRING(CApath);
+  CLONE_STRING(cipher_list);
+  CLONE_STRING(egdsocket);
+  CLONE_STRING(random_file);
+  CLONE_STRING(clientcert);
   return TRUE;
 }
 
-void Curl_free_ssl_config(struct ssl_config_data* sslc)
+void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
 {
   Curl_safefree(sslc->CAfile);
   Curl_safefree(sslc->CApath);
@@ -179,77 +133,6 @@
   Curl_safefree(sslc->clientcert);
 }
 
-
-/*
- * Curl_rand() returns a random unsigned integer, 32bit.
- *
- * This non-SSL function is put here only because this file is the only one
- * with knowledge of what the underlying SSL libraries provide in terms of
- * randomizers.
- *
- * NOTE: 'data' may be passed in as NULL when coming from external API without
- * easy handle!
- *
- */
-
-unsigned int Curl_rand(struct Curl_easy *data)
-{
-  unsigned int r = 0;
-  static unsigned int randseed;
-  static bool seeded = FALSE;
-
-#ifdef CURLDEBUG
-  char *force_entropy = getenv("CURL_ENTROPY");
-  if(force_entropy) {
-    if(!seeded) {
-      size_t elen = strlen(force_entropy);
-      size_t clen = sizeof(randseed);
-      size_t min = elen < clen ? elen : clen;
-      memcpy((char *)&randseed, force_entropy, min);
-      seeded = TRUE;
-    }
-    else
-      randseed++;
-    return randseed;
-  }
-#endif
-
-  /* data may be NULL! */
-  if(!Curl_ssl_random(data, (unsigned char *)&r, sizeof(r)))
-    return r;
-
-  /* If Curl_ssl_random() returns non-zero it couldn't offer randomness and we
-     instead perform a "best effort" */
-
-#ifdef RANDOM_FILE
-  if(!seeded) {
-    /* if there's a random file to read a seed from, use it */
-    int fd = open(RANDOM_FILE, O_RDONLY);
-    if(fd > -1) {
-      /* read random data into the randseed variable */
-      ssize_t nread = read(fd, &randseed, sizeof(randseed));
-      if(nread == sizeof(randseed))
-        seeded = TRUE;
-      close(fd);
-    }
-  }
-#endif
-
-  if(!seeded) {
-    struct timeval now = curlx_tvnow();
-    infof(data, "WARNING: Using weak random seed\n");
-    randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
-    randseed = randseed * 1103515245 + 12345;
-    randseed = randseed * 1103515245 + 12345;
-    randseed = randseed * 1103515245 + 12345;
-    seeded = TRUE;
-  }
-
-  /* Return an unsigned 32-bit pseudo-random number. */
-  r = randseed = randseed * 1103515245 + 12345;
-  return (r << 16) | ((r >> 16) & 0xFFFF);
-}
-
 int Curl_ssl_backend(void)
 {
   return (int)CURL_SSL_BACKEND;
@@ -290,19 +173,42 @@
 static bool ssl_prefs_check(struct Curl_easy *data)
 {
   /* check for CURLOPT_SSLVERSION invalid parameter value */
-  if((data->set.ssl.version < 0)
-     || (data->set.ssl.version >= CURL_SSLVERSION_LAST)) {
+  if((data->set.ssl.primary.version < 0)
+     || (data->set.ssl.primary.version >= CURL_SSLVERSION_LAST)) {
     failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
     return FALSE;
   }
   return TRUE;
 }
 
+static CURLcode
+ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
+{
+  DEBUGASSERT(conn->bits.proxy_ssl_connected[sockindex]);
+  if(ssl_connection_complete == conn->ssl[sockindex].state &&
+     !conn->proxy_ssl[sockindex].use) {
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_NSS) ||  \
+  defined(USE_GSKIT)
+    conn->proxy_ssl[sockindex] = conn->ssl[sockindex];
+    memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex]));
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+  return CURLE_OK;
+}
+
 CURLcode
 Curl_ssl_connect(struct connectdata *conn, int sockindex)
 {
   CURLcode result;
 
+  if(conn->bits.proxy_ssl_connected[sockindex]) {
+    result = ssl_connect_init_proxy(conn, sockindex);
+    if(result)
+      return result;
+  }
+
   if(!ssl_prefs_check(conn->data))
     return CURLE_SSL_CONNECT_ERROR;
 
@@ -323,6 +229,11 @@
                              bool *done)
 {
   CURLcode result;
+  if(conn->bits.proxy_ssl_connected[sockindex]) {
+    result = ssl_connect_init_proxy(conn, sockindex);
+    if(result)
+      return result;
+  }
 
   if(!ssl_prefs_check(conn->data))
     return CURLE_SSL_CONNECT_ERROR;
@@ -365,7 +276,8 @@
  */
 bool Curl_ssl_getsessionid(struct connectdata *conn,
                            void **ssl_sessionid,
-                           size_t *idsize) /* set 0 if unknown */
+                           size_t *idsize, /* set 0 if unknown */
+                           int sockindex)
 {
   struct curl_ssl_session *check;
   struct Curl_easy *data = conn->data;
@@ -373,11 +285,18 @@
   long *general_age;
   bool no_match = TRUE;
 
+  const bool isProxy = CONNECT_PROXY_SSL();
+  struct ssl_primary_config * const ssl_config = isProxy ?
+                                                 &conn->proxy_ssl_config :
+                                                 &conn->ssl_config;
+  const char * const name = isProxy ? conn->http_proxy.host.name :
+                                      conn->host.name;
+  int port = isProxy ? (int)conn->port : conn->remote_port;
   *ssl_sessionid = NULL;
 
-  DEBUGASSERT(conn->ssl_config.sessionid);
+  DEBUGASSERT(data->set.general_ssl.sessionid);
 
-  if(!conn->ssl_config.sessionid)
+  if(!data->set.general_ssl.sessionid)
     /* session ID re-use is disabled */
     return TRUE;
 
@@ -387,20 +306,21 @@
   else
     general_age = &data->state.sessionage;
 
-  for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
     check = &data->state.session[i];
     if(!check->sessionid)
       /* not session ID means blank entry */
       continue;
-    if(Curl_raw_equal(conn->host.name, check->name) &&
+    if(strcasecompare(name, check->name) &&
        ((!conn->bits.conn_to_host && !check->conn_to_host) ||
-         (conn->bits.conn_to_host && check->conn_to_host &&
-           Curl_raw_equal(conn->conn_to_host.name, check->conn_to_host))) &&
+        (conn->bits.conn_to_host && check->conn_to_host &&
+         strcasecompare(conn->conn_to_host.name, check->conn_to_host))) &&
        ((!conn->bits.conn_to_port && check->conn_to_port == -1) ||
-         (conn->bits.conn_to_port && check->conn_to_port != -1 &&
-           conn->conn_to_port == check->conn_to_port)) &&
-       (conn->remote_port == check->remote_port) &&
-       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
+        (conn->bits.conn_to_port && check->conn_to_port != -1 &&
+         conn->conn_to_port == check->conn_to_port)) &&
+       (port == check->remote_port) &&
+       strcasecompare(conn->handler->scheme, check->scheme) &&
+       Curl_ssl_config_matches(ssl_config, &check->ssl_config)) {
       /* yes, we have a session ID! */
       (*general_age)++;          /* increase general age */
       check->age = *general_age; /* set this as used in this age */
@@ -429,7 +349,7 @@
     session->sessionid = NULL;
     session->age = 0; /* fresh */
 
-    Curl_free_ssl_config(&session->ssl_config);
+    Curl_free_primary_ssl_config(&session->ssl_config);
 
     Curl_safefree(session->name);
     Curl_safefree(session->conn_to_host);
@@ -444,7 +364,7 @@
   size_t i;
   struct Curl_easy *data=conn->data;
 
-  for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
     struct curl_ssl_session *check = &data->state.session[i];
 
     if(check->sessionid == ssl_sessionid) {
@@ -462,7 +382,8 @@
  */
 CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
                                void *ssl_sessionid,
-                               size_t idsize)
+                               size_t idsize,
+                               int sockindex)
 {
   size_t i;
   struct Curl_easy *data=conn->data; /* the mother of all structs */
@@ -472,10 +393,14 @@
   char *clone_conn_to_host;
   int conn_to_port;
   long *general_age;
+  const bool isProxy = CONNECT_PROXY_SSL();
+  struct ssl_primary_config * const ssl_config = isProxy ?
+                                           &conn->proxy_ssl_config :
+                                           &conn->ssl_config;
 
-  DEBUGASSERT(conn->ssl_config.sessionid);
+  DEBUGASSERT(data->set.general_ssl.sessionid);
 
-  clone_host = strdup(conn->host.name);
+  clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
   if(!clone_host)
     return CURLE_OUT_OF_MEMORY; /* bail out */
 
@@ -506,14 +431,14 @@
   }
 
   /* find an empty slot for us, or find the oldest */
-  for(i = 1; (i < data->set.ssl.max_ssl_sessions) &&
+  for(i = 1; (i < data->set.general_ssl.max_ssl_sessions) &&
         data->state.session[i].sessionid; i++) {
     if(data->state.session[i].age < oldest_age) {
       oldest_age = data->state.session[i].age;
       store = &data->state.session[i];
     }
   }
-  if(i == data->set.ssl.max_ssl_sessions)
+  if(i == data->set.general_ssl.max_ssl_sessions)
     /* cache is full, we must "kill" the oldest entry! */
     Curl_ssl_kill_session(store);
   else
@@ -529,9 +454,11 @@
   store->name = clone_host;               /* clone host name */
   store->conn_to_host = clone_conn_to_host; /* clone connect to host name */
   store->conn_to_port = conn_to_port; /* connect to port number */
-  store->remote_port = conn->remote_port; /* port number */
+  /* port number */
+  store->remote_port = isProxy ? (int)conn->port : conn->remote_port;
+  store->scheme = conn->handler->scheme;
 
-  if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
+  if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
     store->sessionid = NULL; /* let caller free sessionid */
     free(clone_host);
     free(clone_conn_to_host);
@@ -547,7 +474,7 @@
   size_t i;
   /* kill the session ID cache if not shared */
   if(data->state.session && !SSLSESSION_SHARED(data)) {
-    for(i = 0; i < data->set.ssl.max_ssl_sessions; i++)
+    for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++)
       /* the single-killer function handles empty table slots */
       Curl_ssl_kill_session(&data->state.session[i]);
 
@@ -558,6 +485,43 @@
   curlssl_close_all(data);
 }
 
+#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+    defined(USE_DARWINSSL) || defined(USE_NSS)
+/* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only. */
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
+                     int numsocks)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  if(connssl->connecting_state == ssl_connect_2_writing) {
+    /* write mode */
+    socks[0] = conn->sock[FIRSTSOCKET];
+    return GETSOCK_WRITESOCK(0);
+  }
+  else if(connssl->connecting_state == ssl_connect_2_reading) {
+    /* read mode */
+    socks[0] = conn->sock[FIRSTSOCKET];
+    return GETSOCK_READSOCK(0);
+  }
+
+  return GETSOCK_BLANK;
+}
+#else
+int Curl_ssl_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  (void)conn;
+  (void)socks;
+  (void)numsocks;
+  return GETSOCK_BLANK;
+}
+/* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
+#endif
+
 void Curl_ssl_close(struct connectdata *conn, int sockindex)
 {
   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
@@ -615,7 +579,7 @@
     return CURLE_OUT_OF_MEMORY;
 
   /* store the info in the SSL section */
-  data->set.ssl.max_ssl_sessions = amount;
+  data->set.general_ssl.max_ssl_sessions = amount;
   data->state.session = session;
   data->state.sessionage = 1; /* this is brand new */
   return CURLE_OK;
@@ -691,9 +655,9 @@
                                     const char *value,
                                     size_t valuelen)
 {
-  struct curl_certinfo * ci = &data->info.certs;
-  char * output;
-  struct curl_slist * nl;
+  struct curl_certinfo *ci = &data->info.certs;
+  char *output;
+  struct curl_slist *nl;
   CURLcode result = CURLE_OK;
   size_t labellen = strlen(label);
   size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
@@ -736,11 +700,16 @@
   return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
 }
 
-int Curl_ssl_random(struct Curl_easy *data,
-                     unsigned char *entropy,
-                     size_t length)
+CURLcode Curl_ssl_random(struct Curl_easy *data,
+                         unsigned char *entropy,
+                         size_t length)
 {
-  return curlssl_random(data, entropy, length);
+  int rc = curlssl_random(data, entropy, length);
+  if(rc) {
+    failf(data, "PRNG seeding failed");
+    return CURLE_FAILED_INIT; /* possibly weird return code */
+  }
+  return CURLE_OK;
 }
 
 /*
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index a41ecc3..2aabeda 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -50,13 +50,24 @@
 #define ALPN_HTTP_1_1_LENGTH 8
 #define ALPN_HTTP_1_1 "http/1.1"
 
-bool Curl_ssl_config_matches(struct ssl_config_data* data,
-                             struct ssl_config_data* needle);
-bool Curl_clone_ssl_config(struct ssl_config_data* source,
-                           struct ssl_config_data* dest);
-void Curl_free_ssl_config(struct ssl_config_data* sslc);
+/* set of helper macros for the backends to access the correct fields. For the
+   proxy or for the remote host - to properly support HTTPS proxy */
 
-unsigned int Curl_rand(struct Curl_easy *);
+#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
+  ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
+  CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
+#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
+                             data->set.ssl.var)
+#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ?          \
+  conn->proxy_ssl_config.var : conn->ssl_config.var)
+
+bool Curl_ssl_config_matches(struct ssl_primary_config* data,
+                             struct ssl_primary_config* needle);
+bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
+                                   struct ssl_primary_config *dest);
+void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
+                     int numsocks);
 
 int Curl_ssl_backend(void);
 
@@ -87,12 +98,12 @@
 /* Certificate information list handling. */
 
 void Curl_ssl_free_certinfo(struct Curl_easy *data);
-CURLcode Curl_ssl_init_certinfo(struct Curl_easy * data, int num);
-CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy * data, int certnum,
-                                    const char * label, const char * value,
+CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num);
+CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum,
+                                    const char *label, const char *value,
                                     size_t valuelen);
-CURLcode Curl_ssl_push_certinfo(struct Curl_easy * data, int certnum,
-                                const char * label, const char * value);
+CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, int certnum,
+                                const char *label, const char *value);
 
 /* Functions to be used by SSL library adaptation functions */
 
@@ -116,7 +127,8 @@
  */
 bool Curl_ssl_getsessionid(struct connectdata *conn,
                            void **ssl_sessionid,
-                           size_t *idsize); /* set 0 if unknown */
+                           size_t *idsize, /* set 0 if unknown */
+                           int sockindex);
 /* add a new session ID
  * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
  * Caller must ensure that it has properly shared ownership of this sessionid
@@ -124,7 +136,8 @@
  */
 CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
                                void *ssl_sessionid,
-                               size_t idsize);
+                               size_t idsize,
+                               int sockindex);
 /* Kill a single session ID entry in the cache
  * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
  * This will call engine-specific curlssl_session_free function, which must
@@ -140,10 +153,9 @@
  */
 void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
 
-/* get N random bytes into the buffer, return 0 if a find random is filled
-   in */
-int Curl_ssl_random(struct Curl_easy *data, unsigned char *buffer,
-                    size_t length);
+/* get N random bytes into the buffer */
+CURLcode Curl_ssl_random(struct Curl_easy *data, unsigned char *buffer,
+                         size_t length);
 CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
                          size_t tmplen,
                          unsigned char *md5sum, /* output */
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index e17bcd9..acd98e4 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -27,7 +27,7 @@
 
 #include <curl/curl.h>
 #include "urldata.h"
-#include "strequal.h"
+#include "strcase.h"
 #include "hostcheck.h"
 #include "vtls/vtls.h"
 #include "sendf.h"
@@ -40,6 +40,9 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
+/* For overflow checks. */
+#define CURL_SIZE_T_MAX         ((size_t)-1)
+
 
 /* ASN.1 OIDs. */
 static const char       cnOID[] = "2.5.4.3";    /* Common name. */
@@ -105,8 +108,8 @@
  */
 
 
-const char * Curl_getASN1Element(curl_asn1Element * elem,
-                                 const char * beg, const char * end)
+const char *Curl_getASN1Element(curl_asn1Element *elem,
+                                const char *beg, const char *end)
 {
   unsigned char b;
   unsigned long len;
@@ -116,8 +119,8 @@
      ending at `end'.
      Returns a pointer in source string after the parsed element, or NULL
      if an error occurs. */
-
-  if(beg >= end || !*beg)
+  if(!beg || !end || beg >= end || !*beg ||
+     (size_t)(end - beg) > CURL_ASN1_MAX)
     return (const char *) NULL;
 
   /* Process header byte. */
@@ -152,7 +155,7 @@
     elem->end = beg;
     return beg + 1;
   }
-  else if(beg + b > end)
+  else if((unsigned)b > (size_t)(end - beg))
     return (const char *) NULL; /* Does not fit in source. */
   else {
     /* Get long length. */
@@ -163,28 +166,28 @@
       len = (len << 8) | (unsigned char) *beg++;
     } while(--b);
   }
-  if((unsigned long) (end - beg) < len)
+  if(len > (size_t)(end - beg))
     return (const char *) NULL;  /* Element data does not fit in source. */
   elem->beg = beg;
   elem->end = beg + len;
   return elem->end;
 }
 
-static const curl_OID * searchOID(const char * oid)
+static const curl_OID * searchOID(const char *oid)
 {
-  const curl_OID * op;
+  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) || curl_strequal(op->textoid, oid))
+    if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
       return op;
 
   return (const curl_OID *) NULL;
 }
 
-static const char * bool2str(const char * beg, const char * end)
+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
@@ -195,22 +198,24 @@
   return strdup(*beg? "TRUE": "FALSE");
 }
 
-static const char * octet2str(const char * beg, const char * end)
+static const char *octet2str(const char *beg, const char *end)
 {
   size_t n = end - beg;
-  char * buf;
+  char *buf = NULL;
 
   /* Convert an ASN.1 octet string to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
 
-  buf = malloc(3 * n + 1);
-  if(buf)
-    for(n = 0; beg < end; n += 3)
-      snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+  if(n <= (CURL_SIZE_T_MAX - 1) / 3) {
+    buf = malloc(3 * n + 1);
+    if(buf)
+      for(n = 0; beg < end; n += 3)
+        snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+  }
   return buf;
 }
 
-static const char * bit2str(const char * beg, const char * end)
+static const char *bit2str(const char *beg, const char *end)
 {
   /* Convert an ASN.1 bit string to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
@@ -220,7 +225,7 @@
   return octet2str(beg, end);
 }
 
-static const char * int2str(const char * beg, const char * end)
+static const char *int2str(const char *beg, const char *end)
 {
   long val = 0;
   size_t n = end - beg;
@@ -246,14 +251,14 @@
 }
 
 static ssize_t
-utf8asn1str(char * * to, int type, const char * from, const char * end)
+utf8asn1str(char **to, int type, const char *from, const char *end)
 {
   size_t inlength = end - from;
   int size = 1;
   size_t outlength;
   int charsize;
   unsigned int wc;
-  char * buf;
+  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
@@ -282,6 +287,8 @@
 
   if(inlength % size)
     return -1;  /* Length inconsistent with character size. */
+  if(inlength / size > (CURL_SIZE_T_MAX - 1) / 4)
+    return -1;  /* Too big. */
   buf = malloc(4 * (inlength / size) + 1);
   if(!buf)
     return -1;  /* Not enough memory. */
@@ -335,9 +342,9 @@
   return outlength;
 }
 
-static const char * string2str(int type, const char * beg, const char * end)
+static const char *string2str(int type, const char *beg, const char *end)
 {
-  char * buf;
+  char *buf;
 
   /* Convert an ASN.1 String into its UTF-8 string representation.
      Return the dynamically allocated string, or NULL if an error occurs. */
@@ -347,7 +354,7 @@
   return buf;
 }
 
-static int encodeUint(char * buf, int n, unsigned int x)
+static int encodeUint(char *buf, int n, unsigned int x)
 {
   int i = 0;
   unsigned int y = x / 10;
@@ -367,7 +374,7 @@
   return i;
 }
 
-static int encodeOID(char * buf, int n, const char * beg, const char * end)
+static int encodeOID(char *buf, int n, const char *beg, const char *end)
 {
   int i = 0;
   unsigned int x;
@@ -406,9 +413,9 @@
   return i;
 }
 
-static const char * OID2str(const char * beg, const char * end, bool symbolic)
+static const char *OID2str(const char *beg, const char *end, bool symbolic)
 {
-  char * buf = (char *) NULL;
+  char *buf = (char *) NULL;
   const curl_OID * op;
   int n;
 
@@ -436,14 +443,14 @@
   return buf;
 }
 
-static const char * GTime2str(const char * beg, const char * end)
+static const char *GTime2str(const char *beg, const char *end)
 {
-  const char * tzp;
-  const char * fracp;
+  const char *tzp;
+  const char *fracp;
   char sec1, sec2;
   size_t fracl;
   size_t tzl;
-  const char * sep = "";
+  const char *sep = "";
 
   /* Convert an ASN.1 Generalized time to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
@@ -499,11 +506,11 @@
                        sep, tzl, tzp);
 }
 
-static const char * UTime2str(const char * beg, const char * end)
+static const char *UTime2str(const char *beg, const char *end)
 {
-  const char * tzp;
+  const char *tzp;
   size_t tzl;
-  const char * sec;
+  const char *sec;
 
   /* Convert an ASN.1 UTC time to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
@@ -538,7 +545,7 @@
                        tzl, tzp);
 }
 
-const char * Curl_ASN1tostr(curl_asn1Element * elem, int type)
+const char *Curl_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. */
@@ -581,17 +588,17 @@
   return (const char *) NULL;   /* Unsupported. */
 }
 
-static ssize_t encodeDN(char * buf, size_t n, curl_asn1Element * dn)
+static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
 {
   curl_asn1Element rdn;
   curl_asn1Element atv;
   curl_asn1Element oid;
   curl_asn1Element value;
   size_t l = 0;
-  const char * p1;
-  const char * p2;
-  const char * p3;
-  const char * str;
+  const char *p1;
+  const char *p2;
+  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'. */
@@ -647,9 +654,9 @@
   return l;
 }
 
-const char * Curl_DNtostr(curl_asn1Element * dn)
+const char *Curl_DNtostr(curl_asn1Element *dn)
 {
-  char * buf = (char *) NULL;
+  char *buf = (char *) NULL;
   ssize_t n = encodeDN(buf, 0, dn);
 
   /* Convert an ASN.1 distinguished name into a printable string.
@@ -669,12 +676,12 @@
  * X509 parser.
  */
 
-void Curl_parseX509(curl_X509certificate * cert,
-                    const char * beg, const char * end)
+int Curl_parseX509(curl_X509certificate *cert,
+                   const char *beg, const char *end)
 {
   curl_asn1Element elem;
   curl_asn1Element tbsCertificate;
-  const char * ccp;
+  const char *ccp;
   static const char defaultVersion = 0;  /* v1. */
 
   /* ASN.1 parse an X509 certificate into structure subfields.
@@ -686,7 +693,8 @@
   cert->certificate.end = end;
 
   /* Get the sequence content. */
-  Curl_getASN1Element(&elem, beg, end);
+  if(!Curl_getASN1Element(&elem, beg, end))
+    return -1;  /* Invalid bounds/size. */
   beg = elem.beg;
   end = elem.end;
 
@@ -749,9 +757,10 @@
   }
   if(elem.tag == 3)
     Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
+  return 0;
 }
 
-static size_t copySubstring(char * to, const char * from)
+static size_t copySubstring(char *to, const char *from)
 {
   size_t i;
 
@@ -768,8 +777,8 @@
   return i;
 }
 
-static const char * dumpAlgo(curl_asn1Element * param,
-                             const char * beg, const char * end)
+static const char *dumpAlgo(curl_asn1Element *param,
+                            const char *beg, const char *end)
 {
   curl_asn1Element oid;
 
@@ -784,10 +793,10 @@
   return OID2str(oid.beg, oid.end, TRUE);
 }
 
-static void do_pubkey_field(struct Curl_easy * data, int certnum,
-                            const char * label, curl_asn1Element * elem)
+static void do_pubkey_field(struct Curl_easy *data, int certnum,
+                            const char *label, curl_asn1Element *elem)
 {
-  const char * output;
+  const char *output;
 
   /* Generate a certificate information record for the public key. */
 
@@ -801,14 +810,14 @@
   }
 }
 
-static void do_pubkey(struct Curl_easy * data, int certnum,
-                      const char * algo, curl_asn1Element * param,
-                      curl_asn1Element * pubkey)
+static void do_pubkey(struct Curl_easy *data, int certnum,
+                      const char *algo, curl_asn1Element *param,
+                      curl_asn1Element *pubkey)
 {
   curl_asn1Element elem;
   curl_asn1Element pk;
-  const char * p;
-  const char * q;
+  const char *p;
+  const char *q;
   unsigned long len;
   unsigned int i;
 
@@ -817,7 +826,7 @@
   /* Get the public key (single element). */
   Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
 
-  if(curl_strequal(algo, "rsaEncryption")) {
+  if(strcasecompare(algo, "rsaEncryption")) {
     p = Curl_getASN1Element(&elem, pk.beg, pk.end);
     /* Compute key length. */
     for(q = elem.beg; !*q && q < elem.end; q++)
@@ -842,7 +851,7 @@
     Curl_getASN1Element(&elem, p, pk.end);
     do_pubkey_field(data, certnum, "rsa(e)", &elem);
   }
-  else if(curl_strequal(algo, "dsa")) {
+  else if(strcasecompare(algo, "dsa")) {
     p = Curl_getASN1Element(&elem, param->beg, param->end);
     do_pubkey_field(data, certnum, "dsa(p)", &elem);
     p = Curl_getASN1Element(&elem, p, param->end);
@@ -851,7 +860,7 @@
     do_pubkey_field(data, certnum, "dsa(g)", &elem);
     do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
   }
-  else if(curl_strequal(algo, "dhpublicnumber")) {
+  else if(strcasecompare(algo, "dhpublicnumber")) {
     p = Curl_getASN1Element(&elem, param->beg, param->end);
     do_pubkey_field(data, certnum, "dh(p)", &elem);
     Curl_getASN1Element(&elem, param->beg, param->end);
@@ -859,24 +868,24 @@
     do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
   }
 #if 0 /* Patent-encumbered. */
-  else if(curl_strequal(algo, "ecPublicKey")) {
+  else if(strcasecompare(algo, "ecPublicKey")) {
     /* Left TODO. */
   }
 #endif
 }
 
-CURLcode Curl_extract_certinfo(struct connectdata * conn,
+CURLcode Curl_extract_certinfo(struct connectdata *conn,
                                int certnum,
-                               const char * beg,
-                               const char * end)
+                               const char *beg,
+                               const char *end)
 {
   curl_X509certificate cert;
-  struct Curl_easy * data = conn->data;
+  struct Curl_easy *data = conn->data;
   curl_asn1Element param;
-  const char * ccp;
-  char * cp1;
+  const char *ccp;
+  char *cp1;
   size_t cl1;
-  char * cp2;
+  char *cp2;
   CURLcode result;
   unsigned long version;
   size_t i;
@@ -889,7 +898,8 @@
   /* Prepare the certificate information for curl_easy_getinfo(). */
 
   /* Extract the certificate ASN.1 elements. */
-  Curl_parseX509(&cert, beg, end);
+  if(Curl_parseX509(&cert, beg, end))
+    return CURLE_OUT_OF_MEMORY;
 
   /* Subject. */
   ccp = Curl_DNtostr(&cert.subject);
@@ -1029,12 +1039,12 @@
 
 #if defined(USE_GSKIT)
 
-static const char * checkOID(const char * beg, const char * end,
-                             const char * oid)
+static const char *checkOID(const char *beg, const char *end,
+                            const char *oid)
 {
   curl_asn1Element e;
-  const char * ccp;
-  const char * p;
+  const char *ccp;
+  const char *p;
   bool matched;
 
   /* Check if first ASN.1 element at `beg' is the given OID.
@@ -1053,21 +1063,26 @@
   return matched? ccp: (const char *) NULL;
 }
 
-CURLcode Curl_verifyhost(struct connectdata * conn,
-                         const char * beg, const char * end)
+CURLcode Curl_verifyhost(struct connectdata *conn,
+                         const char *beg, const char *end)
 {
-  struct Curl_easy * data = conn->data;
+  struct Curl_easy *data = conn->data;
   curl_X509certificate cert;
   curl_asn1Element dn;
   curl_asn1Element elem;
   curl_asn1Element ext;
   curl_asn1Element name;
-  const char * p;
-  const char * q;
-  char * dnsname;
+  const char *p;
+  const char *q;
+  char *dnsname;
   int matched = -1;
   size_t addrlen = (size_t) -1;
   ssize_t len;
+  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
+                                                conn->host.name;
+  const char * const dispname = SSL_IS_PROXY()?
+                                  conn->http_proxy.host.dispname:
+                                  conn->host.dispname;
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
@@ -1077,20 +1092,19 @@
   /* Verify that connection server matches info in X509 certificate at
      `beg'..`end'. */
 
-  if(!data->set.ssl.verifyhost)
+  if(!SSL_CONN_CONFIG(verifyhost))
     return CURLE_OK;
 
-  if(!beg)
+  if(Curl_parseX509(&cert, beg, end))
     return CURLE_PEER_FAILED_VERIFICATION;
-  Curl_parseX509(&cert, beg, end);
 
   /* Get the server IP address. */
 #ifdef ENABLE_IPV6
-  if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+  if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, hostname, &addr))
     addrlen = sizeof(struct in6_addr);
   else
 #endif
-  if(Curl_inet_pton(AF_INET, conn->host.name, &addr))
+  if(Curl_inet_pton(AF_INET, hostname, &addr))
     addrlen = sizeof(struct in_addr);
 
   /* Process extensions. */
@@ -1113,7 +1127,7 @@
           len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
                             name.beg, name.end);
           if(len > 0 && (size_t)len == strlen(dnsname))
-            matched = Curl_cert_hostcheck(dnsname, conn->host.name);
+            matched = Curl_cert_hostcheck(dnsname, hostname);
           else
             matched = 0;
           free(dnsname);
@@ -1131,12 +1145,12 @@
   switch (matched) {
   case 1:
     /* an alternative name matched the server hostname */
-    infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
+    infof(data, "\t subjectAltName: %s matched\n", dispname);
     return CURLE_OK;
   case 0:
     /* an alternative name field existed, but didn't match and then
        we MUST fail */
-    infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
+    infof(data, "\t subjectAltName does not match %s\n", dispname);
     return CURLE_PEER_FAILED_VERIFICATION;
   }
 
@@ -1168,14 +1182,14 @@
     }
     if(strlen(dnsname) != (size_t) len)         /* Nul byte in string ? */
       failf(data, "SSL: illegal cert name field");
-    else if(Curl_cert_hostcheck((const char *) dnsname, conn->host.name)) {
+    else if(Curl_cert_hostcheck((const char *) dnsname, hostname)) {
       infof(data, "\t common name: %s (matched)\n", dnsname);
       free(dnsname);
       return CURLE_OK;
     }
     else
       failf(data, "SSL: certificate subject name '%s' does not match "
-            "target host name '%s'", dnsname, conn->host.dispname);
+            "target host name '%s'", dnsname, dispname);
     free(dnsname);
   }
 
diff --git a/lib/x509asn1.h b/lib/x509asn1.h
index 0f2b930..ce40297 100644
--- a/lib/x509asn1.h
+++ b/lib/x509asn1.h
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -34,6 +34,9 @@
  * Constants.
  */
 
+/* Largest supported ASN.1 structure. */
+#define CURL_ASN1_MAX                   ((size_t) 0x40000)      /* 256K */
+
 /* ASN.1 classes. */
 #define CURL_ASN1_UNIVERSAL             0
 #define CURL_ASN1_APPLICATION           1
@@ -117,16 +120,15 @@
  * Prototypes.
  */
 
-const char * Curl_getASN1Element(curl_asn1Element * elem,
-                                 const char * beg, const char * end);
-const char * Curl_ASN1tostr(curl_asn1Element * elem, int type);
-const char * Curl_DNtostr(curl_asn1Element * dn);
-void Curl_parseX509(curl_X509certificate * cert,
-                    const char * beg, const char * end);
-CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
-                               const char * beg, const char * end);
-CURLcode Curl_verifyhost(struct connectdata * conn,
-                         const char * beg, const char * end);
-
+const char *Curl_getASN1Element(curl_asn1Element *elem,
+                                 const char *beg, const char *end);
+const char *Curl_ASN1tostr(curl_asn1Element *elem, int type);
+const char *Curl_DNtostr(curl_asn1Element *dn);
+int Curl_parseX509(curl_X509certificate *cert,
+                   const char *beg, const char *end);
+CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
+                               const char *beg, const char *end);
+CURLcode Curl_verifyhost(struct connectdata *conn,
+                         const char *beg, const char *end);
 #endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */
 #endif /* HEADER_CURL_X509ASN1_H */
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index 6ecd323..3219baf 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -64,7 +64,7 @@
 ***
 *** Whatever settings are present in CFLAGS will be used for this run.
 ***
-*** If you wish to help the cURL project to better support your compiler
+*** If you wish to help the curl project to better support your compiler
 *** you can report this and the required info on the libcurl development
 *** mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/
 ***
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index ee7a252..dde7fe2 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2016, 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
@@ -4739,12 +4739,15 @@
   tst_allow_poll="unknown"
   #
   case $host_os in
-    darwin[[123456789]].*|darwin10.*|darwin11.*|darwin12.*|interix*)
+    darwin*|interix*)
       dnl poll() does not work on these platforms
       dnl Interix: "does provide poll(), but the implementing developer must
       dnl have been in a bad mood, because poll() only works on the /proc
       dnl filesystem here"
+      dnl macOS: poll() first didn't exist, then was broken until fixed in 10.9
+      dnl only to break again in 10.12.
       curl_disallow_poll="yes"
+      tst_compi_poll="no"
       ;;
   esac
   #
@@ -4803,11 +4806,27 @@
       AC_LANG_PROGRAM([[
         $curl_includes_stdlib
         $curl_includes_poll
+        $curl_includes_time
       ]],[[
+        /* detect the original poll() breakage */
         if(0 != poll(0, 0, 10))
           exit(1); /* fail */
-        else
-          exit(0);
+        else {
+          /* detect the 10.12 poll() breakage */
+          struct timeval before, after;
+          int rc;
+          size_t us;
+
+          gettimeofday(&before, NULL);
+          rc = poll(NULL, 0, 500);
+          gettimeofday(&after, NULL);
+
+          us = (after.tv_sec - before.tv_sec) * 1000000 +
+            (after.tv_usec - before.tv_usec);
+
+          if(us < 400000)
+            exit(1);
+        }
       ]])
     ],[
       AC_MSG_RESULT([yes])
diff --git a/maketgz b/maketgz
index aede6d0..8d117e6 100755
--- a/maketgz
+++ b/maketgz
@@ -31,6 +31,11 @@
   exit
 fi
 
+if [ "xonly" = "x$2" ]; then
+    echo "Setup version number only!"
+    only=1
+fi
+
 libversion="$version"
 
 # we make curl the same version as libcurl
@@ -40,25 +45,50 @@
 minor=`echo $libversion |cut -d. -f2 | sed -e "s/[^0-9]//g"`
 patch=`echo $libversion |cut -d. -f3 | cut -d- -f1 | sed -e "s/[^0-9]//g"`
 
+if test -z "$patch"; then
+    echo "invalid version number? needs to be z.y.z"
+    exit
+fi
+
 numeric=`perl -e 'printf("%02x%02x%02x\n", '"$major, $minor, $patch);"`
 
 HEADER=include/curl/curlver.h
 CHEADER=src/tool_version.h
+PLIST=lib/libcurl.plist
+
+if test -z "$only"; then
+    ext=".dist"
+    # when not setting up version numbers locally
+    for a in $HEADER $CHEADER $PLIST; do
+        cp $a "$a$ext"
+    done
+    HEADER="$HEADER$ext"
+    CHEADER="$CHEADER$ext"
+    PLIST="$PLIST$ext"
+fi
 
 # requires a date command that knows -u for UTC time zone
 datestamp=`LC_TIME=C date -u`
 
 # Replace version number in header file:
-sed -e 's/^#define LIBCURL_VERSION .*/#define LIBCURL_VERSION "'$libversion'"/g' \
+sed -i -e 's/^#define LIBCURL_VERSION .*/#define LIBCURL_VERSION "'$libversion'"/g' \
     -e 's/^#define LIBCURL_VERSION_NUM .*/#define LIBCURL_VERSION_NUM 0x'$numeric'/g' \
     -e 's/^#define LIBCURL_VERSION_MAJOR .*/#define LIBCURL_VERSION_MAJOR '$major'/g' \
     -e 's/^#define LIBCURL_VERSION_MINOR .*/#define LIBCURL_VERSION_MINOR '$minor'/g' \
     -e 's/^#define LIBCURL_VERSION_PATCH .*/#define LIBCURL_VERSION_PATCH '$patch'/g' \
     -e "s/^#define LIBCURL_TIMESTAMP .*/#define LIBCURL_TIMESTAMP \"$datestamp\"/g" \
- $HEADER >$HEADER.dist
+ $HEADER
 
 # Replace version number in header file:
-sed 's/#define CURL_VERSION .*/#define CURL_VERSION "'$curlversion'"/g' $CHEADER >$CHEADER.dist
+sed -i 's/#define CURL_VERSION .*/#define CURL_VERSION "'$curlversion'"/g' $CHEADER
+
+# Replace version number in plist file:
+sed -i "s/7\.12\.3/$libversion/g" $PLIST
+
+if test -n "$only"; then
+    # done!
+    exit;
+fi
 
 # Generate VC7, VC8, VC9, VC10, VC11, VC12 and VC14 versions from the VC6
 # Makefile versions
@@ -68,10 +98,6 @@
   mv lib/Makefile.$ver lib/Makefile.$ver.dist
 done
 
-# Replace version number in plist file:
-PLIST=lib/libcurl.plist
-sed "s/7\.12\.3/$libversion/g" $PLIST > $PLIST.dist
-
 echo "curl version $curlversion"
 echo "libcurl version $libversion"
 echo "libcurl numerical $numeric"
@@ -115,16 +141,7 @@
 
 ############################################################################
 #
-# Make sure we have updated HTML versions of all man pages:
-#
-echo "make html"
-make -s html
-
-# And the PDF versions
-echo "make pdf"
-make -s pdf
-
-# And the IDE files
+# Update the IDE files
 echo "make vc-ide"
 make -s vc-ide
 
diff --git a/packages/AIX/RPM/README b/packages/AIX/RPM/README
index 790beb8..51615ad 100644
--- a/packages/AIX/RPM/README
+++ b/packages/AIX/RPM/README
@@ -29,5 +29,5 @@
 Lastly, the spec file expects the Curl source distribution file to be
 in .tar.bz2 format.
 
-The nifty cURL header of this README is a ripoff of the vms/readme file.
+The nifty curl header of this README is a ripoff of the vms/readme file.
 
diff --git a/packages/DOS/common.dj b/packages/DOS/common.dj
index 85b611c..e069ce6 100644
--- a/packages/DOS/common.dj
+++ b/packages/DOS/common.dj
@@ -1,7 +1,7 @@
 #
 # Common defines for curl (djgpp/Watt-32)
 #
-# Assumes you've unpacked cURL with long-file names
+# Assumes you've unpacked curl with long-file names
 # I.e use "set LFN=y" before untaring on Win9x/XP.
 # Requires sed, yacc, rm and the usual stuff.
 #
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index 24cf39e..e709f40 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -76,16 +76,16 @@
         CURLOPT_DNS_SERVERS
         CURLOPT_EGDSOCKET
         CURLOPT_ENCODING
+        CURLOPT_FTPPORT
         CURLOPT_FTP_ACCOUNT
         CURLOPT_FTP_ALTERNATIVE_TO_USER
-        CURLOPT_FTPPORT
         CURLOPT_INTERFACE
         CURLOPT_ISSUERCERT
         CURLOPT_KEYPASSWD
         CURLOPT_KRBLEVEL
         CURLOPT_LOGIN_OPTIONS
-        CURLOPT_MAIL_FROM
         CURLOPT_MAIL_AUTH
+        CURLOPT_MAIL_FROM
         CURLOPT_NETRC_FILE
         CURLOPT_NOPROXY
         CURLOPT_PASSWORD
@@ -94,7 +94,19 @@
         CURLOPT_PROXYPASSWORD
         CURLOPT_PROXYUSERNAME
         CURLOPT_PROXYUSERPWD
+        CURLOPT_PROXY_CAINFO
+        CURLOPT_PROXY_CAPATH
+        CURLOPT_PROXY_CRLFILE
+        CURLOPT_PROXY_KEYPASSWD
         CURLOPT_PROXY_SERVICE_NAME
+        CURLOPT_PROXY_SSLCERT
+        CURLOPT_PROXY_SSLCERTTYPE
+        CURLOPT_PROXY_SSLKEY
+        CURLOPT_PROXY_SSLKEYTYPE
+        CURLOPT_PROXY_SSL_CIPHER_LIST
+        CURLOPT_PROXY_TLSAUTH_PASSWORD
+        CURLOPT_PROXY_TLSAUTH_TYPE
+        CURLOPT_PROXY_TLSAUTH_USERNAME
         CURLOPT_RANDOM_FILE
         CURLOPT_RANGE
         CURLOPT_REFERER
@@ -103,16 +115,17 @@
         CURLOPT_RTSP_TRANSPORT
         CURLOPT_SERVICE_NAME
         CURLOPT_SOCKS5_GSSAPI_SERVICE
+        CURLOPT_SOCKS_PROXY
         CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
         CURLOPT_SSH_KNOWNHOSTS
         CURLOPT_SSH_PRIVATE_KEYFILE
         CURLOPT_SSH_PUBLIC_KEYFILE
         CURLOPT_SSLCERT
         CURLOPT_SSLCERTTYPE
-        CURLOPT_SSL_CIPHER_LIST
         CURLOPT_SSLENGINE
         CURLOPT_SSLKEY
         CURLOPT_SSLKEYTYPE
+        CURLOPT_SSL_CIPHER_LIST
         CURLOPT_TLSAUTH_PASSWORD
         CURLOPT_TLSAUTH_TYPE
         CURLOPT_TLSAUTH_USERNAME
@@ -160,6 +173,7 @@
         CURLINFO_PRIMARY_IP
         CURLINFO_RTSP_SESSION_ID
         CURLINFO_LOCAL_IP
+        CURLINFO_SCHEME
   Likewise, the following options are followed by a struct curl_slist * * and a
 CCSID.
         CURLINFO_SSL_ENGINES
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index 3b08bef..6082442 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -615,7 +615,7 @@
   struct curl_certinfo * cipf;
   struct curl_certinfo * cipt;
 
-  /* WARNING: unlike curl_easy_get_info(), the strings returned by this
+  /* WARNING: unlike curl_easy_getinfo(), the strings returned by this
      procedure have to be free'ed. */
 
   data = (struct Curl_easy *) curl;
@@ -1147,16 +1147,16 @@
   case CURLOPT_DNS_SERVERS:
   case CURLOPT_EGDSOCKET:
   case CURLOPT_ENCODING:
+  case CURLOPT_FTPPORT:
   case CURLOPT_FTP_ACCOUNT:
   case CURLOPT_FTP_ALTERNATIVE_TO_USER:
-  case CURLOPT_FTPPORT:
   case CURLOPT_INTERFACE:
   case CURLOPT_ISSUERCERT:
   case CURLOPT_KEYPASSWD:
   case CURLOPT_KRBLEVEL:
   case CURLOPT_LOGIN_OPTIONS:
-  case CURLOPT_MAIL_FROM:
   case CURLOPT_MAIL_AUTH:
+  case CURLOPT_MAIL_FROM:
   case CURLOPT_NETRC_FILE:
   case CURLOPT_NOPROXY:
   case CURLOPT_PASSWORD:
@@ -1165,7 +1165,19 @@
   case CURLOPT_PROXYPASSWORD:
   case CURLOPT_PROXYUSERNAME:
   case CURLOPT_PROXYUSERPWD:
+  case CURLOPT_PROXY_CAINFO:
+  case CURLOPT_PROXY_CAPATH:
+  case CURLOPT_PROXY_CRLFILE:
+  case CURLOPT_PROXY_KEYPASSWD:
   case CURLOPT_PROXY_SERVICE_NAME:
+  case CURLOPT_PROXY_SSLCERT:
+  case CURLOPT_PROXY_SSLCERTTYPE:
+  case CURLOPT_PROXY_SSLKEY:
+  case CURLOPT_PROXY_SSLKEYTYPE:
+  case CURLOPT_PROXY_SSL_CIPHER_LIST:
+  case CURLOPT_PROXY_TLSAUTH_PASSWORD:
+  case CURLOPT_PROXY_TLSAUTH_TYPE:
+  case CURLOPT_PROXY_TLSAUTH_USERNAME:
   case CURLOPT_RANDOM_FILE:
   case CURLOPT_RANGE:
   case CURLOPT_REFERER:
@@ -1174,16 +1186,17 @@
   case CURLOPT_RTSP_TRANSPORT:
   case CURLOPT_SERVICE_NAME:
   case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+  case CURLOPT_SOCKS_PROXY:
   case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
   case CURLOPT_SSH_KNOWNHOSTS:
   case CURLOPT_SSH_PRIVATE_KEYFILE:
   case CURLOPT_SSH_PUBLIC_KEYFILE:
   case CURLOPT_SSLCERT:
   case CURLOPT_SSLCERTTYPE:
-  case CURLOPT_SSL_CIPHER_LIST:
   case CURLOPT_SSLENGINE:
   case CURLOPT_SSLKEY:
   case CURLOPT_SSLKEYTYPE:
+  case CURLOPT_SSL_CIPHER_LIST:
   case CURLOPT_TLSAUTH_PASSWORD:
   case CURLOPT_TLSAUTH_TYPE:
   case CURLOPT_TLSAUTH_USERNAME:
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index 1e8a93d..c0b0330 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -258,6 +258,8 @@
      d                 c                   5
      d CURL_SSLVERSION_TLSv1_2...
      d                 c                   6
+     d CURL_SSLVERSION_TLSv1_3...
+     d                 c                   7
       *
      d CURL_TLSAUTH_NONE...
      d                 c                   0
@@ -369,6 +371,8 @@
      d                 c                   6
      d  CURLE_COULDNT_CONNECT...
      d                 c                   7
+     d  CURLE_WEIRD_SERVER_REPLY...
+     d                 c                   8
      d  CURLE_FTP_WEIRD_SERVER_REPLY...
      d                 c                   8
      d  CURLE_REMOTE_ACCESS_DENIED...
@@ -653,6 +657,8 @@
      d                 c                   0
      d  CURLPROXY_HTTP_1_0...
      d                 c                   1
+     d  CURLPROXY_HTTPS...
+     d                 c                   2
      d  CURLPROXY_SOCKS4...
      d                 c                   4
      d  CURLPROXY_SOCKS5...
@@ -1252,6 +1258,44 @@
      d                 c                   10243
      d  CURLOPT_TCP_FASTOPEN...
      d                 c                   00244
+     d  CURLOPT_KEEP_SENDING_ON_ERROR...
+     d                 c                   00245
+     d  CURLOPT_PROXY_CAINFO...
+     d                 c                   10246
+     d  CURLOPT_PROXY_CAPATH...
+     d                 c                   10247
+     d  CURLOPT_PROXY_SSL_VERIFYPEER...
+     d                 c                   00248
+     d  CURLOPT_PROXY_SSL_VERIFYHOST...
+     d                 c                   00249
+     d  CURLOPT_PROXY_SSLVERSION...
+     d                 c                   00250
+     d  CURLOPT_PROXY_TLSAUTH_USERNAME...
+     d                 c                   10251
+     d  CURLOPT_PROXY_TLSAUTH_PASSWORD...
+     d                 c                   10252
+     d  CURLOPT_PROXY_TLSAUTH_TYPE...
+     d                 c                   10253
+     d  CURLOPT_PROXY_SSLCERT...
+     d                 c                   10254
+     d  CURLOPT_PROXY_SSLCERTTYPE...
+     d                 c                   10255
+     d  CURLOPT_PROXY_SSLKEY...
+     d                 c                   10256
+     d  CURLOPT_PROXY_SSLKEYTYPE...
+     d                 c                   10257
+     d  CURLOPT_PROXY_KEYPASSWD...
+     d                 c                   10258
+     d  CURLOPT_PROXY_SSL_CIPHER_LIST...
+     d                 c                   10259
+     d  CURLOPT_PROXY_CRLFILE...
+     d                 c                   10260
+     d  CURLOPT_PROXY_SSL_OPTIONS...
+     d                 c                   00261
+     d  CURLOPT_SOCKS_PROXY...
+     d                 c                   10262
+     d  CURLOPT_SOCKS_PROXYTYPE...
+     d                 c                   00263
       *
       /if not defined(CURL_NO_OLDIES)
      d  CURLOPT_FILE   c                   10001
@@ -1438,6 +1482,12 @@
      d                 c                   X'0040002D'
      d  CURLINFO_HTTP_VERSION...                                                CURLINFO_LONG + 46
      d                 c                   X'0020002E'
+     d  CURLINFO_PROXY_SSL_VERIFYRESULT...                                      CURLINFO_LONG + 47
+     d                 c                   X'0020002F'
+     d  CURLINFO_PROTOCOL...                                                    CURLINFO_LONG + 48
+     d                 c                   X'00200030'
+     d  CURLINFO_SCHEME...                                                      CURLINFO_STRING + 49
+     d                 c                   X'00100031'
       *
      d  CURLINFO_HTTP_CODE...                                                   Old ...RESPONSE_CODE
      d                 c                   X'00200002'
diff --git a/packages/Symbian/group/curl.mmp b/packages/Symbian/group/curl.mmp
index 28498ce..4b304a3 100644
--- a/packages/Symbian/group/curl.mmp
+++ b/packages/Symbian/group/curl.mmp
@@ -1,5 +1,5 @@
 //
-// cURL network retrieval client
+// curl network retrieval client
 //
 
 TARGET        curl.exe
@@ -49,7 +49,7 @@
 
 SOURCEPATH  ../../../lib
 SOURCE \
-    rawstr.c nonblock.c
+    strcase.c nonblock.c
 
 USERINCLUDE ../../../src ../../../lib ../../../include/curl
 
diff --git a/packages/Symbian/group/libcurl.mmp b/packages/Symbian/group/libcurl.mmp
index f74b19b..6388bbd 100644
--- a/packages/Symbian/group/libcurl.mmp
+++ b/packages/Symbian/group/libcurl.mmp
@@ -1,5 +1,5 @@
 //
-// libcurl.dll cURL network retrieval client library
+// libcurl.dll curl network retrieval client library
 //
 
 // Build-time options (uncomment these to enable)
@@ -31,7 +31,7 @@
   http_negotiate.c inet_pton.c strtoofft.c strerror.c amigaos.c        \
   hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c     \
   select.c vtls/gtls.c vtls/vtls.c tftp.c splay.c strdup.c socks.c     \
-  ssh.c vtls/nss.c rawstr.c curl_addrinfo.c socks_gssapi.c             \
+  ssh.c vtls/nss.c strcase.c curl_addrinfo.c socks_gssapi.c             \
   socks_sspi.c curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c    \
   pop3.c smtp.c pingpong.c rtsp.c curl_threads.c warnless.c hmac.c     \
   vtls/polarssl.c curl_rtmp.c openldap.c curl_gethostname.c gopher.c   \
diff --git a/packages/Win32/cygwin/README b/packages/Win32/cygwin/README
index a0811de..60bb5e1 100644
--- a/packages/Win32/cygwin/README
+++ b/packages/Win32/cygwin/README
@@ -12,7 +12,7 @@
   - Cygwin
   - OpenSSL 0.9.6b-2+ (*)
 
-  (*) cURL can be built without SSL support, see below for details
+  (*) curl can be built without SSL support, see below for details
 
 
 Canonical Homepage and Downloads:
@@ -41,7 +41,7 @@
   (**) LibTool 1.4.2 had a bug related to cygwin's use of ".exe" extensions,
       such that "make install" blew up at curl.exe. See this URL for details:
          http://mail.gnu.org/pipermail/libtool/2001-September/005549.html
-      The copy of ltmain.sh that is distributed with cURL includes this patch.
+      The copy of ltmain.sh that is distributed with curl includes this patch.
 
   As of curl 7.9.1, the official source compiles (under Cygwin) and tests
     100% cleanly OOTB (Out Of The Box)
@@ -100,9 +100,9 @@
   requires: cygwin openssl
 
   @ curl-devel
-  sdesc: "(lib)cURL headers, static libraries, developer docs and samples"
+  sdesc: "(lib)curl headers, static libraries, developer docs and samples"
   ldesc: "curl-devel is the developer-oriented (non-run-time) parts
-  of the cURL package. It includes header files, static libraries,
+  of the curl package. It includes header files, static libraries,
   example source code snippets, and the libcurl man pages."
   category: Web Libs Devel
   requires: cygwin openssl curl
@@ -110,5 +110,5 @@
 
 Cygwin port maintained by:
   Kevin Roth <kproth @ users . sourceforge . net>
-  Questions about cURL should be directed to curl-users@cool.haxx.se.
+  Questions about curl should be directed to curl-users@cool.haxx.se.
   Questions about this cygwin package go to cygwin@cygwin.com.
diff --git a/packages/vms/curlmsg.h b/packages/vms/curlmsg.h
index 2cb32ec..424a382 100644
--- a/packages/vms/curlmsg.h
+++ b/packages/vms/curlmsg.h
@@ -57,7 +57,8 @@
 #define CURL_COULDNT_RESOLVE_PROXY 251756594
 #define CURL_COULDNT_RESOLVE_HOST 251756602
 #define CURL_COULDNT_CONNECT 251756610
-#define CURL_FTP_WEIRD_SERVER_REPLY 251756618
+#define CURL_WEIRD_SERVER_REPLY 251756618
+#define CURL_FTP_WEIRD_SERVER_REPLY CURL_WEIRD_SERVER_REPLY
 #define CURL_FTP_ACCESS_DENIED 251756626
 #define CURL_OBSOLETE10 251756634
 #define CURL_FTP_WEIRD_PASS_REPLY 251756642
diff --git a/packages/vms/curlmsg.msg b/packages/vms/curlmsg.msg
index 7fd4483..492657c 100644
--- a/packages/vms/curlmsg.msg
+++ b/packages/vms/curlmsg.msg
@@ -30,7 +30,7 @@
 COULDNT_RESOLVE_PROXY	<could not resolve proxy>
 COULDNT_RESOLVE_HOST	<could not resolve host>
 COULDNT_CONNECT		<could not connect>
-FTP_WEIRD_SERVER_REPLY	<FTP weird server reply>
+WEIRD_SERVER_REPLY	<weird server reply>
 FTP_ACCESS_DENIED	<FTP access denied>
 OBSOLETE10		<obsolete error code>
 FTP_WEIRD_PASS_REPLY	<FTP weird PASS reply>
diff --git a/packages/vms/curlmsg.sdl b/packages/vms/curlmsg.sdl
index e192c07..db5baad 100644
--- a/packages/vms/curlmsg.sdl
+++ b/packages/vms/curlmsg.sdl
@@ -34,6 +34,7 @@
        ,"COULDNT_RESOLVE_PROXY" EQUALS %X0F018032 PREFIX "CURL" TAG ""
        ,"COULDNT_RESOLVE_HOST" EQUALS %X0F01803A PREFIX "CURL" TAG ""
        ,"COULDNT_CONNECT" EQUALS %X0F018042  PREFIX "CURL" TAG ""
+       ,"WEIRD_SERVER_REPLY" EQUALS %X0F01804A PREFIX "CURL" TAG ""
        ,"FTP_WEIRD_SERVER_REPLY" EQUALS %X0F01804A PREFIX "CURL" TAG ""
        ,"FTP_ACCESS_DENIED" EQUALS %X0F018052 PREFIX "CURL" TAG ""
        ,"OBSOLETE10"   EQUALS %X0F01805A     PREFIX "CURL" TAG ""
diff --git a/packages/vms/curlmsg_vms.h b/packages/vms/curlmsg_vms.h
index 3aef9cf..b7ff7a0 100644
--- a/packages/vms/curlmsg_vms.h
+++ b/packages/vms/curlmsg_vms.h
@@ -59,7 +59,7 @@
 	CURL_COULDNT_RESOLVE_PROXY,
 	CURL_COULDNT_RESOLVE_HOST,
 	CURL_COULDNT_CONNECT,
-	CURL_FTP_WEIRD_SERVER_REPLY,
+	CURL_WEIRD_SERVER_REPLY,
 	CURL_FTP_ACCESS_DENIED,
 	CURL_OBSOLETE10,
 	CURL_FTP_WEIRD_PASS_REPLY,
diff --git a/packages/vms/gnv_link_curl.com b/packages/vms/gnv_link_curl.com
index b7e6083..add4be9 100644
--- a/packages/vms/gnv_link_curl.com
+++ b/packages/vms/gnv_link_curl.com
@@ -416,7 +416,7 @@
            [.src]curl-tool_urlglob.o, [.src]curl-tool_util.o, -
            [.src]curl-tool_vms.o, [.src]curl-tool_writeenv.o, -
            [.src]curl-tool_writeout.o, [.src]curl-tool_xattr.o, -
-           [.src]curl-strtoofft.o, [.src]curl-strdup.o, [.src]curl-rawstr.o, -
+           [.src]curl-strtoofft.o, [.src]curl-strdup.o, [.src]curl-strcase.o, -
            [.src]curl-nonblock.o, gnv_packages_vms:curlmsg.obj,-
            sys$input:/opt
 gnv$libcurl/share
@@ -428,7 +428,7 @@
 $   curl_main = "[.packages.vms.''arch_name']tool_main.obj"
 $   curl_src = "[.packages.vms.''arch_name']curlsrc.olb"
 $   curl_lib = "[.packages.vms.''arch_name']curllib.olb"
-$   rawstr = "rawstr"
+$   strcase = "strcase"
 $   nonblock = "nonblock"
 $   warnless = "warnless"
 $!
@@ -436,7 +436,7 @@
 $!
 $   if (arch_name .nes. "VAX") .and. (parse_style .eqs. "EXTENDED")
 $   then
-$       rawstr = """rawstr"""
+$       strcase = """strcase"""
 $       nonblock = """nonblock"""
 $       warnless = """warnless"""
 $   endif
@@ -446,7 +446,7 @@
 $       link'ldebug'/exe='curl_exe'/dsf='curl_dsf' -
            'curl_main','curl_src'/lib, -
            'curl_lib'/library/include=-
-           ('rawstr','nonblock','warnless'),-
+           ('strcase','nonblock','warnless'),-
            gnv_packages_vms:curlmsg.obj,-
            sys$input:/opt
 gnv$libcurl/share
diff --git a/packages/vms/readme b/packages/vms/readme
index 1b24580..5f116a5 100644
--- a/packages/vms/readme
+++ b/packages/vms/readme
@@ -83,13 +83,13 @@
                         libcurl shared image and to set up the needed
                         logical names.
 
-curlmsg.h               C header defining cURL status code macros.
+curlmsg.h               C header defining curl status code macros.
 
 curlmsg.msg             Error message source for curlmsg.h and curlmsg.sdl.
 
-curlmsg.sdl             SDL source defining cURL status code constants.
+curlmsg.sdl             SDL source defining curl status code constants.
 
-curlmsg_vms.h           Mapping of cURL status codes to VMS-form codes.
+curlmsg_vms.h           Mapping of curl status codes to VMS-form codes.
 
 generate_config_vms_h_curl.com
                         DCL procedure to generate the curl specific
@@ -115,9 +115,9 @@
 macro32_exactcase.patch The patch file needed to modify VAX Macro32 to be
                         case sensitive and case preserving.
 
-Makefile.am             cURL kit file list for this directory.
+Makefile.am             curl kit file list for this directory.
 
-Makefile.in             cURL kit makefile source for this directory.
+Makefile.in             curl kit makefile source for this directory.
 
 make_gnv_curl_install.sh
                         Script to do a make install using GNV after running
diff --git a/packages/vms/vms_eco_level.h b/packages/vms/vms_eco_level.h
index 4353407..354875b 100644
--- a/packages/vms/vms_eco_level.h
+++ b/packages/vms/vms_eco_level.h
@@ -19,7 +19,7 @@
  */
 
 /* This file should be incremented for each ECO that is kit */
-/* for a specific cURL x.y-z release. */
+/* for a specific curl x.y-z release. */
 /* When any part of x.y-z is incremented, the ECO should be set back to 0 */
 
 #ifndef _VMS_ECO_LEVEL_H
diff --git a/projects/README b/projects/README
index f631437..fee7304 100644
--- a/projects/README
+++ b/projects/README
@@ -4,7 +4,7 @@
    This document describes how to compile, build and install curl and libcurl
    from sources using an IDE based development tool such as Visual Studio.
 
-   Project files are currently available for Visual C++ v6.0 to v12.0. The
+   Project files are currently available for Visual C++ v6.0 to v14.0. The
    following directory structure has been used to cater for this:
 
    somedirectory\
@@ -160,17 +160,3 @@
    support the legacy handshakes and algorithms used by those versions. If
    you will be using curl in one of those earlier versions of Windows you
    should choose another SSL backend such as OpenSSL.
-
-TODO
-====
-
-   These project files are a recent addition to the curl source code and as such
-   are not 100% complete. This is a list of things that are still todo:
-
-   * Support zlib
-   * Use of static runtime libraries
-   * Add the Test Suite components
-   * Support for other development IDEs
-   * Add PATH environment variables for third-party DLLs
-
-   Any additional help would be appreciated ;-)
\ No newline at end of file
diff --git a/projects/generate.bat b/projects/generate.bat
index 8209a5d..fbe3a92 100644
--- a/projects/generate.bat
+++ b/projects/generate.bat
@@ -264,19 +264,18 @@
       for /f "delims=" %%r in ('dir /b ..\src\*.rc') do call :element %1 src "%%r" %3
     ) else if "!var!" == "CURL_SRC_X_C_FILES" (
       call :element %1 lib "strtoofft.c" %3
-      call :element %1 lib "rawstr.c" %3
       call :element %1 lib "nonblock.c" %3
       call :element %1 lib "warnless.c" %3
     ) else if "!var!" == "CURL_SRC_X_H_FILES" (
       call :element %1 lib "config-win32.h" %3
       call :element %1 lib "curl_setup.h" %3
       call :element %1 lib "strtoofft.h" %3
-      call :element %1 lib "rawstr.h" %3
       call :element %1 lib "nonblock.h" %3
       call :element %1 lib "warnless.h" %3
     ) else if "!var!" == "CURL_LIB_C_FILES" (
       for /f "delims=" %%c in ('dir /b ..\lib\*.c') do call :element %1 lib "%%c" %3
     ) else if "!var!" == "CURL_LIB_H_FILES" (
+      for /f "delims=" %%h in ('dir /b ..\include\curl\*.h') do call :element %1 include\curl "%%h" %3
       for /f "delims=" %%h in ('dir /b ..\lib\*.h') do call :element %1 lib "%%h" %3
     ) else if "!var!" == "CURL_LIB_RC_FILES" (
       for /f "delims=" %%r in ('dir /b ..\lib\*.rc') do call :element %1 lib "%%r" %3
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cfcefb3..9bbeb60 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -49,9 +49,9 @@
   ${CURL_FILES}
   )
 
-source_group("cURLX source files" FILES ${CURLX_CFILES})
-source_group("cURL source files" FILES ${CURL_CFILES})
-source_group("cURL header files" FILES ${CURL_HFILES})
+source_group("curlX source files" FILES ${CURLX_CFILES})
+source_group("curl source files" FILES ${CURL_CFILES})
+source_group("curl header files" FILES ${CURL_HFILES})
 
 include_directories(
   ${CURL_SOURCE_DIR}/lib        # To be able to reach "curl_setup_once.h"
@@ -61,7 +61,7 @@
   ${CURL_SOURCE_DIR}/src        # To be able to reach "tool_hugehelp.h"
   )
 
-#Build cURL executable
+#Build curl executable
 target_link_libraries( ${EXE_NAME} libcurl ${CURL_LIBS})
 
 ################################################################################
diff --git a/src/Makefile.Watcom b/src/Makefile.Watcom
index f1ddc29..25cd3bf 100644
--- a/src/Makefile.Watcom
+++ b/src/Makefile.Watcom
@@ -22,7 +22,7 @@
 #***************************************************************************
 
 #
-#  Watcom / OpenWatcom / Win32 makefile for cURL.
+#  Watcom / OpenWatcom / Win32 makefile for curl.
 #
 
 .ERASE
@@ -156,7 +156,7 @@
 DIRS = $(OBJ_DIR)
 
 all: tool_hugehelp.c $(DIRS) $(TARGETS) .SYMBOLIC
-	@echo Welcome to cURL
+	@echo Welcome to curl
 
 clean: .SYMBOLIC
 	-rm -f $(OBJS)
diff --git a/src/Makefile.inc b/src/Makefile.inc
index 1aa153c..2196ffa 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -11,14 +11,12 @@
 # the official API, but we re-use the code here to avoid duplication.
 CURLX_CFILES = \
 	../lib/strtoofft.c \
-	../lib/rawstr.c \
 	../lib/nonblock.c \
 	../lib/warnless.c
 
 CURLX_HFILES = \
 	../lib/curl_setup.h \
 	../lib/strtoofft.h \
-	../lib/rawstr.h \
 	../lib/nonblock.h \
 	../lib/warnless.h
 
diff --git a/src/Makefile.netware b/src/Makefile.netware
index 3e4f654..a927da5 100644
--- a/src/Makefile.netware
+++ b/src/Makefile.netware
@@ -102,7 +102,7 @@
 TARGET  = curl
 VERSION	= $(LIBCURL_VERSION)
 COPYR	= Copyright (C) $(LIBCURL_COPYRIGHT_STR)
-DESCR	= cURL $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
+DESCR	= curl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
 MTSAFE	= YES
 STACK	= 64000
 SCREEN	= $(TARGET) commandline utility
diff --git a/src/Makefile.vc6 b/src/Makefile.vc6
index ff82a4d..85828ce 100644
--- a/src/Makefile.vc6
+++ b/src/Makefile.vc6
@@ -142,7 +142,7 @@
 

 RELEASE_OBJS= \

 	nonblockr.obj \

-	rawstrr.obj \

+	strcaser.obj \

 	strtoofftr.obj \

 	warnless.obj \

 	slist_wc.obj \

@@ -188,7 +188,7 @@
 

 DEBUG_OBJS= \

 	nonblockd.obj \

-	rawstrd.obj \

+	strcased.obj \

 	strtoofftd.obj \

 	warnlessd.obj \

 	slist_wcd.obj \

@@ -363,8 +363,8 @@
 ## Release

 nonblockr.obj: ../lib/nonblock.c

 	$(CCR) $(CFLAGS) /Fo"$@" ../lib/nonblock.c

-rawstrr.obj: ../lib/rawstr.c

-	$(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c

+strcaser.obj: ../lib/strcase.c

+	$(CCR) $(CFLAGS) /Fo"$@" ../lib/strcase.c

 strtoofftr.obj: ../lib/strtoofft.c

 	$(CCR) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c

 warnless.obj: ../lib/warnless.c

@@ -453,8 +453,8 @@
 ## Debug

 nonblockd.obj: ../lib/nonblock.c

 	$(CCD) $(CFLAGS) /Fo"$@" ../lib/nonblock.c

-rawstrd.obj: ../lib/rawstr.c

-	$(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c

+strcased.obj: ../lib/strcase.c

+	$(CCD) $(CFLAGS) /Fo"$@" ../lib/strcase.c

 strtoofftd.obj: ../lib/strtoofft.c

 	$(CCD) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c

 warnlessd.obj: ../lib/warnless.c

diff --git a/src/curl.rc b/src/curl.rc
index 30ae444..3a2c3a0 100644
--- a/src/curl.rc
+++ b/src/curl.rc
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,12 +44,12 @@
   BEGIN
     BLOCK "040904b0"
     BEGIN
-      VALUE "CompanyName",      "cURL, https://curl.haxx.se/\0"
-      VALUE "FileDescription",  "The cURL executable\0"
+      VALUE "CompanyName",      "curl, https://curl.haxx.se/\0"
+      VALUE "FileDescription",  "The curl executable\0"
       VALUE "FileVersion",      CURL_VERSION "\0"
       VALUE "InternalName",     "curl\0"
       VALUE "OriginalFilename", "curl.exe\0"
-      VALUE "ProductName",      "The cURL executable\0"
+      VALUE "ProductName",      "The curl executable\0"
       VALUE "ProductVersion",   CURL_VERSION "\0"
       VALUE "LegalCopyright",   "© " CURL_COPYRIGHT "\0"
       VALUE "License",          "https://curl.haxx.se/docs/copyright.html\0"
diff --git a/src/macos/MACINSTALL.TXT b/src/macos/MACINSTALL.TXT
index 1839ef2..ce4d1dc 100644
--- a/src/macos/MACINSTALL.TXT
+++ b/src/macos/MACINSTALL.TXT
Binary files differ
diff --git a/src/makefile.amiga b/src/makefile.amiga
index 25449a6..9f3748b 100644
--- a/src/makefile.amiga
+++ b/src/makefile.amiga
@@ -1,5 +1,5 @@
 #
-# $VER: cURL Makefile for AmigaOS ...
+# $VER: curl Makefile for AmigaOS ...
 #
 
 # change the follow to where you have the AmiTCP SDK v4.3 includes:
@@ -19,12 +19,12 @@
 OBJS = $(CURL_CFILES:.c=.o) $(CURLX_CFILES:.c=.o)
 
 all:	tool_hugehelp.c $(OBJS)
-	$(CC) $(CFLAGS) -o cURL $(OBJS) $(LIBS) -Wl,-Map,cURL.map,--cref
+	$(CC) $(CFLAGS) -o curl $(OBJS) $(LIBS) -Wl,-Map,curl.map,--cref
 
 tool_hugehelp.c: $(README) $(MANPAGE)  mkhelp.pl
 	rm -f tool_hugehelp.c
 	/bin/nroff -man $(MANPAGE) | /bin/perl $(MKHELP) -c $(README) > tool_hugehelp.c
 
 install:
-	$(INSTALL) -c cURL /c/cURL
+	$(INSTALL) -c curl /c/curl
 
diff --git a/src/makefile.dj b/src/makefile.dj
index 6a6c8f9..c3bbc23 100644
--- a/src/makefile.dj
+++ b/src/makefile.dj
@@ -59,7 +59,7 @@
 OBJECTS += $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o))
 
 all: $(OBJ_DIR) $(PROGRAM)
-	@echo Welcome to cURL
+	@echo Welcome to curl
 
 $(PROGRAM): $(OBJECTS) ../lib/libcurl.a
 	$(CC) -o $@ $^ $(LDFLAGS) $(EX_LIBS)
diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c
index 97a5c92..221eae6 100644
--- a/src/tool_cb_dbg.c
+++ b/src/tool_cb_dbg.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,9 +73,9 @@
 
   if(!config->trace_stream) {
     /* open for append */
-    if(curlx_strequal("-", config->trace_dump))
+    if(!strcmp("-", config->trace_dump))
       config->trace_stream = stdout;
-    else if(curlx_strequal("%", config->trace_dump))
+    else if(!strcmp("%", config->trace_dump))
       /* Ok, this is somewhat hackish but we do it undocumented for now */
       config->trace_stream = config->errors;  /* aka stderr */
     else {
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index f7d8355..3891b07 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -47,7 +47,7 @@
   struct OutStruct *heads = hdrcbdata->heads;
   const char *str = ptr;
   const size_t cb = size * nmemb;
-  const char *end = (char*)ptr + cb;
+  const char *end = (char *)ptr + cb;
   char *url = NULL;
 
   /*
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
index 8b60a91..5d38fb3 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,6 +41,7 @@
                           CURLPROTO_SMBS);
   config->proto_redir_present = FALSE;
   config->proto_default = NULL;
+  config->tcp_nodelay = TRUE; /* enabled by default */
 }
 
 static void free_config_fields(struct OperationConfig *config)
@@ -67,6 +68,9 @@
   Curl_safefree(config->tls_username);
   Curl_safefree(config->tls_password);
   Curl_safefree(config->tls_authtype);
+  Curl_safefree(config->proxy_tls_username);
+  Curl_safefree(config->proxy_tls_password);
+  Curl_safefree(config->proxy_tls_authtype);
   Curl_safefree(config->proxyuserpwd);
   Curl_safefree(config->proxy);
 
@@ -98,15 +102,24 @@
   config->url_out = NULL;
 
   Curl_safefree(config->cipher_list);
+  Curl_safefree(config->proxy_cipher_list);
   Curl_safefree(config->cert);
+  Curl_safefree(config->proxy_cert);
   Curl_safefree(config->cert_type);
+  Curl_safefree(config->proxy_cert_type);
   Curl_safefree(config->cacert);
+  Curl_safefree(config->proxy_cacert);
   Curl_safefree(config->capath);
+  Curl_safefree(config->proxy_capath);
   Curl_safefree(config->crlfile);
   Curl_safefree(config->pinnedpubkey);
+  Curl_safefree(config->proxy_crlfile);
   Curl_safefree(config->key);
+  Curl_safefree(config->proxy_key);
   Curl_safefree(config->key_type);
+  Curl_safefree(config->proxy_key_type);
   Curl_safefree(config->key_passwd);
+  Curl_safefree(config->proxy_key_passwd);
   Curl_safefree(config->pubkey);
   Curl_safefree(config->hostpubmd5);
   Curl_safefree(config->engine);
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index aa98fce..6589d88 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -78,6 +78,9 @@
   char *tls_username;
   char *tls_password;
   char *tls_authtype;
+  char *proxy_tls_username;
+  char *proxy_tls_password;
+  char *proxy_tls_authtype;
   char *proxyuserpwd;
   char *proxy;
   int proxyver;             /* set to CURLPROXY_HTTP* define */
@@ -106,15 +109,24 @@
   struct getout *url_get;   /* point to the node to fill in URL */
   struct getout *url_out;   /* point to the node to fill in outfile */
   char *cipher_list;
+  char *proxy_cipher_list;
   char *cert;
+  char *proxy_cert;
   char *cert_type;
+  char *proxy_cert_type;
   char *cacert;
+  char *proxy_cacert;
   char *capath;
+  char *proxy_capath;
   char *crlfile;
+  char *proxy_crlfile;
   char *pinnedpubkey;
   char *key;
+  char *proxy_key;
   char *key_type;
+  char *proxy_key_type;
   char *key_passwd;
+  char *proxy_key_passwd;
   char *pubkey;
   char *hostpubmd5;
   char *engine;
@@ -127,6 +139,8 @@
   bool globoff;
   bool use_httpget;
   bool insecure_ok;         /* set TRUE to allow insecure SSL connects */
+  bool proxy_insecure_ok;   /* set TRUE to allow insecure SSL connects
+                               for proxy */
   bool verifystatus;
   bool create_dirs;
   bool ftp_create_dirs;
@@ -142,6 +156,7 @@
   struct curl_slist *postquote;
   struct curl_slist *prequote;
   long ssl_version;
+  long proxy_ssl_version;
   long ip_version;
   curl_TimeCond timecond;
   time_t condtime;
@@ -176,6 +191,7 @@
   bool tcp_nodelay;
   bool tcp_fastopen;
   long req_retry;           /* number of retries */
+  bool retry_connrefused;   /* set connection refused as a transient error */
   long retry_delay;         /* delay between retries (in seconds) */
   long retry_maxtime;       /* maximum time to keep retrying */
 
@@ -201,7 +217,10 @@
   bool xattr;               /* store metadata in extended attributes */
   long gssapi_delegation;
   bool ssl_allow_beast;     /* allow this SSL vulnerability */
+  bool proxy_ssl_allow_beast; /* allow this SSL vulnerability for proxy*/
+
   bool ssl_no_revoke;       /* disable SSL certificate revocation checks */
+  /*bool proxy_ssl_no_revoke; */
 
   bool use_metalink;        /* process given URLs as metalink XML file */
   metalinkfile *metalinkfile_list; /* point to the first node */
@@ -238,7 +257,7 @@
   bool tracetime;                 /* include timestamp? */
   int progressmode;               /* CURL_PROGRESS_BAR / CURL_PROGRESS_STATS */
   char *libcurl;                  /* Output libcurl code to this file name */
-
+  bool fail_early;                /* exit on first transfer error */
   struct OperationConfig *first;
   struct OperationConfig *current;
   struct OperationConfig *last;   /* Always last in the struct */
diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c
index b65db41..23bb2cb 100644
--- a/src/tool_dirhie.c
+++ b/src/tool_dirhie.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,14 @@
  *  should create all the dir* automagically
  */
 
+#ifdef WIN32
+/* systems that may use either or when specifying a path */
+#define PATH_DELIMITERS "\\/"
+#else
+#define PATH_DELIMITERS DIR_CHAR
+#endif
+
+
 CURLcode create_dir_hierarchy(const char *outfile, FILE *errors)
 {
   char *tempdir;
@@ -112,10 +120,12 @@
   }
   dirbuildup[0] = '\0';
 
-  tempdir = strtok(outdup, DIR_CHAR);
+  /* Allow strtok() here since this isn't used threaded */
+  /* !checksrc! disable BANNEDFUNC 2 */
+  tempdir = strtok(outdup, PATH_DELIMITERS);
 
   while(tempdir != NULL) {
-    tempdir2 = strtok(NULL, DIR_CHAR);
+    tempdir2 = strtok(NULL, PATH_DELIMITERS);
     /* since strtok returns a token for the last word even
        if not ending with DIR_CHAR, we need to prune it */
     if(tempdir2 != NULL) {
@@ -123,7 +133,8 @@
       if(dlen)
         snprintf(&dirbuildup[dlen], outlen - dlen, "%s%s", DIR_CHAR, tempdir);
       else {
-        if(0 != strncmp(outdup, DIR_CHAR, 1))
+        if(outdup == tempdir)
+          /* the output string doesn't start with a separator */
           strcpy(dirbuildup, tempdir);
         else
           snprintf(dirbuildup, outlen, "%s%s", DIR_CHAR, tempdir);
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index aed657a..eb3b29c 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -615,7 +615,7 @@
 char **__crt0_glob_function(char *arg)
 {
   (void)arg;
-  return (char**)0;
+  return (char **)0;
 }
 
 #endif /* MSDOS && (__DJGPP__ || __GO32__) */
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
index de30c52..88352fb 100644
--- a/src/tool_formparse.c
+++ b/src/tool_formparse.c
@@ -21,7 +21,7 @@
  ***************************************************************************/
 #include "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index d60e04c..3d254e1 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -21,7 +21,7 @@
  ***************************************************************************/
 #include "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -125,6 +125,7 @@
   {"$e", "proxy-digest",             FALSE},
   {"$f", "proxy-basic",              FALSE},
   {"$g", "retry",                    TRUE},
+  {"$V", "retry-connrefused",        FALSE},
   {"$h", "retry-delay",              TRUE},
   {"$i", "retry-max-time",           TRUE},
   {"$k", "proxy-negotiate",          FALSE},
@@ -190,6 +191,7 @@
   {"10",  "tlsv1.0",                 FALSE},
   {"11",  "tlsv1.1",                 FALSE},
   {"12",  "tlsv1.2",                 FALSE},
+  {"13",  "tlsv1.3",                 FALSE},
   {"2",  "sslv2",                    FALSE},
   {"3",  "sslv3",                    FALSE},
   {"4",  "ipv4",                     FALSE},
@@ -228,7 +230,26 @@
   {"Er", "false-start",              FALSE},
   {"Es", "ssl-no-revoke",            FALSE},
   {"Et", "tcp-fastopen",             FALSE},
+  {"Eu", "proxy-tlsuser",            TRUE},
+  {"Ev", "proxy-tlspassword",        TRUE},
+  {"Ew", "proxy-tlsauthtype",        TRUE},
+  {"Ex", "proxy-cert",               TRUE},
+  {"Ey", "proxy-cert-type",          TRUE},
+  {"Ez", "proxy-key",                TRUE},
+  {"E0", "proxy-key-type",           TRUE},
+  {"E1", "proxy-pass",               TRUE},
+  {"E2", "proxy-ciphers",            TRUE},
+  {"E3", "proxy-crlfile",            TRUE},
+  {"E4", "proxy-ssl-allow-beast",    FALSE},
+  {"E5", "login-options",            TRUE},
+  {"E6", "proxy-cacert",             TRUE},
+  {"E7", "proxy-capath",             TRUE},
+  {"E8", "proxy-insecure",           FALSE},
+  {"E9", "proxy-tlsv1",              FALSE},
+  {"EA", "proxy-sslv2",              FALSE},
+  {"EB", "proxy-sslv3",              FALSE},
   {"f",  "fail",                     FALSE},
+  {"fa", "fail-early",               FALSE},
   {"F",  "form",                     TRUE},
   {"Fs", "form-string",              TRUE},
   {"g",  "globoff",                  FALSE},
@@ -301,9 +322,12 @@
   if(param_length == 0)
     return;
 
-  /* next less trivial: cert_parameter contains no colon nor backslash; this
+  /* next less trivial: cert_parameter starts 'pkcs11:' and thus
+   * looks like a RFC7512 PKCS#11 URI which can be used as-is.
+   * Also if cert_parameter contains no colon nor backslash, this
    * means no passphrase was given and no characters escaped */
-  if(!strpbrk(cert_parameter, ":\\")) {
+  if(!strncmp(cert_parameter, "pkcs11:", 7) ||
+     !strpbrk(cert_parameter, ":\\")) {
     *certname = strdup(cert_parameter);
     return;
   }
@@ -378,6 +402,20 @@
   *certname_place = '\0';
 }
 
+static void
+GetFileAndPassword(char *nextarg, char **file, char **password)
+{
+  char *certname, *passphrase;
+  parse_cert_parameter(nextarg, &certname, &passphrase);
+  Curl_safefree(*file);
+  *file = certname;
+  if(passphrase) {
+    Curl_safefree(*password);
+    *password = passphrase;
+  }
+  cleanarg(nextarg);
+}
+
 ParameterError getparameter(char *flag,    /* f or -long-flag */
                             char *nextarg, /* NULL if unset */
                             bool *usedarg, /* set to TRUE if the arg
@@ -413,10 +451,10 @@
     }
 
     for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) {
-      if(curlx_strnequal(aliases[j].lname, word, fnam)) {
+      if(curl_strnequal(aliases[j].lname, word, fnam)) {
         longopt = TRUE;
         numhits++;
-        if(curlx_raw_equal(aliases[j].lname, word)) {
+        if(curl_strequal(aliases[j].lname, word)) {
           parse = aliases[j].letter;
           hit = j;
           numhits = 1; /* a single unique hit */
@@ -789,6 +827,9 @@
         if(err)
           return err;
         break;
+      case 'V': /* --retry-connrefused */
+        config->retry_connrefused = toggle;
+        break;
       case 'h': /* --retry-delay */
         err = str2unum(&config->retry_delay, nextarg);
         if(err)
@@ -1058,6 +1099,10 @@
         /* TLS version 1.2 */
         config->ssl_version = CURL_SSLVERSION_TLSv1_2;
         break;
+      case '3':
+        /* TLS version 1.3 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_3;
+        break;
       }
       break;
     case '2':
@@ -1106,7 +1151,7 @@
       break;
     case 'C':
       /* This makes us continue an ftp transfer at given position */
-      if(!curlx_strequal(nextarg, "-")) {
+      if(strcmp(nextarg, "-")) {
         err = str2offset(&config->resume_from, nextarg);
         if(err)
           return err;
@@ -1150,7 +1195,7 @@
         }
         if('@' == is_file) {
           /* a '@' letter, it means that a file name or - (stdin) follows */
-          if(curlx_strequal("-", p)) {
+          if(!strcmp("-", p)) {
             file = stdin;
             set_binmode(stdin);
           }
@@ -1215,7 +1260,7 @@
            or - (stdin) follows */
         nextarg++; /* pass the @ */
 
-        if(curlx_strequal("-", nextarg)) {
+        if(!strcmp("-", nextarg)) {
           file = stdin;
           if(subletter == 'b') /* forced data-binary */
             set_binmode(stdin);
@@ -1321,6 +1366,9 @@
     break;
     case 'E':
       switch(subletter) {
+      case '\0': /* certificate file */
+        GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
+        break;
       case 'a': /* CA info PEM file */
         /* CA info PEM file */
         GetStr(&config->cacert, nextarg);
@@ -1340,7 +1388,7 @@
         break;
       case 'f': /* crypto engine */
         GetStr(&config->engine, nextarg);
-        if(config->engine && curlx_raw_equal(config->engine, "list"))
+        if(config->engine && curl_strequal(config->engine, "list"))
           return PARAM_ENGINES_REQUESTED;
         break;
       case 'g': /* CA info PEM file */
@@ -1374,7 +1422,7 @@
       case 'm': /* TLS authentication type */
         if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
           GetStr(&config->tls_authtype, nextarg);
-          if(!strequal(config->tls_authtype, "SRP"))
+          if(!curl_strequal(config->tls_authtype, "SRP"))
             return PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */
         }
         else
@@ -1411,23 +1459,112 @@
         config->tcp_fastopen = TRUE;
         break;
 
-      default: /* certificate file */
-      {
-        char *certname, *passphrase;
-        parse_cert_parameter(nextarg, &certname, &passphrase);
-        Curl_safefree(config->cert);
-        config->cert = certname;
-        if(passphrase) {
-          Curl_safefree(config->key_passwd);
-          config->key_passwd = passphrase;
+      case 'u': /* TLS username for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->proxy_tls_username, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'v': /* TLS password for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->proxy_tls_password, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'w': /* TLS authentication type for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
+          GetStr(&config->proxy_tls_authtype, nextarg);
+          if(!curl_strequal(config->proxy_tls_authtype, "SRP"))
+            return PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */
         }
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'x': /* certificate file for proxy */
+        GetFileAndPassword(nextarg, &config->proxy_cert,
+                           &config->proxy_key_passwd);
+        break;
+
+      case 'y': /* cert file type for proxy */
+        GetStr(&config->proxy_cert_type, nextarg);
+        break;
+
+      case 'z': /* private key file for proxy */
+        GetStr(&config->proxy_key, nextarg);
+        break;
+
+      case '0': /* private key file type for proxy */
+        GetStr(&config->proxy_key_type, nextarg);
+        break;
+
+      case '1': /* private key passphrase for proxy */
+        GetStr(&config->proxy_key_passwd, nextarg);
         cleanarg(nextarg);
-      }
+        break;
+
+      case '2': /* ciphers for proxy */
+        GetStr(&config->proxy_cipher_list, nextarg);
+        break;
+
+      case '3': /* CRL info PEM file for proxy */
+        /* CRL file */
+        GetStr(&config->proxy_crlfile, nextarg);
+        break;
+
+      case '4': /* no empty SSL fragments for proxy */
+        if(curlinfo->features & CURL_VERSION_SSL)
+          config->proxy_ssl_allow_beast = toggle;
+        break;
+
+      case '5': /* --login-options */
+        GetStr(&config->login_options, nextarg);
+        break;
+
+      case '6': /* CA info PEM file for proxy */
+        /* CA info PEM file */
+        GetStr(&config->proxy_cacert, nextarg);
+        break;
+
+      case '7': /* CA info PEM file for proxy */
+        /* CA cert directory */
+        GetStr(&config->proxy_capath, nextarg);
+        break;
+
+      case '8': /* allow insecure SSL connects for proxy */
+        config->proxy_insecure_ok = toggle;
+        break;
+
+      case '9':
+        /* TLS version 1 for proxy */
+        config->proxy_ssl_version = CURL_SSLVERSION_TLSv1;
+        break;
+
+      case 'A':
+        /* SSL version 2 for proxy */
+        config->proxy_ssl_version = CURL_SSLVERSION_SSLv2;
+        break;
+
+      case 'B':
+        /* SSL version 3 for proxy */
+        config->proxy_ssl_version = CURL_SSLVERSION_SSLv3;
+        break;
+
+      default: /* unknown flag */
+        return PARAM_OPTION_UNKNOWN;
       }
       break;
     case 'f':
-      /* fail hard on errors  */
-      config->failonerror = toggle;
+      switch(subletter) {
+      case 'a': /* --fail-early */
+        global->fail_early = toggle;
+        break;
+      default:
+        /* fail hard on errors  */
+        config->failonerror = toggle;
+      }
       break;
     case 'F':
       /* "form data" simulation, this is a little advanced so lets do our best
@@ -1767,7 +1904,7 @@
         FILE *file;
         const char *fname;
         nextarg++; /* pass the @ */
-        if(curlx_strequal("-", nextarg)) {
+        if(!strcmp("-", nextarg)) {
           fname = "<stdin>";
           file = stdin;
         }
@@ -1877,7 +2014,7 @@
       bool passarg;
       char *flag = argv[i];
 
-      if(curlx_strequal("--", argv[i]))
+      if(!strcmp("--", argv[i]))
         /* This indicates the end of the flags and thus enables the
            following (URL) argument to start with -. */
         stillflags = FALSE;
@@ -1933,7 +2070,7 @@
      result != PARAM_ENGINES_REQUESTED) {
     const char *reason = param2text(result);
 
-    if(orig_opt && !curlx_strequal(":", orig_opt))
+    if(orig_opt && strcmp(":", orig_opt))
       helpf(config->errors, "option %s: %s\n", orig_opt, reason);
     else
       helpf(config->errors, "%s\n", reason);
diff --git a/src/tool_getpass.h b/src/tool_getpass.h
index 95dd779..f639596 100644
--- a/src/tool_getpass.h
+++ b/src/tool_getpass.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 @@
 /*
  * Returning NULL will abort the continued operation!
  */
-char* getpass_r(const char *prompt, char* buffer, size_t buflen);
+char *getpass_r(const char *prompt, char *buffer, size_t buflen);
 #endif
 
 #endif /* HEADER_CURL_TOOL_GETPASS_H */
diff --git a/src/tool_help.c b/src/tool_help.c
index fb428c9..39a5178 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -78,7 +78,7 @@
   "     --dns-interface  Interface to use for DNS requests",
   "     --dns-ipv4-addr  IPv4 address to use for DNS requests, dot notation",
   "     --dns-ipv6-addr  IPv6 address to use for DNS requests, dot notation",
-  " -D, --dump-header FILE  Write the headers to FILE",
+  " -D, --dump-header FILE  Write the received headers to FILE",
   "     --egd-file FILE  EGD socket path for random data (SSL)",
   "     --engine ENGINE  Crypto engine (use \"--engine list\" for list) (SSL)",
 #ifdef USE_ENVIRONMENT
@@ -86,6 +86,7 @@
 #endif
   "     --expect100-timeout SECONDS How long to wait for 100-continue (H)",
   " -f, --fail          Fail silently (no output at all) on HTTP errors (H)",
+  "     --fail-early    Fail on first transfer error, do not continue",
   "     --false-start   Enable TLS False Start.",
   " -F, --form CONTENT  Specify HTTP multipart POST data (H)",
   "     --form-string STRING  Specify HTTP multipart POST data (H)",
@@ -175,10 +176,36 @@
   "     --proxy-anyauth  Pick \"any\" proxy authentication method (H)",
   "     --proxy-basic   Use Basic authentication on the proxy (H)",
   "     --proxy-digest  Use Digest authentication on the proxy (H)",
+  "     --proxy-cacert FILE "
+  "CA certificate to verify peer against for proxy (SSL)",
+  "     --proxy-capath DIR "
+  "CA directory to verify peer against for proxy (SSL)",
+  "     --proxy-cert CERT[:PASSWD] "
+  "Client certificate file and password for proxy (SSL)",
+  "     --proxy-cert-type TYPE "
+  "Certificate file type (DER/PEM/ENG) for proxy (SSL)",
+  "     --proxy-ciphers LIST SSL ciphers to use for proxy (SSL)",
+  "     --proxy-crlfile FILE "
+  "Get a CRL list in PEM format from the given file for proxy",
+  "     --proxy-insecure "
+  "Allow connections to SSL sites without certs for proxy (H)",
+  "     --proxy-key KEY Private key file name for proxy (SSL)",
+  "     --proxy-key-type TYPE "
+  "Private key file type for proxy (DER/PEM/ENG) (SSL)",
   "     --proxy-negotiate  "
   "Use HTTP Negotiate (SPNEGO) authentication on the proxy (H)",
   "     --proxy-ntlm    Use NTLM authentication on the proxy (H)",
   "     --proxy-header LINE Pass custom header LINE to proxy (H)",
+  "     --proxy-pass PASS Pass phrase for the private key for proxy (SSL)",
+  "     --proxy-ssl-allow-beast "
+  "Allow security flaw to improve interop for proxy (SSL)",
+  "     --proxy-sslv2   Use SSLv2 for proxy (SSL)",
+  "     --proxy-sslv3   Use SSLv3 for proxy (SSL)",
+  "     --proxy-tlsv1   Use TLSv1 for proxy (SSL)",
+  "     --proxy-tlsuser USER TLS username for proxy",
+  "     --proxy-tlspassword STRING TLS password for proxy",
+  "     --proxy-tlsauthtype STRING "
+  "TLS authentication type for proxy (default SRP)",
   "     --proxy-service-name NAME  SPNEGO proxy service name",
   "     --service-name NAME  SPNEGO service name",
   " -U, --proxy-user USER[:PASSWORD]  Proxy user and password",
@@ -198,6 +225,7 @@
   "     --resolve HOST:PORT:ADDRESS  Force resolve of HOST:PORT to ADDRESS",
   "     --retry NUM   "
   "Retry request NUM times if transient problems occur",
+  "     --retry-connrefused  Retry on connection refused (use with --retry)",
   "     --retry-delay SECONDS  Wait SECONDS between retries",
   "     --retry-max-time SECONDS  Retry only within this period",
   "     --sasl-ir       Enable initial response in SASL authentication",
@@ -232,6 +260,7 @@
   "     --tlsv1.0       Use TLSv1.0 (SSL)",
   "     --tlsv1.1       Use TLSv1.1 (SSL)",
   "     --tlsv1.2       Use TLSv1.2 (SSL)",
+  "     --tlsv1.3       Use TLSv1.3 (SSL)",
   "     --trace FILE    Write a debug trace to FILE",
   "     --trace-ascii FILE  Like --trace, but without hex output",
   "     --trace-time    Add time stamps to trace/verbose output",
diff --git a/src/tool_helpers.c b/src/tool_helpers.c
index fef1459..b5a619b 100644
--- a/src/tool_helpers.c
+++ b/src/tool_helpers.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -35,7 +35,7 @@
 #include "memdebug.h" /* keep this as LAST include */
 
 /*
-** Helper functions that are used from more tha one source file.
+** Helper functions that are used from more than one source file.
 */
 
 const char *param2text(int res)
diff --git a/src/tool_libinfo.c b/src/tool_libinfo.c
index 5db8548..d2bf7fb 100644
--- a/src/tool_libinfo.c
+++ b/src/tool_libinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -89,7 +89,7 @@
   if(curlinfo->protocols) {
     for(proto = curlinfo->protocols; *proto; proto++) {
       for(p = possibly_built_in; p->proto_name; p++) {
-        if(curlx_raw_equal(*proto, p->proto_name)) {
+        if(curl_strequal(*proto, p->proto_name)) {
           built_in_protos |= p->proto_pattern;
           break;
         }
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 9a6465e..f417356 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,6 +24,7 @@
 #ifdef USE_METALINK
 
 #include <sys/stat.h>
+#include <stdlib.h>
 
 #ifdef HAVE_FCNTL_H
 #  include <fcntl.h>
@@ -92,8 +93,6 @@
 #  error "Can't compile METALINK support without a crypto library."
 #endif
 
-#include "rawstr.h"
-
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
 #include "curlx.h"
@@ -563,18 +562,13 @@
 
 static unsigned char hex_to_uint(const char *s)
 {
-  int v[2];
-  int i;
-  for(i = 0; i < 2; ++i) {
-    v[i] = Curl_raw_toupper(s[i]);
-    if('0' <= v[i] && v[i] <= '9') {
-      v[i] -= '0';
-    }
-    else if('A' <= v[i] && v[i] <= 'Z') {
-      v[i] -= 'A'-10;
-    }
-  }
-  return (unsigned char)((v[0] << 4) | v[1]);
+  char buf[3];
+  unsigned long val;
+  buf[0] = s[0];
+  buf[1] = s[1];
+  buf[2] = 0;
+  val = strtoul(buf, NULL, 16);
+  return (unsigned char)(val&0xff);
 }
 
 /*
@@ -747,7 +741,7 @@
         ++digest_alias) {
       metalink_checksum_t **p;
       for(p = fileinfo->checksums; *p; ++p) {
-        if(Curl_raw_equal(digest_alias->alias_name, (*p)->type) &&
+        if(curl_strequal(digest_alias->alias_name, (*p)->type) &&
            check_hex_digest((*p)->hash, digest_alias->digest_def)) {
           f->checksum =
             new_metalink_checksum_from_hex_digest(digest_alias->digest_def,
@@ -777,10 +771,10 @@
          metainfo file URL may be appeared in fileinfo->metaurls.
       */
       if((*p)->type == NULL ||
-         Curl_raw_equal((*p)->type, "http") ||
-         Curl_raw_equal((*p)->type, "https") ||
-         Curl_raw_equal((*p)->type, "ftp") ||
-         Curl_raw_equal((*p)->type, "ftps")) {
+         curl_strequal((*p)->type, "http") ||
+         curl_strequal((*p)->type, "https") ||
+         curl_strequal((*p)->type, "ftp") ||
+         curl_strequal((*p)->type, "ftps")) {
         res = new_metalink_resource((*p)->url);
         tail->next = res;
         tail = res;
@@ -906,7 +900,7 @@
   if(!*ptr) {
     return 0;
   }
-  return Curl_raw_nequal(ptr, media_type, media_type_len) &&
+  return curl_strnequal(ptr, media_type, media_type_len) &&
     (*(ptr+media_type_len) == '\0' || *(ptr+media_type_len) == ' ' ||
      *(ptr+media_type_len) == '\t' || *(ptr+media_type_len) == ';');
 }
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 2b53c9a..94d87fe 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -43,7 +43,7 @@
 #  include <fabdef.h>
 #endif
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -143,8 +143,8 @@
  * and CD/DVD images should be either a STREAM_LF format or a fixed format.
  *
  */
-static curl_off_t vms_realfilesize(const char * name,
-                                   const struct_stat * stat_buf)
+static curl_off_t vms_realfilesize(const char *name,
+                                   const struct_stat *stat_buf)
 {
   char buffer[8192];
   curl_off_t count;
@@ -174,8 +174,8 @@
  *  if not to call a routine to get the correct size.
  *
  */
-static curl_off_t VmsSpecialSize(const char * name,
-                                 const struct_stat * stat_buf)
+static curl_off_t VmsSpecialSize(const char *name,
+                                 const struct_stat *stat_buf)
 {
   switch(stat_buf->st_fab_rfm) {
   case FAB$C_VAR:
@@ -321,7 +321,7 @@
   /* Single header file for all URLs */
   if(config->headerfile) {
     /* open file for output: */
-    if(!curlx_strequal(config->headerfile, "-")) {
+    if(strcmp(config->headerfile, "-")) {
       FILE *newfile = fopen(config->headerfile, "wb");
       if(!newfile) {
         warnf(config->global, "Failed to open %s\n", config->headerfile);
@@ -464,7 +464,7 @@
         urlnum = 1; /* without globbing, this is a single URL */
 
       /* if multiple files extracted to stdout, insert separators! */
-      separator= ((!outfiles || curlx_strequal(outfiles, "-")) && urlnum > 1);
+      separator= ((!outfiles || !strcmp(outfiles, "-")) && urlnum > 1);
 
       /* Here's looping around each globbed URL */
       for(li = 0 ; li < urlnum; li++) {
@@ -534,7 +534,7 @@
         }
 
         if(((urlnode->flags&GETOUT_USEREMOTE) ||
-            (outfile && !curlx_strequal("-", outfile))) &&
+            (outfile && strcmp("-", outfile))) &&
            (metalink || !config->use_metalink)) {
 
           /*
@@ -715,7 +715,7 @@
           DEBUGASSERT(infd == STDIN_FILENO);
 
           set_binmode(stdin);
-          if(curlx_strequal(uploadfile, ".")) {
+          if(!strcmp(uploadfile, ".")) {
             if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
               warnf(config->global,
                     "fcntl failed on fd=%d: %s\n", infd, strerror(errno));
@@ -792,14 +792,15 @@
           set_binmode(stdout);
         }
 
-        if(config->tcp_nodelay)
-          my_setopt(curl, CURLOPT_TCP_NODELAY, 1L);
+        if(!config->tcp_nodelay)
+          my_setopt(curl, CURLOPT_TCP_NODELAY, 0L);
 
         if(config->tcp_fastopen)
           my_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
 
         /* where to store */
         my_setopt(curl, CURLOPT_WRITEDATA, &outs);
+        my_setopt(curl, CURLOPT_INTERLEAVEDATA, &outs);
         if(metalink || !config->use_metalink)
           /* what call to write */
           my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
@@ -868,8 +869,9 @@
 
           /* new in libcurl 7.10 */
           if(config->socksproxy) {
-            my_setopt_str(curl, CURLOPT_PROXY, config->socksproxy);
-            my_setopt_enum(curl, CURLOPT_PROXYTYPE, (long)config->socksver);
+            my_setopt_str(curl, CURLOPT_SOCKS_PROXY, config->socksproxy);
+            my_setopt_enum(curl, CURLOPT_SOCKS_PROXYTYPE,
+                           (long)config->socksver);
           }
 
           /* new in libcurl 7.10.6 */
@@ -999,6 +1001,7 @@
           my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0));
 
         my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd);
+        my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd);
 
         if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
 
@@ -1016,6 +1019,8 @@
 
         if(config->cacert)
           my_setopt_str(curl, CURLOPT_CAINFO, config->cacert);
+        if(config->proxy_cacert)
+          my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert);
         if(config->capath) {
           result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath);
           if(result == CURLE_NOT_BUILT_IN) {
@@ -1026,17 +1031,32 @@
           else if(result)
             goto show_error;
         }
+        if(config->proxy_capath)
+          my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->proxy_capath);
+        else if(config->capath) /* CURLOPT_PROXY_CAPATH default is capath */
+          my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->capath);
+
         if(config->crlfile)
           my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile);
+        if(config->proxy_crlfile)
+          my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile);
+        else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */
+          my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile);
 
         if(config->pinnedpubkey)
           my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
 
         if(curlinfo->features & CURL_VERSION_SSL) {
           my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
           my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLCERTTYPE,
+                        config->proxy_cert_type);
           my_setopt_str(curl, CURLOPT_SSLKEY, config->key);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLKEY, config->proxy_key);
           my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE,
+                        config->proxy_key_type);
 
           if(config->insecure_ok) {
             my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
@@ -1047,6 +1067,13 @@
             /* libcurl default is strict verifyhost -> 2L   */
             /* my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); */
           }
+          if(config->proxy_insecure_ok) {
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
+          }
+          else {
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+          }
 
           if(config->verifystatus)
             my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L);
@@ -1055,6 +1082,8 @@
             my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
 
           my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version);
+          my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
+                         config->proxy_ssl_version);
         }
         if(config->path_as_is)
           my_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
@@ -1156,6 +1185,10 @@
         if(config->cipher_list)
           my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
 
+        if(config->proxy_cipher_list)
+          my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST,
+                        config->proxy_cipher_list);
+
         /* new in libcurl 7.9.2: */
         if(config->disable_epsv)
           /* disable it */
@@ -1177,7 +1210,6 @@
           result = res_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
           if(result)
             goto show_error;
-          my_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
         }
 
         /* new in curl 7.10.7, extended in 7.19.4. Modified to use
@@ -1325,6 +1357,15 @@
           if(config->tls_authtype)
             my_setopt_str(curl, CURLOPT_TLSAUTH_TYPE,
                           config->tls_authtype);
+          if(config->proxy_tls_username)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_USERNAME,
+                          config->proxy_tls_username);
+          if(config->proxy_tls_password)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD,
+                          config->proxy_tls_password);
+          if(config->proxy_tls_authtype)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_TYPE,
+                          config->proxy_tls_authtype);
         }
 
         /* new in 7.22.0 */
@@ -1340,6 +1381,10 @@
             my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask);
         }
 
+        if(config->proxy_ssl_allow_beast)
+          my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS,
+                    (long)CURLSSLOPT_ALLOW_BEAST);
+
         if(config->mail_auth)
           my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth);
 
@@ -1441,6 +1486,7 @@
             enum {
               RETRY_NO,
               RETRY_TIMEOUT,
+              RETRY_CONNREFUSED,
               RETRY_HTTP,
               RETRY_FTP,
               RETRY_LAST /* not used */
@@ -1452,6 +1498,13 @@
                (CURLE_FTP_ACCEPT_TIMEOUT == result))
               /* retry timeout always */
               retry = RETRY_TIMEOUT;
+            else if(config->retry_connrefused &&
+                    (CURLE_COULDNT_CONNECT == result)) {
+              long oserrno;
+              curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno);
+              if(ECONNREFUSED == oserrno)
+                retry = RETRY_CONNREFUSED;
+            }
             else if((CURLE_OK == result) ||
                     (config->failonerror &&
                      (CURLE_HTTP_RETURNED_ERROR == result))) {
@@ -1499,7 +1552,11 @@
 
             if(retry) {
               static const char * const m[]={
-                NULL, "timeout", "HTTP error", "FTP error"
+                NULL,
+                "timeout",
+                "connection refused",
+                "HTTP error",
+                "FTP error"
               };
 
               warnf(config->global, "Transient problem: %s "
@@ -1559,7 +1616,7 @@
               char *effective_url = NULL;
               curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
               if(effective_url &&
-                 curlx_strnequal(effective_url, "http", 4)) {
+                 curl_strnequal(effective_url, "http", 4)) {
                 /* This was HTTP(S) */
                 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
                 if(response != 200 && response != 206) {
@@ -1793,9 +1850,9 @@
     urlnode->flags = 0;
 
     /*
-    ** Bail out upon critical errors
+    ** Bail out upon critical errors or --fail-early
     */
-    if(is_fatal_error(result))
+    if(is_fatal_error(result) || (result && global->fail_early))
       goto quit_curl;
 
   } /* for-loop through all URLs */
@@ -1842,8 +1899,8 @@
 
   /* Parse .curlrc if necessary */
   if((argc == 1) ||
-     (!curlx_strequal(argv[1], "-q") &&
-      !curlx_strequal(argv[1], "--disable"))) {
+     (!curl_strequal(argv[1], "-q") &&
+      !curl_strequal(argv[1], "--disable"))) {
     parseconfig(NULL, config); /* ignore possible failure */
 
     /* If we had no arguments then make sure a url was specified in .curlrc */
diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c
index b43dc95..21b5ffe 100644
--- a/src/tool_operhlp.c
+++ b/src/tool_operhlp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, 2016, 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 "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -63,8 +63,8 @@
 
 bool stdin_upload(const char *uploadfile)
 {
-  return (curlx_strequal(uploadfile, "-") ||
-          curlx_strequal(uploadfile, ".")) ? TRUE : FALSE;
+  return (!strcmp(uploadfile, "-") ||
+          !strcmp(uploadfile, ".")) ? TRUE : FALSE;
 }
 
 /*
diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c
index f2e68da..7de4905 100644
--- a/src/tool_paramhlp.c
+++ b/src/tool_paramhlp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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 "tool_setup.h"
 
-#include "rawstr.h"
+#include "strcase.h"
 
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
@@ -284,6 +284,8 @@
   if(!buffer)
     return 1;
 
+  /* Allow strtok() here since this isn't used threaded */
+  /* !checksrc! disable BANNEDFUNC 2 */
   for(token = strtok(buffer, sep);
       token;
       token = strtok(NULL, sep)) {
@@ -310,7 +312,7 @@
     }
 
     for(pp=protos; pp->name; pp++) {
-      if(curlx_raw_equal(token, pp->name)) {
+      if(curl_strequal(token, pp->name)) {
         switch (action) {
         case deny:
           *val &= ~(pp->bit);
@@ -353,7 +355,7 @@
   if(!str)
     return PARAM_REQUIRES_PARAMETER;
   for(pp = curlinfo->protocols; *pp; pp++) {
-    if(curlx_raw_equal(*pp, str))
+    if(curl_strequal(*pp, str))
       return PARAM_OK;
   }
   return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
@@ -464,11 +466,11 @@
 
 int ftpfilemethod(struct OperationConfig *config, const char *str)
 {
-  if(curlx_raw_equal("singlecwd", str))
+  if(curl_strequal("singlecwd", str))
     return CURLFTPMETHOD_SINGLECWD;
-  if(curlx_raw_equal("nocwd", str))
+  if(curl_strequal("nocwd", str))
     return CURLFTPMETHOD_NOCWD;
-  if(curlx_raw_equal("multicwd", str))
+  if(curl_strequal("multicwd", str))
     return CURLFTPMETHOD_MULTICWD;
 
   warnf(config->global, "unrecognized ftp file method '%s', using default\n",
@@ -479,9 +481,9 @@
 
 int ftpcccmethod(struct OperationConfig *config, const char *str)
 {
-  if(curlx_raw_equal("passive", str))
+  if(curl_strequal("passive", str))
     return CURLFTPSSL_CCC_PASSIVE;
-  if(curlx_raw_equal("active", str))
+  if(curl_strequal("active", str))
     return CURLFTPSSL_CCC_ACTIVE;
 
   warnf(config->global, "unrecognized ftp CCC method '%s', using default\n",
@@ -492,11 +494,11 @@
 
 long delegation(struct OperationConfig *config, char *str)
 {
-  if(curlx_raw_equal("none", str))
+  if(curl_strequal("none", str))
     return CURLGSSAPI_DELEGATION_NONE;
-  if(curlx_raw_equal("policy", str))
+  if(curl_strequal("policy", str))
     return CURLGSSAPI_DELEGATION_POLICY_FLAG;
-  if(curlx_raw_equal("always", str))
+  if(curl_strequal("always", str))
     return CURLGSSAPI_DELEGATION_FLAG;
 
   warnf(config->global, "unrecognized delegation method '%s', using none\n",
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index 690ce14..ad3d307 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -45,6 +45,15 @@
 const NameValue setopt_nv_CURLPROXY[] = {
   NV(CURLPROXY_HTTP),
   NV(CURLPROXY_HTTP_1_0),
+  NV(CURLPROXY_HTTPS),
+  NV(CURLPROXY_SOCKS4),
+  NV(CURLPROXY_SOCKS5),
+  NV(CURLPROXY_SOCKS4A),
+  NV(CURLPROXY_SOCKS5_HOSTNAME),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_SOCKS_PROXY[] = {
   NV(CURLPROXY_SOCKS4),
   NV(CURLPROXY_SOCKS5),
   NV(CURLPROXY_SOCKS4A),
@@ -83,6 +92,7 @@
   NV(CURL_SSLVERSION_TLSv1_0),
   NV(CURL_SSLVERSION_TLSv1_1),
   NV(CURL_SSLVERSION_TLSv1_2),
+  NV(CURL_SSLVERSION_TLSv1_3),
   NVEND,
 };
 
@@ -157,6 +167,9 @@
   NV1(CURLOPT_SSL_VERIFYHOST, 1),
   NV1(CURLOPT_SSL_ENABLE_NPN, 1),
   NV1(CURLOPT_SSL_ENABLE_ALPN, 1),
+  NV1(CURLOPT_TCP_NODELAY, 1),
+  NV1(CURLOPT_PROXY_SSL_VERIFYPEER, 1),
+  NV1(CURLOPT_PROXY_SSL_VERIFYHOST, 1),
   NVEND
 };
 
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index 7cd3875..fecf24f 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -47,6 +47,7 @@
 } NameValueUnsigned;
 
 extern const NameValue setopt_nv_CURLPROXY[];
+extern const NameValue setopt_nv_CURL_SOCKS_PROXY[];
 extern const NameValue setopt_nv_CURL_HTTP_VERSION[];
 extern const NameValue setopt_nv_CURL_SSLVERSION[];
 extern const NameValue setopt_nv_CURL_TIMECOND[];
@@ -61,6 +62,7 @@
 #define setopt_nv_CURLOPT_HTTP_VERSION setopt_nv_CURL_HTTP_VERSION
 #define setopt_nv_CURLOPT_HTTPAUTH setopt_nv_CURLAUTH
 #define setopt_nv_CURLOPT_SSLVERSION setopt_nv_CURL_SSLVERSION
+#define setopt_nv_CURLOPT_PROXY_SSLVERSION setopt_nv_CURL_SSLVERSION
 #define setopt_nv_CURLOPT_TIMECONDITION setopt_nv_CURL_TIMECOND
 #define setopt_nv_CURLOPT_FTP_SSL_CCC setopt_nv_CURLFTPSSL_CCC
 #define setopt_nv_CURLOPT_USE_SSL setopt_nv_CURLUSESSL
@@ -69,6 +71,7 @@
 #define setopt_nv_CURLOPT_PROTOCOLS setopt_nv_CURLPROTO
 #define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO
 #define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY
+#define setopt_nv_CURLOPT_SOCKS_PROXYTYPE setopt_nv_CURL_SOCKS_PROXY
 #define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH
 
 /* Intercept setopt calls for --libcurl */
diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c
index a357b8b..e68e30e 100644
--- a/src/tool_urlglob.c
+++ b/src/tool_urlglob.c
@@ -44,7 +44,7 @@
   pat->content.Set.ptr_s = 0;
   pat->globindex = -1;
 
-  pat->content.Set.elements = malloc(sizeof(char*));
+  pat->content.Set.elements = malloc(sizeof(char *));
 
   if(!pat->content.Set.elements)
     return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
@@ -118,14 +118,14 @@
       *buf = '\0';
       if(pat->content.Set.elements) {
         char **new_arr = realloc(pat->content.Set.elements,
-                                 (pat->content.Set.size + 1) * sizeof(char*));
+                                 (pat->content.Set.size + 1) * sizeof(char *));
         if(!new_arr)
           return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
 
         pat->content.Set.elements = new_arr;
       }
       else
-        pat->content.Set.elements = malloc(sizeof(char*));
+        pat->content.Set.elements = malloc(sizeof(char *));
 
       if(!pat->content.Set.elements)
         return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
@@ -188,32 +188,39 @@
     /* character range detected */
     char min_c;
     char max_c;
+    char end_c;
     int step=1;
 
     pat->type = UPTCharRange;
 
-    rc = sscanf(pattern, "%c-%c", &min_c, &max_c);
+    rc = sscanf(pattern, "%c-%c%c", &min_c, &max_c, &end_c);
 
-    if((rc == 2) && (pattern[3] == ':')) {
-      char *endp;
-      unsigned long lstep;
-      errno = 0;
-      lstep = strtoul(&pattern[4], &endp, 10);
-      if(errno || (*endp != ']'))
-        step = -1;
-      else {
-        pattern = endp+1;
-        step = (int)lstep;
-        if(step > (max_c - min_c))
+    if(rc == 3) {
+      if(end_c == ':') {
+        char *endp;
+        unsigned long lstep;
+        errno = 0;
+        lstep = strtoul(&pattern[4], &endp, 10);
+        if(errno || &pattern[4] == endp || *endp != ']')
           step = -1;
+        else {
+          pattern = endp+1;
+          step = (int)lstep;
+          if(step > (max_c - min_c))
+            step = -1;
+        }
       }
+      else if(end_c != ']')
+        /* then this is wrong */
+        rc = 0;
+      else
+        /* end_c == ']' */
+        pattern += 4;
     }
-    else
-      pattern += 4;
 
     *posp += (pattern - *patternp);
 
-    if((rc != 2) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
+    if((rc != 3) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
        (step <= 0) )
       /* the pattern is not well-formed */
       return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);
@@ -257,6 +264,12 @@
         endp = NULL;
       else {
         pattern = endp+1;
+        while(*pattern && ISBLANK(*pattern))
+          pattern++;
+        if(!ISDIGIT(*pattern)) {
+          endp = NULL;
+          goto fail;
+        }
         errno = 0;
         max_n = strtoul(pattern, &endp, 10);
         if(errno || (*endp == ':')) {
@@ -277,6 +290,7 @@
       }
     }
 
+    fail:
     *posp += (pattern - *patternp);
 
     if(!endp || (min_n > max_n) || (step_n > (max_n - min_n)) || !step_n)
@@ -407,7 +421,7 @@
   return res;
 }
 
-CURLcode glob_url(URLGlob** glob, char* url, unsigned long *urlnum,
+CURLcode glob_url(URLGlob **glob, char *url, unsigned long *urlnum,
                   FILE *error)
 {
   /*
@@ -424,6 +438,7 @@
   glob_buffer = malloc(strlen(url) + 1);
   if(!glob_buffer)
     return CURLE_OUT_OF_MEMORY;
+  glob_buffer[0]=0;
 
   glob_expand = calloc(1, sizeof(URLGlob));
   if(!glob_expand) {
@@ -541,20 +556,25 @@
     switch(pat->type) {
     case UPTSet:
       if(pat->content.Set.elements) {
-        len = strlen(pat->content.Set.elements[pat->content.Set.ptr_s]);
         snprintf(buf, buflen, "%s",
                  pat->content.Set.elements[pat->content.Set.ptr_s]);
+        len = strlen(buf);
         buf += len;
         buflen -= len;
       }
       break;
     case UPTCharRange:
-      *buf++ = pat->content.CharRange.ptr_c;
+      if(buflen) {
+        *buf++ = pat->content.CharRange.ptr_c;
+        *buf = '\0';
+        buflen--;
+      }
       break;
     case UPTNumRange:
-      len = snprintf(buf, buflen, "%0*ld",
-                     pat->content.NumRange.padlength,
-                     pat->content.NumRange.ptr_n);
+      snprintf(buf, buflen, "%0*ld",
+               pat->content.NumRange.padlength,
+               pat->content.NumRange.ptr_n);
+      len = strlen(buf);
       buf += len;
       buflen -= len;
       break;
@@ -563,7 +583,6 @@
       return CURLE_FAILED_INIT;
     }
   }
-  *buf = '\0';
 
   *globbed = strdup(glob->glob_buffer);
   if(!*globbed)
diff --git a/src/tool_urlglob.h b/src/tool_urlglob.h
index c3be948..82d9d46 100644
--- a/src/tool_urlglob.h
+++ b/src/tool_urlglob.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -68,9 +68,9 @@
   size_t pos;        /* column position of error or 0 */
 } URLGlob;
 
-CURLcode glob_url(URLGlob**, char*, unsigned long *, FILE *);
+CURLcode glob_url(URLGlob**, char *, unsigned long *, FILE *);
 CURLcode glob_next_url(char **, URLGlob *);
-CURLcode glob_match_url(char **, char*, URLGlob *);
+CURLcode glob_match_url(char **, char *, URLGlob *);
 void glob_cleanup(URLGlob* glob);
 
 #endif /* HEADER_CURL_TOOL_URLGLOB_H */
diff --git a/src/tool_writeenv.c b/src/tool_writeenv.c
index c1bfcbe..198847e 100644
--- a/src/tool_writeenv.c
+++ b/src/tool_writeenv.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,7 +33,7 @@
 
 static const struct
 {
-  const char * name;
+  const char *name;
   CURLINFO id;
   enum {
     writeenv_NONE,
@@ -59,7 +59,7 @@
   {NULL, 0, writeenv_NONE}
  };
 
-static void internalSetEnv(const char * name, char * value)
+static void internalSetEnv(const char *name, char *value)
 {
   /* Add your OS-specific code here. */
 #ifdef __riscos__
diff --git a/src/tool_writeout.c b/src/tool_writeout.c
index 6e94afe..3737df8 100644
--- a/src/tool_writeout.c
+++ b/src/tool_writeout.c
@@ -52,12 +52,14 @@
   VAR_FTP_ENTRY_PATH,
   VAR_REDIRECT_URL,
   VAR_SSL_VERIFY_RESULT,
+  VAR_PROXY_SSL_VERIFY_RESULT,
   VAR_EFFECTIVE_FILENAME,
   VAR_PRIMARY_IP,
   VAR_PRIMARY_PORT,
   VAR_LOCAL_IP,
   VAR_LOCAL_PORT,
   VAR_HTTP_VERSION,
+  VAR_SCHEME,
   VAR_NUM_OF_VARS /* must be the last */
 } replaceid;
 
@@ -91,12 +93,14 @@
   {"ftp_entry_path", VAR_FTP_ENTRY_PATH},
   {"redirect_url", VAR_REDIRECT_URL},
   {"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
+  {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT},
   {"filename_effective", VAR_EFFECTIVE_FILENAME},
   {"remote_ip", VAR_PRIMARY_IP},
   {"remote_port", VAR_PRIMARY_PORT},
   {"local_ip", VAR_LOCAL_IP},
   {"local_port", VAR_LOCAL_PORT},
   {"http_version", VAR_HTTP_VERSION},
+  {"scheme", VAR_SCHEME},
   {NULL, VAR_NONE}
 };
 
@@ -170,41 +174,41 @@
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
                                      &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_TOTAL_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_NAMELOOKUP_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
                                      &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_CONNECT_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_APPCONNECT_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
                                      &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_PRETRANSFER_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
                                      &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_STARTTRANSFER_TIME:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
                                      &doubleinfo))
-                  fprintf(stream, "%.3f", doubleinfo);
+                  fprintf(stream, "%.6f", doubleinfo);
                 break;
               case VAR_SIZE_UPLOAD:
                 if(CURLE_OK ==
@@ -252,6 +256,12 @@
                                      &longinfo))
                   fprintf(stream, "%ld", longinfo);
                 break;
+              case VAR_PROXY_SSL_VERIFY_RESULT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT,
+                                     &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
               case VAR_EFFECTIVE_FILENAME:
                 if(outs->filename)
                   fprintf(stream, "%s", outs->filename);
@@ -300,6 +310,12 @@
                   fprintf(stream, version);
                 }
                 break;
+              case VAR_SCHEME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SCHEME,
+                                     &stringp))
+                  fprintf(stream, "%s", stringp);
+                break;
               default:
                 break;
               }
diff --git a/tests/README b/tests/README
index ae8ff25..8f52688 100644
--- a/tests/README
+++ b/tests/README
@@ -4,7 +4,7 @@
                             | (__| |_| |  _ <| |___
                              \___|\___/|_| \_\_____|
 
-The cURL Test Suite
+The curl Test Suite
 
  1. Running
   1.1 Requires to run
@@ -43,6 +43,7 @@
   diff (when a test fails, a diff is shown)
   stunnel (for HTTPS and FTPS tests)
   OpenSSH or SunSSH (for SCP, SFTP and SOCKS4/5 tests)
+  nghttpx (for HTTP/2 tests)
 
  1.2 Port numbers used by test servers
 
@@ -163,7 +164,7 @@
 
  1.8 Logs
 
-  All logs are generated in the logs/ subdirectory (it is emptied first in the
+  All logs are generated in the log/ subdirectory (it is emptied first in the
   runtests.pl script). Use runtests.pl -k to force it to keep the temporary
   files after the test run since successful runs will clean it up otherwise.
 
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 9c50673..b8b18e5 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -44,7 +44,7 @@
 test190 test191 test192 test193 test194 test195 test196 test197 test198 \
 test199 test200 test201 test202 test203 test204 test205 test206 test207 \
 test208 test209 test210 test211 test212 test213 test214 test215 test216 \
-test217 test218         test220 test221 test222 test223 test224 test225 \
+test217 test218 test219 test220 test221 test222 test223 test224 test225 \
 test226 test227 test228 test229         test231         test233 test234 \
 test235 test236 test237 test238 test239 test240 test241 test242 test243 \
         test245 test246 test247 test248 test249 test250 test251 test252 \
@@ -120,14 +120,16 @@
 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \
 test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \
 test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \
-\
+test1144 \
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
 test1216 test1217 test1218 test1219 \
 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
 test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
 test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
-test1244 \
+test1244 test1245 test1246 test1247 \
+\
+test1280 \
 \
 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
 test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
@@ -156,9 +158,10 @@
 \
 test1520 \
 \
-test1525 test1526 test1527 test1528 test1529 test1530 test1531 \
+test1525 test1526 test1527 test1528 test1529 test1530 test1531 test1532 \
+test1533 test1534 \
 \
-test1600 test1601 test1602 test1603 test1604 \
+test1600 test1601 test1602 test1603 test1604 test1605 \
 \
 test1700 test1701 test1702 \
 \
diff --git a/tests/data/test1001 b/tests/data/test1001
index 60e68a8..91b1320 100644
--- a/tests/data/test1001
+++ b/tests/data/test1001
@@ -89,6 +89,7 @@
 Content-Range: bytes 2-4/5

 User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 

 GET http://%HOSTIP:%HTTPPORT/1001 HTTP/1.1

@@ -96,6 +97,7 @@
 Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1001", response="6af4d89c952f4dd4cc215a6878dc499d"

 Content-Range: bytes 2-4/5

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 3

 Expect: 100-continue

 

diff --git a/tests/data/test1002 b/tests/data/test1002
index 83b87b9..83cce6e 100644
--- a/tests/data/test1002
+++ b/tests/data/test1002
@@ -88,6 +88,7 @@
 Content-Range: bytes 2-4/5

 User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 

 GET http://%HOSTIP:%HTTPPORT/1002.upload1 HTTP/1.1

@@ -95,6 +96,7 @@
 Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1002.upload1", response="198aa9b6acb4b0c71d02a197a5e41f54"

 Content-Range: bytes 2-4/5

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 3

 Expect: 100-continue

 

@@ -105,6 +107,7 @@
 Content-Range: bytes 2-4/5

 User-Agent: curl/7.16.1

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 3

 Expect: 100-continue

 

diff --git a/tests/data/test1008 b/tests/data/test1008
index 1dac395..bcc503e 100644
--- a/tests/data/test1008
+++ b/tests/data/test1008
@@ -114,10 +114,12 @@
 CONNECT test.remote.example.com.1008:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.1008:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.1008:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.1008:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

+Proxy-Connection: Keep-Alive

 

 GET /path/10080002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test1021 b/tests/data/test1021
index 3bd64bd..3ac9e12 100644
--- a/tests/data/test1021
+++ b/tests/data/test1021
@@ -119,14 +119,17 @@
 <protocol>
 CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.1021:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.1021:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.1021:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

+Proxy-Connection: Keep-Alive

 

 GET /path/10210002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test1034 b/tests/data/test1034
index f142684..c475740 100644
--- a/tests/data/test1034
+++ b/tests/data/test1034
@@ -55,6 +55,7 @@
 GET http://invalid-utf8-â.local/page/1034 HTTP/1.1

 Host: invalid-utf8-â.local

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1035 b/tests/data/test1035
index e1c2af6..20b434c 100644
--- a/tests/data/test1035
+++ b/tests/data/test1035
@@ -52,6 +52,7 @@
 GET http://too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local/page/1035 HTTP/1.1

 Host: too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1059 b/tests/data/test1059
index ee4e6a7..6820ea6 100644
--- a/tests/data/test1059
+++ b/tests/data/test1059
@@ -51,6 +51,7 @@
 <protocol>
 CONNECT test-number:1059 HTTP/1.1

 Host: test-number:1059

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1060 b/tests/data/test1060
index 1094792..e4aea65 100644
--- a/tests/data/test1060
+++ b/tests/data/test1060
@@ -887,10 +887,12 @@
 <protocol>
 CONNECT test.remote.haxx.se.1060:8990 HTTP/1.1

 Host: test.remote.haxx.se.1060:8990

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.haxx.se.1060:8990 HTTP/1.1

 Host: test.remote.haxx.se.1060:8990

 Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.1060:8990", response="e1fbed39c26f4efe284adc0e576ff638"

+Proxy-Connection: Keep-Alive

 

 GET /path/10600002 HTTP/1.1

 Host: test.remote.haxx.se.1060:8990

diff --git a/tests/data/test1061 b/tests/data/test1061
index 4f53a87..a55a272 100644
--- a/tests/data/test1061
+++ b/tests/data/test1061
@@ -892,10 +892,12 @@
 <protocol>
 CONNECT test.remote.haxx.se.1061:8990 HTTP/1.1

 Host: test.remote.haxx.se.1061:8990

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.haxx.se.1061:8990 HTTP/1.1

 Host: test.remote.haxx.se.1061:8990

 Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.1061:8990", response="4e23449fa93224834299e7282a70472c"

+Proxy-Connection: Keep-Alive

 

 GET /path/10610002 HTTP/1.1

 Host: test.remote.haxx.se.1061:8990

diff --git a/tests/data/test1077 b/tests/data/test1077
index e71d756..a3c9024 100644
--- a/tests/data/test1077
+++ b/tests/data/test1077
@@ -30,6 +30,7 @@
 Content-Type: text/plain

 Content-Length: 9

 Funny-head: yesyes

+Proxy-Connection: Keep-Alive

 

 contents
 </data2>
@@ -62,10 +63,12 @@
 GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1077 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/10770002 HTTP/1.0

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1078 b/tests/data/test1078
index f04bad3..a9bb771 100644
--- a/tests/data/test1078
+++ b/tests/data/test1078
@@ -56,6 +56,7 @@
 <proxy>
 CONNECT %HOSTIP.1078:%HTTPPORT HTTP/1.0

 Host: %HOSTIP.1078:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test1087 b/tests/data/test1087
index 1fb13cb..d228976 100644
--- a/tests/data/test1087
+++ b/tests/data/test1087
@@ -92,15 +92,18 @@
 GET http://first.host.it.is/we/want/that/page/10871000 HTTP/1.1

 Host: first.host.it.is

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://first.host.it.is/we/want/that/page/10871000 HTTP/1.1

 Host: first.host.it.is

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://goto.second.host.now/10871002 HTTP/1.1

 Host: goto.second.host.now

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1088 b/tests/data/test1088
index 9801fff..a807ce9 100644
--- a/tests/data/test1088
+++ b/tests/data/test1088
@@ -93,16 +93,19 @@
 GET http://first.host.it.is/we/want/that/page/10881000 HTTP/1.1

 Host: first.host.it.is

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://first.host.it.is/we/want/that/page/10881000 HTTP/1.1

 Host: first.host.it.is

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://goto.second.host.now/10881002 HTTP/1.1

 Host: goto.second.host.now

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1092 b/tests/data/test1092
index ce843f0..adef432 100644
--- a/tests/data/test1092
+++ b/tests/data/test1092
@@ -49,6 +49,7 @@
 GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1092;type=i HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1097 b/tests/data/test1097
index 81ea855..3b733a5 100644
--- a/tests/data/test1097
+++ b/tests/data/test1097
@@ -67,6 +67,7 @@
 Host: test.a.galaxy.far.far.away.1097:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 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

+Proxy-Connection: Keep-Alive

 

 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

diff --git a/tests/data/test1098 b/tests/data/test1098
index 70a6f39..9805648 100644
--- a/tests/data/test1098
+++ b/tests/data/test1098
@@ -49,10 +49,12 @@
 GET ftp://ftp-site/moo/1098 HTTP/1.1

 Host: ftp-site:21

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET ftp://ftp-site/moo/1098 HTTP/1.1

 Host: ftp-site:21

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <stdout>
diff --git a/tests/data/test1104 b/tests/data/test1104
index 4df81a1..21efe3c 100644
--- a/tests/data/test1104
+++ b/tests/data/test1104
@@ -72,10 +72,12 @@
 GET http://%HOSTIP:%HTTPPORT/want/1104 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://%HOSTIP:%HTTPPORT/want/data/11040002 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: test2=true

 

 </protocol>
diff --git a/tests/data/test1106 b/tests/data/test1106
index a2adbbb..0c6bec1 100644
--- a/tests/data/test1106
+++ b/tests/data/test1106
@@ -50,6 +50,7 @@
 GET ftp://%HOSTIP:23456/1106 HTTP/1.1

 Host: %HOSTIP:23456

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1135 b/tests/data/test1135
index 960aade..f7c6a7a 100644
--- a/tests/data/test1135
+++ b/tests/data/test1135
@@ -58,7 +58,7 @@
 CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
 CURL_EXTERN void curl_easy_cleanup(CURL *curl);
 CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
-CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
 CURL_EXTERN void curl_easy_reset(CURL *curl);
 CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
 CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
diff --git a/tests/data/test1141 b/tests/data/test1141
index b0ff038..9c41d39 100644
--- a/tests/data/test1141
+++ b/tests/data/test1141
@@ -58,10 +58,12 @@
 GET http://%HOSTIP:%HTTPPORT/want/1141 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://foo.example.com/want/11410001 HTTP/1.1

 Host: foo.example.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1142 b/tests/data/test1142
index 0ecfbd3..76c6bdf 100644
--- a/tests/data/test1142
+++ b/tests/data/test1142
@@ -53,6 +53,7 @@
 GET http://%HOSTIP:%HTTPPORT/want/1142 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 # 3, CURLE_URL_MALFORMAT for the four slashes
diff --git a/tests/data/test1144 b/tests/data/test1144
new file mode 100644
index 0000000..3fb9093
--- /dev/null
+++ b/tests/data/test1144
@@ -0,0 +1,69 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP HEAD
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+No headers at all, just data swsclose
+
+Let's get
+
+a little
+
+so that
+
+we
+
+have
+
+some
+
+test
+
+data to
+
+verify
+</data>
+# make sure no data is written
+<datacheck nonewline="yes">
+
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP HEAD, receive no headers only body
+ </name>
+ <command>
+-I http://%HOSTIP:%HTTPPORT/1144
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+HEAD /1144 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+</protocol>
+<errorcode>
+8
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1213 b/tests/data/test1213
index bc146b0..4f22f0d 100644
--- a/tests/data/test1213
+++ b/tests/data/test1213
@@ -46,6 +46,7 @@
 GET http://we.want.that.site.com.1213/ HTTP/1.1

 Host: we.want.that.site.com.1213

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1214 b/tests/data/test1214
index e703f7a..3eeb3e3 100644
--- a/tests/data/test1214
+++ b/tests/data/test1214
@@ -46,6 +46,7 @@
 GET http://we.want.that.site.com.1214/?moo=foo HTTP/1.1

 Host: we.want.that.site.com.1214

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1215 b/tests/data/test1215
index e22591c..f8c52a9 100644
--- a/tests/data/test1215
+++ b/tests/data/test1215
@@ -92,12 +92,14 @@
 Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.30.0-DEV

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://%HOSTIP:%HTTPPORT/1215 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.30.0-DEV

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1216 b/tests/data/test1216
index 6e45ac6..5beda79 100644
--- a/tests/data/test1216
+++ b/tests/data/test1216
@@ -50,11 +50,13 @@
 GET http://example.fake/c/1216 HTTP/1.1

 Host: example.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: moo2=indeed; moo3=indeed

 

 GET http://bexample.fake/c/1216 HTTP/1.1

 Host: bexample.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1218 b/tests/data/test1218
index 9c2fc03..e3f1f6d 100644
--- a/tests/data/test1218
+++ b/tests/data/test1218
@@ -43,15 +43,18 @@
 GET http://example.fake/c/1218 HTTP/1.1

 Host: example.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://example.fake/c/1218 HTTP/1.1

 Host: example.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: bug=fixed

 

 GET http://bexample.fake/c/1218 HTTP/1.1

 Host: bexample.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1228 b/tests/data/test1228
index d0af517..a7e56a7 100644
--- a/tests/data/test1228
+++ b/tests/data/test1228
@@ -42,10 +42,12 @@
 GET http://example.fake/hoge/1228 HTTP/1.1

 Host: example.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://example.fake/hogege/ HTTP/1.1

 Host: example.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: path1=root

 

 </protocol>
diff --git a/tests/data/test1230 b/tests/data/test1230
index 8ce4c4e..3c1d3d4 100644
--- a/tests/data/test1230
+++ b/tests/data/test1230
@@ -69,6 +69,7 @@
 <protocol>
 CONNECT [1234:1234:1234::4ce]:%HTTPPORT HTTP/1.1

 Host: [1234:1234:1234::4ce]:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 GET /wanted/page/1230 HTTP/1.1

 Host: [1234:1234:1234::4ce]:%HTTPPORT

diff --git a/tests/data/test1232 b/tests/data/test1232
index 1c5bc20..ead4336 100644
--- a/tests/data/test1232
+++ b/tests/data/test1232
@@ -53,10 +53,12 @@
 GET http://test.remote.haxx.se.1232:8990/hej/but/1232?stupid=me/../1232 HTTP/1.1

 Host: test.remote.haxx.se.1232:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.haxx.se.1232:8990/hej/but/12320001 HTTP/1.1

 Host: test.remote.haxx.se.1232:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1241 b/tests/data/test1241
index 5a12732..aaa5688 100644
--- a/tests/data/test1241
+++ b/tests/data/test1241
@@ -52,10 +52,12 @@
 GET http://test.remote.haxx.se.1241:8990/../../hej/but/who/../1241?stupid=me/../1241 HTTP/1.1

 Host: test.remote.haxx.se.1241:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.haxx.se.1241:8990/../../hej/but/who/../12410001 HTTP/1.1

 Host: test.remote.haxx.se.1241:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1244 b/tests/data/test1244
index 7912b4e..d0769ad 100644
--- a/tests/data/test1244
+++ b/tests/data/test1244
@@ -54,6 +54,7 @@
 GET http://%HOSTIP:%HTTPPORT/1244 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1245 b/tests/data/test1245
new file mode 100644
index 0000000..34d6549
--- /dev/null
+++ b/tests/data/test1245
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+FTP
+HTTP
+HTTP GET
+--proto
+--proto-redir
+followlocation
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 OK swsclose

+Date: Thu, 09 Nov 2010 14:49:00 GMT

+Server: test-server/fake

+Content-Length: 0

+Location: ftp://127.0.0.1:8992/1245

+Connection: close

+

+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+ftp
+http
+</server>
+<name>
+--proto deny must override --proto-redir allow
+</name>
+<command>
+--location --proto +all,-ftp --proto-redir -all,+ftp http://%HOSTIP:%HTTPPORT/1245
+</command>
+# The data section doesn't do variable substitution, so we must assert this
+<precheck>
+perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP' ne '127.0.0.1' || '%FTPPORT' ne '8992' );"
+</precheck>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /1245 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+</protocol>
+# 1 - Protocol ftp not supported or disabled in libcurl
+<errorcode>
+1
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1246 b/tests/data/test1246
new file mode 100644
index 0000000..6565929
--- /dev/null
+++ b/tests/data/test1246
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+# verify URL with hostname ending in pound sign
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 6
+Connection: close
+
+-foo-
+</data>
+
+<data1>
+HTTP/1.1 200 OK
+Content-Length: 7
+Connection: close
+
+-cool-
+</data1>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+URL with '#' at end of host name instead of '/'
+ </name>
+ <command>
+--proxy http://%HOSTIP:%HTTPPORT http://test.remote.haxx.se.1246:%HTTPPORT#@127.0.0.1/tricked.html no-scheme-url.com.1246:%HTTPPORT#@127.127.127.127/again.html
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://test.remote.haxx.se.1246:%HTTPPORT/ HTTP/1.1

+Host: test.remote.haxx.se.1246:%HTTPPORT

+Accept: */*

+Proxy-Connection: Keep-Alive

+

+GET http://no-scheme-url.com.1246:%HTTPPORT/ HTTP/1.1

+Host: no-scheme-url.com.1246:%HTTPPORT

+Accept: */*

+Proxy-Connection: Keep-Alive

+

+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1247 b/tests/data/test1247
new file mode 100644
index 0000000..48c5ccd
--- /dev/null
+++ b/tests/data/test1247
@@ -0,0 +1,38 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+--fail-early
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+ <name>
+--fail-early
+ </name>
+ <command>
+--fail-early h1234://%HOSTIP:%HTTPPORT/1247 http://%HOSTIP:%HTTPPORT/1247
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# Protocol "h1234" not supported or disabled in libcurl
+<errorcode>
+1
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1280 b/tests/data/test1280
new file mode 100644
index 0000000..15c1e2f
--- /dev/null
+++ b/tests/data/test1280
@@ -0,0 +1,58 @@
+<testcase>
+<info>
+<keywords>
+globbing
+</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
+
+bytes
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+simple [a-d] globbing
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/[a-d]/1280
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /a/1280 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+GET /b/1280 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+GET /c/1280 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+GET /d/1280 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1301 b/tests/data/test1301
index 4b6fac8..8506c00 100644
--- a/tests/data/test1301
+++ b/tests/data/test1301
@@ -2,7 +2,7 @@
 <info>
 <keywords>
 unittest
-curl_strequal
+curl_strcasecompare
 </keywords>
 </info>
 
@@ -16,7 +16,7 @@
 unittest
 </features>
  <name>
-curl_strequal unit tests
+curl_strcasecompare unit tests
  </name>
 <tool>
 unit1301
diff --git a/tests/data/test1314 b/tests/data/test1314
index 11e128a..078ada6 100644
--- a/tests/data/test1314
+++ b/tests/data/test1314
@@ -67,10 +67,12 @@
 GET http://firstplace.example.com/want/1314 HTTP/1.1

 Host: firstplace.example.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://somewhere.example.com/reply/1314 HTTP/1.1

 Host: somewhere.example.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1319 b/tests/data/test1319
index a97da9c..0520b1b 100644
--- a/tests/data/test1319
+++ b/tests/data/test1319
@@ -79,6 +79,7 @@
 CONNECT pop.1319:%POP3PORT HTTP/1.1

 Host: pop.1319:%POP3PORT

 User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e

+Proxy-Connection: Keep-Alive

 

 </proxy>
 </verify>
diff --git a/tests/data/test1320 b/tests/data/test1320
index 609f4c2..7a15f80 100644
--- a/tests/data/test1320
+++ b/tests/data/test1320
@@ -66,6 +66,7 @@
 CONNECT smtp.1320:%SMTPPORT HTTP/1.1

 Host: smtp.1320:%SMTPPORT

 User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e

+Proxy-Connection: Keep-Alive

 

 </proxy>
 </verify>
diff --git a/tests/data/test1321 b/tests/data/test1321
index b5ad277..266fd88 100644
--- a/tests/data/test1321
+++ b/tests/data/test1321
@@ -75,6 +75,7 @@
 CONNECT imap.1321:%IMAPPORT HTTP/1.1

 Host: imap.1321:%IMAPPORT

 User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e

+Proxy-Connection: Keep-Alive

 

 </proxy>
 </verify>
diff --git a/tests/data/test1331 b/tests/data/test1331
index 837ef8d..3299df4 100644
--- a/tests/data/test1331
+++ b/tests/data/test1331
@@ -75,11 +75,13 @@
 GET http://z.x.com/1331 HTTP/1.1

 Host: z.x.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://z.x.com/1331 HTTP/1.1

 Host: z.x.com

 Proxy-Authorization: Basic bXluYW1lOm15cGFzc3dvcmQ=

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: proxycookie=weirdo

 

 </protocol>
diff --git a/tests/data/test1400 b/tests/data/test1400
index 0ee7370..838fe63 100644
--- a/tests/data/test1400
+++ b/tests/data/test1400
@@ -77,6 +77,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1401 b/tests/data/test1401
index 602b09a..1e2b4a7 100644
--- a/tests/data/test1401
+++ b/tests/data/test1401
@@ -96,6 +96,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1402 b/tests/data/test1402
index 0c2199e..07c3f49 100644
--- a/tests/data/test1402
+++ b/tests/data/test1402
@@ -84,6 +84,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1403 b/tests/data/test1403
index 98f238f..18167b4 100644
--- a/tests/data/test1403
+++ b/tests/data/test1403
@@ -79,6 +79,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1404 b/tests/data/test1404
index a159e49..6f53ca8 100644
--- a/tests/data/test1404
+++ b/tests/data/test1404
@@ -133,6 +133,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1405 b/tests/data/test1405
index f223954..4e8d46d 100644
--- a/tests/data/test1405
+++ b/tests/data/test1405
@@ -93,6 +93,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1406 b/tests/data/test1406
index c7e4cd4..0ccb08a 100644
--- a/tests/data/test1406
+++ b/tests/data/test1406
@@ -88,6 +88,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1407 b/tests/data/test1407
index 8f8cb2a..981e4e4 100644
--- a/tests/data/test1407
+++ b/tests/data/test1407
@@ -68,6 +68,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1415 b/tests/data/test1415
index 37cfb07..5604404 100644
--- a/tests/data/test1415
+++ b/tests/data/test1415
@@ -57,6 +57,7 @@
 GET http://example.com/we/want/1415 HTTP/1.1

 Host: example.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test1420 b/tests/data/test1420
index 7a86806..a20f898 100644
--- a/tests/data/test1420
+++ b/tests/data/test1420
@@ -73,6 +73,7 @@
      them yourself.
 
   CURLOPT_WRITEDATA set to a objectpointer
+  CURLOPT_INTERLEAVEDATA set to a objectpointer
   CURLOPT_WRITEFUNCTION set to a functionpointer
   CURLOPT_READDATA set to a objectpointer
   CURLOPT_READFUNCTION set to a functionpointer
diff --git a/tests/data/test1421 b/tests/data/test1421
index 889c938..6c59b21 100644
--- a/tests/data/test1421
+++ b/tests/data/test1421
@@ -59,10 +59,12 @@
 GET http://test.remote.haxx.se.1421:8990/ HTTP/1.1

 Host: test.remote.haxx.se.1421:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://different.remote.haxx.se.1421:8990/ HTTP/1.1

 Host: different.remote.haxx.se.1421:8990

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 [DISCONNECT]
 </protocol>
diff --git a/tests/data/test1428 b/tests/data/test1428
index 60fb8a9..59041ec 100644
--- a/tests/data/test1428
+++ b/tests/data/test1428
@@ -64,6 +64,7 @@
 CONNECT test.1428:%HTTPPORT HTTP/1.1

 Host: test.1428:%HTTPPORT

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

+Proxy-Connection: Keep-Alive

 header-type: proxy

 

 </proxy>
diff --git a/tests/data/test1509 b/tests/data/test1509
index 18eb07f..b4bfc66 100644
--- a/tests/data/test1509
+++ b/tests/data/test1509
@@ -74,6 +74,7 @@
 <proxy>
 CONNECT the.old.moo.1509:%HTTPPORT HTTP/1.1

 Host: the.old.moo.1509:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test1525 b/tests/data/test1525
index d8f6883..0560d5c 100644
--- a/tests/data/test1525
+++ b/tests/data/test1525
@@ -58,6 +58,7 @@
 <proxy>
 CONNECT the.old.moo.1525:%HTTPPORT HTTP/1.1

 Host: the.old.moo.1525:%HTTPPORT

+Proxy-Connection: Keep-Alive

 User-Agent: Http Agent

 

 </proxy>
diff --git a/tests/data/test1526 b/tests/data/test1526
index 9f5d09e..aa111c8 100644
--- a/tests/data/test1526
+++ b/tests/data/test1526
@@ -58,6 +58,7 @@
 <proxy>
 CONNECT the.old.moo.1526:%HTTPPORT HTTP/1.1

 Host: the.old.moo.1526:%HTTPPORT

+Proxy-Connection: Keep-Alive

 User-Agent: Proxy Agent

 

 </proxy>
diff --git a/tests/data/test1527 b/tests/data/test1527
index 69ae6e4..e8d5279 100644
--- a/tests/data/test1527
+++ b/tests/data/test1527
@@ -57,6 +57,7 @@
 <proxy>
 CONNECT the.old.moo.1527:%HTTPPORT HTTP/1.1

 Host: the.old.moo.1527:%HTTPPORT

+Proxy-Connection: Keep-Alive

 User-Agent: Http Agent

 Expect: 100-continue

 

diff --git a/tests/data/test1528 b/tests/data/test1528
index e60f600..876806a 100644
--- a/tests/data/test1528
+++ b/tests/data/test1528
@@ -51,6 +51,7 @@
 GET http://the.old.moo:%HTTPPORT/1528 HTTP/1.1

 Host: the.old.moo:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 User-Agent: Http Agent

 Proxy-User-Agent: Http Agent2

 

diff --git a/tests/data/test1532 b/tests/data/test1532
new file mode 100644
index 0000000..5b2afc7
--- /dev/null
+++ b/tests/data/test1532
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.0 200 OK swsclose

+Content-Length: 0

+

+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib1532
+</tool>
+<name>
+Test CURLINFO_RESPONSE_CODE
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/1532
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /1532 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1533 b/tests/data/test1533
new file mode 100644
index 0000000..5651816
--- /dev/null
+++ b/tests/data/test1533
@@ -0,0 +1,74 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+CURLOPT_KEEP_SENDING_ON_ERROR
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<servercmd>
+auth_required
+</servercmd>
+<data nocheck="yes">
+HTTP/1.1 401 Authorization Required

+Date: Thu, 09 Nov 2010 14:49:00 GMT

+Server: test-server/fake

+Content-Length: 15

+
+Early Response
+</data>
+</reply>
+# Client-side
+<client>
+<server>
+http
+</server>
+<tool>
+lib1533
+</tool>
+<name>
+HTTP with CURLOPT_KEEP_SENDING_ON_ERROR and an early error response
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/1533
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+# TEST_ERR_SUCCESS is errorcode 120
+<verify>
+<errorcode>
+120
+</errorcode>
+<protocol nonewline="yes">
+POST /1533 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+Content-Length: 3

+Content-Type: application/x-www-form-urlencoded

+

+POST /1533 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+Content-Length: 3

+Content-Type: application/x-www-form-urlencoded

+

+POST /1533 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+Content-Length: 3

+Content-Type: application/x-www-form-urlencoded

+

+aaaPOST /1533 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+Content-Length: 3

+Content-Type: application/x-www-form-urlencoded

+

+aaa
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1534 b/tests/data/test1534
new file mode 100644
index 0000000..f3cd2f0
--- /dev/null
+++ b/tests/data/test1534
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.0 200 OK swsclose

+Last-Modified: Thu, 01 Jan 1970 00:00:30 GMT

+Content-Length: 0

+

+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib1534
+</tool>
+<name>
+Test CURLINFO_RESPONSE_CODE
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/1534
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /1534 HTTP/1.1

+Host: %HOSTIP:%HTTPPORT

+Accept: */*

+

+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test16 b/tests/data/test16
index 9d9a9cc..15f4c7a 100644
--- a/tests/data/test16
+++ b/tests/data/test16
@@ -45,6 +45,7 @@
 Host: we.want.that.site.com

 Proxy-Authorization: Basic ZmFrZUB1c2VyOmxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZw==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test1605 b/tests/data/test1605
new file mode 100644
index 0000000..09ef669
--- /dev/null
+++ b/tests/data/test1605
@@ -0,0 +1,25 @@
+<testcase>
+<info>
+<keywords>
+unittest
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+unittest
+</features>
+ <name>
+Test negative data lengths as input to libcurl functions
+ </name>
+<tool>
+unit1605
+</tool>
+</client>
+
+</testcase>
diff --git a/tests/data/test161 b/tests/data/test161
index 0458359..91a3388 100644
--- a/tests/data/test161
+++ b/tests/data/test161
@@ -32,8 +32,8 @@
 
 # Verify data after the test has been "shot"
 <verify>
-# This gets QUIT sent because CURLE_PARTIAL_FILE does NOT mark the control
-# connection as bad
+# This doesn't send QUIT because of known bug:
+# "7.8 Premature transfer end but healthy control channel"
 <protocol>
 USER anonymous

 PASS ftp@example.com

@@ -42,8 +42,8 @@
 TYPE I

 SIZE 161

 RETR 161

-QUIT

 </protocol>
+# CURLE_PARTIAL_FILE = 18
 <errorcode>
 18
 </errorcode>
diff --git a/tests/data/test162 b/tests/data/test162
index cc4c82d..ee2f40a 100644
--- a/tests/data/test162
+++ b/tests/data/test162
@@ -51,6 +51,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <errorcode>
diff --git a/tests/data/test165 b/tests/data/test165
index b475fde..6fc0ad2 100644
--- a/tests/data/test165
+++ b/tests/data/test165
@@ -31,13 +31,14 @@
 idn
 </features>
 <setenv>
-CHARSET=ISO8859-1
+CHARSET=UTF-8
+LANG=en_US.UTF-8
 </setenv>
  <name>
 HTTP over proxy with IDN host name
  </name>
  <command>
-http://www.åäö.se/page/165 -x %HOSTIP:%HTTPPORT
+http://www.åäö.se/page/165 -x %HOSTIP:%HTTPPORT http://www.große.de/page/165
 </command>
 </client>
 
@@ -51,6 +52,12 @@
 GET http://www.xn--4cab6c.se/page/165 HTTP/1.1

 Host: www.xn--4cab6c.se

 Accept: */*

+Proxy-Connection: Keep-Alive

+

+GET http://www.xn--groe-xna.de/page/165 HTTP/1.1

+Host: www.xn--groe-xna.de

+Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test167 b/tests/data/test167
index 76f9e5c..0b14996 100644
--- a/tests/data/test167
+++ b/tests/data/test167
@@ -65,6 +65,7 @@
 Proxy-Authorization: Basic Zm9vOmJhcg==

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://data.from.server.requiring.digest.hohoho.com/167 HTTP/1.1

 Host: data.from.server.requiring.digest.hohoho.com

@@ -72,6 +73,7 @@
 Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/167", response="13c7c02a252cbe1c46d8669898a3be26"

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test168 b/tests/data/test168
index 0f4e025..20e0b6d 100644
--- a/tests/data/test168
+++ b/tests/data/test168
@@ -78,12 +78,14 @@
 Host: data.from.server.requiring.digest.hohoho.com

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1

 Host: data.from.server.requiring.digest.hohoho.com

 Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/168", response="fb8608e00ad9239a3dedb14bc8575976"

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1

 Host: data.from.server.requiring.digest.hohoho.com

@@ -91,6 +93,7 @@
 Authorization: Digest username="digest", realm="realmweirdo", nonce="123456", uri="/168", response="ca87f2d768a231e2d637a55698d5c416"

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test169 b/tests/data/test169
index be5b4c6..73ca9bd 100644
--- a/tests/data/test169
+++ b/tests/data/test169
@@ -108,18 +108,21 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1

 Host: data.from.server.requiring.digest.hohoho.com

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1

 Host: data.from.server.requiring.digest.hohoho.com

 Authorization: Digest username="digest", realm="r e a l m", nonce="abcdef", uri="/169", response="95d48591985a03c4b49cb962aa7bd3e6"

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test170 b/tests/data/test170
index 48a263f..8ce7774 100644
--- a/tests/data/test170
+++ b/tests/data/test170
@@ -40,6 +40,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 libidn/0.4.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 

 </protocol>
diff --git a/tests/data/test171 b/tests/data/test171
index 3b9f7ba..09e48b7 100644
--- a/tests/data/test171
+++ b/tests/data/test171
@@ -44,6 +44,7 @@
 GET http://z.x.com/171 HTTP/1.1

 Host: z.x.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <file name="log/jar171" mode="text">
diff --git a/tests/data/test179 b/tests/data/test179
index 1cd5bad..f8f7811 100644
--- a/tests/data/test179
+++ b/tests/data/test179
@@ -49,6 +49,7 @@
 GET http://supertrooper.fake/c/179 HTTP/1.1

 Host: supertrooper.fake

 Accept: */*

+Proxy-Connection: Keep-Alive

 Cookie: moo2=indeed

 

 </protocol>
diff --git a/tests/data/test1800 b/tests/data/test1800
index 96a6c14..0a2bb1f 100644
--- a/tests/data/test1800
+++ b/tests/data/test1800
@@ -48,7 +48,7 @@
 Accept: */*

 Connection: Upgrade, HTTP2-Settings

 Upgrade: %H2CVER

-HTTP2-Settings: AAMAAABkAAQAAP__

+HTTP2-Settings: AAMAAABkAARAAAAA

 

 </protocol>
 </verify>
diff --git a/tests/data/test1801 b/tests/data/test1801
index 16ee12d..9e1900b 100644
--- a/tests/data/test1801
+++ b/tests/data/test1801
@@ -58,7 +58,7 @@
 Accept: */*

 Connection: Upgrade, HTTP2-Settings

 Upgrade: %H2CVER

-HTTP2-Settings: AAMAAABkAAQAAP__

+HTTP2-Settings: AAMAAABkAARAAAAA

 

 </protocol>
 # CURLE_HTTP2: Send failure: Broken pipe
diff --git a/tests/data/test183 b/tests/data/test183
index b447109..f34dc0c 100644
--- a/tests/data/test183
+++ b/tests/data/test183
@@ -42,11 +42,13 @@
 User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6

 Host: deathstar.another.galaxy

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://a.galaxy.far.far.away/183 HTTP/1.1

 User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6
 Host: a.galaxy.far.far.away

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test184 b/tests/data/test184
index 9cadc82..8b09dde 100644
--- a/tests/data/test184
+++ b/tests/data/test184
@@ -62,10 +62,12 @@
 Host: another.visitor.stay.a.while.stay.foreeeeeever

 User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://yet.another.host/184 HTTP/1.1

 Host: yet.another.host

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test185 b/tests/data/test185
index dbef6e7..298dd49 100644
--- a/tests/data/test185
+++ b/tests/data/test185
@@ -62,10 +62,12 @@
 Host: another.visitor.stay.a.while.stay.foreeeeeever

 User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://deathstar.another.galaxy/go/west/185 HTTP/1.1

 Host: another.visitor.stay.a.while.stay.foreeeeeever

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test2045 b/tests/data/test2045
index 3190f80..15647d3 100644
--- a/tests/data/test2045
+++ b/tests/data/test2045
@@ -19,7 +19,7 @@
 that by replying with something that both protocols can understand. Our FTP
 server allows a custom welcome message, so we use that feature to make an HTTP
 reply that contains an FTP reply (think polyglot). In the case of FTP we expect
-curl will return CURLE_FTP_WEIRD_SERVER_REPLY so we test for that return code.
+curl will return CURLE_WEIRD_SERVER_REPLY so we test for that return code.
 -->
 <servercmd>
 REPLY welcome HTTP/1.1 200 OK\r\nContent-Length: 21\r\n\r\n500 Weird FTP Reply
@@ -46,7 +46,7 @@
 #
 # Verify data after the test has been "shot"
 <verify>
-# CURLE_FTP_WEIRD_SERVER_REPLY is error code 8
+# CURLE_WEIRD_SERVER_REPLY is error code 8
 <errorcode>
 8
 </errorcode>
diff --git a/tests/data/test2047 b/tests/data/test2047
index a8cca2f..4422978 100644
--- a/tests/data/test2047
+++ b/tests/data/test2047
@@ -63,10 +63,12 @@
 GET http://xn--4cab6c.se/2047 HTTP/1.1

 Host: xn--4cab6c.se

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://xn--4cab6c.se/20470001 HTTP/1.1

 Host: xn--4cab6c.se

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test2048 b/tests/data/test2048
index eb2b1df..787f584 100644
--- a/tests/data/test2048
+++ b/tests/data/test2048
@@ -26,7 +26,7 @@
 pinnedpubkey no-match must fail even when insecure
 </name>
 <command>
---insecure --cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost.nn-sv.pub.der https://localhost:%HTTPSPORT/2034
+--insecure --cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost.nn-sv.pub.der https://localhost:%HTTPSPORT/2048
 </command>
 </client>
 
diff --git a/tests/data/test2050 b/tests/data/test2050
index 805e872..81ef79f 100644
--- a/tests/data/test2050
+++ b/tests/data/test2050
@@ -64,6 +64,7 @@
 <proxy>
 CONNECT connect.example.com.2050:%HTTPPORT HTTP/1.1

 Host: connect.example.com.2050:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test206 b/tests/data/test206
index efbc56e..5f0c885 100644
--- a/tests/data/test206
+++ b/tests/data/test206
@@ -90,10 +90,12 @@
 <protocol>
 CONNECT test.remote.haxx.se.206:8990 HTTP/1.1

 Host: test.remote.haxx.se.206:8990

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.haxx.se.206:8990 HTTP/1.1

 Host: test.remote.haxx.se.206:8990

 Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.206:8990", response="003e36decb4dbf6366b3ecb9b87c24ec"

+Proxy-Connection: Keep-Alive

 

 GET /path/2060002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test208 b/tests/data/test208
index fb4c0ea..afb2566 100644
--- a/tests/data/test208
+++ b/tests/data/test208
@@ -57,6 +57,7 @@
 Host: host.com:21

 Authorization: Basic ZGFuaWVsOm15c2VjcmV0

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 78

 Expect: 100-continue

 

diff --git a/tests/data/test209 b/tests/data/test209
index f868541..961eba1 100644
--- a/tests/data/test209
+++ b/tests/data/test209
@@ -104,10 +104,12 @@
 CONNECT test.remote.example.com.209:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.209:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.209:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.209:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

+Proxy-Connection: Keep-Alive

 

 GET /path/2090002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test213 b/tests/data/test213
index 7ceed98..edbb6a6 100644
--- a/tests/data/test213
+++ b/tests/data/test213
@@ -104,10 +104,12 @@
 CONNECT test.remote.example.com.213:%HTTPPORT HTTP/1.0

 Host: test.remote.example.com.213:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.213:%HTTPPORT HTTP/1.0

 Host: test.remote.example.com.213:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

+Proxy-Connection: Keep-Alive

 

 POST /path/2130002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test217 b/tests/data/test217
index 0e0c0ad..f10df56 100644
--- a/tests/data/test217
+++ b/tests/data/test217
@@ -44,6 +44,7 @@
 <protocol>
 CONNECT test.remote.example.com.217:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.217:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 </protocol>
 # CURLE_RECV_ERROR
diff --git a/tests/data/test219 b/tests/data/test219
new file mode 100644
index 0000000..be3f0f3
--- /dev/null
+++ b/tests/data/test219
@@ -0,0 +1,37 @@
+<testcase>
+<info>
+<keywords>
+proxy
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+http
+</features>
+ <name>
+try using proxy with unsupported scheme
+ </name>
+ <command>
+-x foo://%HOSTIP:%HTTPPORT/219 http://%HOSTIP:%HTTPPORT/219
+</command>
+</client>
+
+#
+# Verify after the test has been "shot"
+<verify>
+<errorcode>
+7
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test233 b/tests/data/test233
index 996855d..b631e52 100644
--- a/tests/data/test233
+++ b/tests/data/test233
@@ -81,11 +81,13 @@
 Proxy-Authorization: Basic dGVzdGluZzp0aGlz

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://goto.second.host.now/2330002 HTTP/1.1

 Host: goto.second.host.now

 Proxy-Authorization: Basic dGVzdGluZzp0aGlz

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test234 b/tests/data/test234
index f7da2b9..1d2e05b 100644
--- a/tests/data/test234
+++ b/tests/data/test234
@@ -83,12 +83,14 @@
 Proxy-Authorization: Basic dGVzdGluZzp0aGlz

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://goto.second.host.now/2340002 HTTP/1.1

 Host: goto.second.host.now

 Proxy-Authorization: Basic dGVzdGluZzp0aGlz

 Authorization: Basic aWFtOm15c2VsZg==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test239 b/tests/data/test239
index 275c81b..6b92f07 100644
--- a/tests/data/test239
+++ b/tests/data/test239
@@ -83,6 +83,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 Content-Type: application/x-www-form-urlencoded

 

@@ -91,6 +92,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 6

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test243 b/tests/data/test243
index bc09286..3496055 100644
--- a/tests/data/test243
+++ b/tests/data/test243
@@ -103,6 +103,7 @@
 Host: %HOSTIP:%HTTPPORT

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 6

 Content-Type: application/x-www-form-urlencoded

 

@@ -111,6 +112,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 Content-Type: application/x-www-form-urlencoded

 

@@ -119,6 +121,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 6

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test256 b/tests/data/test256
index 0acd9db..2b96ecf 100644
--- a/tests/data/test256
+++ b/tests/data/test256
@@ -51,6 +51,7 @@
 Proxy-Authorization: Basic ZGFuaWVsOnN0ZW5iZXJn

 Range: bytes=78-

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 
diff --git a/tests/data/test257 b/tests/data/test257
index 45dcbd5..502448d 100644
--- a/tests/data/test257
+++ b/tests/data/test257
@@ -92,17 +92,20 @@
 Authorization: Basic dXNlcjE6cGFzc3dkMQ==

 User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://anotherone.com/2570002 HTTP/1.1

 Host: anotherone.com

 Authorization: Basic dXNlcjI6cGFzc3dkMg==

 User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://athird.com/2570003 HTTP/1.1

 Host: athird.com

 User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test258 b/tests/data/test258
index 82c6731..98c3401 100644
--- a/tests/data/test258
+++ b/tests/data/test258
@@ -20,6 +20,7 @@
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Proxy-Authenticate: Digest realm="many secrets", nonce="911"
+Proxy-Connection: close
 Content-Length: 0
 
 </data>
@@ -36,6 +37,7 @@
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Proxy-Authenticate: Digest realm="many secrets", nonce="911"
+Proxy-Connection: close
 Content-Length: 0
 
 HTTP/1.1 200 A OK

@@ -81,6 +83,7 @@
 Host: remotehost:54321

 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 409

 Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

 

@@ -106,6 +109,7 @@
 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Proxy-Authorization: Digest username="uuuser", realm="many secrets", nonce="911", uri="/we/want/258", response="2501654ca391f0b5c8c12a1da77e34cd"

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 409

 Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

 

diff --git a/tests/data/test259 b/tests/data/test259
index 75b1f53..9532887 100644
--- a/tests/data/test259
+++ b/tests/data/test259
@@ -79,6 +79,7 @@
 Host: remotehost:54321

 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 409

 Expect: 100-continue

 Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

@@ -105,6 +106,7 @@
 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Proxy-Authorization: Digest username="uuuser", realm="many secrets", nonce="911", uri="/we/want/259", response="b479994d13e60f3aa192a67c5892ddc5"

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 409

 Expect: 100-continue

 Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

diff --git a/tests/data/test263 b/tests/data/test263
index df0ba03..5088141 100644
--- a/tests/data/test263
+++ b/tests/data/test263
@@ -47,6 +47,7 @@
 GET http://veryveryremotesite.com/263 HTTP/1.1

 Host: veryveryremotesite.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test264 b/tests/data/test264
index 1174ca5..f4d171a 100644
--- a/tests/data/test264
+++ b/tests/data/test264
@@ -42,6 +42,7 @@
 Host: we.want.that.site.com

 Proxy-Authorization: Basic ZmFrZTp1c2Vy

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test265 b/tests/data/test265
index 79ab183..1a162b8 100644
--- a/tests/data/test265
+++ b/tests/data/test265
@@ -107,10 +107,12 @@
 CONNECT test.remote.example.com.265:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.265:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

+Proxy-Connection: Keep-Alive

 

 CONNECT test.remote.example.com.265:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.265:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

+Proxy-Connection: Keep-Alive

 

 POST /path/2650002 HTTP/1.1

 User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4

diff --git a/tests/data/test275 b/tests/data/test275
index 6000454..802c4bb 100644
--- a/tests/data/test275
+++ b/tests/data/test275
@@ -69,6 +69,7 @@
 Host: remotesite.com.275:%HTTPPORT

 Proxy-Authorization: Basic eW91YXJlOnlvdXJzZWxm

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test278 b/tests/data/test278
index e6f1ef7..3112264 100644
--- a/tests/data/test278
+++ b/tests/data/test278
@@ -42,6 +42,7 @@
 Host: we.want.that.site.com

 Proxy-Authorization: Basic ZmFrZTo=

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test279 b/tests/data/test279
index 5005daa..47f8b68 100644
--- a/tests/data/test279
+++ b/tests/data/test279
@@ -43,6 +43,7 @@
 Host: we.want.that.site.com

 Proxy-Authorization: Basic ZmFrZTo=

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test287 b/tests/data/test287
index 526446f..6772e22 100644
--- a/tests/data/test287
+++ b/tests/data/test287
@@ -37,6 +37,7 @@
 <protocol>
 CONNECT test.remote.example.com.287:%HTTPPORT HTTP/1.1

 Host: test.remote.example.com.287:%HTTPPORT

+Proxy-Connection: Keep-Alive

 User-Agent: looser/2007

 

 </protocol>
diff --git a/tests/data/test299 b/tests/data/test299
index a7b7755..4daaea4 100644
--- a/tests/data/test299
+++ b/tests/data/test299
@@ -46,6 +46,7 @@
 Host: host.com:21

 Authorization: Basic bWljaGFsOmF5YmFidHU=

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test43 b/tests/data/test43
index dc0dd5f..e5535bb 100644
--- a/tests/data/test43
+++ b/tests/data/test43
@@ -67,10 +67,12 @@
 GET http://%HOSTIP:%HTTPPORT/want/43 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://%HOSTIP:%HTTPPORT/want/data/430002.txt?coolsite=yes HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test5 b/tests/data/test5
index 1331457..b62f1a1 100644
--- a/tests/data/test5
+++ b/tests/data/test5
@@ -43,6 +43,7 @@
 GET http://%HOSTIP:%HTTPPORT/we/want/that/page/5 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test503 b/tests/data/test503
index f02bac6..e8dc21e 100644
--- a/tests/data/test503
+++ b/tests/data/test503
@@ -72,6 +72,7 @@
 CONNECT machine.503:%HTTPPORT HTTP/1.1

 Host: machine.503:%HTTPPORT

 Proxy-Authorization: Basic dGVzdDppbmc=

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test506 b/tests/data/test506
index f1939fe..96e690b 100644
--- a/tests/data/test506
+++ b/tests/data/test506
@@ -41,10 +41,12 @@
 Funny-head: yesyes
 Set-Cookie: test4=overwritten4; domain=host.foo.com; expires=Sat May 5 GMT 11:56:27 2035
 Set-Cookie: test1=overwritten1; domain=foo.com; expires=Thu Mar 3 GMT 11:56:27 2033
+Set-Cookie: test6=six; domain=.www.host.foo.com; expires=Thu Mar 3 GMT 11:56:27 2033
+Set-Cookie: test6=six_more; expires=Thu Mar 3 GMT 11:56:27 2033
 Content-Type: text/html
-Content-Length: 32
+Content-Length: 73
 
-run 3: overwrite cookie 1 and 4
+run 3: overwrite cookie 1 and 4, set cookie 6 with and without tailmatch
 </data3>
 </reply>
 
@@ -166,24 +168,28 @@
 unlock: cookie [Pigs in space]: 61
 lock:   cookie [Pigs in space]: 62
 unlock: cookie [Pigs in space]: 63
-run 3: overwrite cookie 1 and 4
-lock:   dns    [Pigs in space]: 64
-unlock: dns    [Pigs in space]: 65
-CLEANUP
+lock:   cookie [Pigs in space]: 64
+unlock: cookie [Pigs in space]: 65
 lock:   cookie [Pigs in space]: 66
 unlock: cookie [Pigs in space]: 67
-lock:   share  [Pigs in space]: 68
-unlock: share  [Pigs in space]: 69
+run 3: overwrite cookie 1 and 4, set cookie 6 with and without tailmatch
+lock:   dns    [Pigs in space]: 68
+unlock: dns    [Pigs in space]: 69
+CLEANUP
+lock:   cookie [Pigs in space]: 70
+unlock: cookie [Pigs in space]: 71
+lock:   share  [Pigs in space]: 72
+unlock: share  [Pigs in space]: 73
 CURLOPT_SHARE
-lock:   share  [Pigs in space]: 70
-unlock: share  [Pigs in space]: 71
+lock:   share  [Pigs in space]: 74
+unlock: share  [Pigs in space]: 75
 CURLOPT_COOKIELIST ALL
-lock:   cookie [Pigs in space]: 72
-unlock: cookie [Pigs in space]: 73
+lock:   cookie [Pigs in space]: 76
+unlock: cookie [Pigs in space]: 77
 CURLOPT_COOKIEJAR
 CURLOPT_COOKIELIST RELOAD
-lock:   cookie [Pigs in space]: 74
-unlock: cookie [Pigs in space]: 75
+lock:   cookie [Pigs in space]: 78
+unlock: cookie [Pigs in space]: 79
 loaded cookies:
 -----------------
   .host.foo.com	TRUE	/	FALSE	1896263787	injected	yes
@@ -192,19 +198,21 @@
   .foo.com	TRUE	/	FALSE	1896263787	test3	three
   .host.foo.com	TRUE	/	FALSE	2061978987	test4	overwritten4
   .host.foo.com	TRUE	/	FALSE	1896263787	test5	five
+  .www.host.foo.com	TRUE	/	FALSE	1993463787	test6	six
+  www.host.foo.com	FALSE	/	FALSE	1993463787	test6	six_more
 -----------------
 try SHARE_CLEANUP...
-lock:   share  [Pigs in space]: 76
-unlock: share  [Pigs in space]: 77
-SHARE_CLEANUP failed, correct
-CLEANUP
-lock:   cookie [Pigs in space]: 78
-unlock: cookie [Pigs in space]: 79
 lock:   share  [Pigs in space]: 80
 unlock: share  [Pigs in space]: 81
+SHARE_CLEANUP failed, correct
+CLEANUP
+lock:   cookie [Pigs in space]: 82
+unlock: cookie [Pigs in space]: 83
+lock:   share  [Pigs in space]: 84
+unlock: share  [Pigs in space]: 85
 SHARE_CLEANUP
-lock:   share  [Pigs in space]: 82
-unlock: share  [Pigs in space]: 83
+lock:   share  [Pigs in space]: 86
+unlock: share  [Pigs in space]: 87
 GLOBAL_CLEANUP
 </stdout>
 <stderr>
@@ -221,6 +229,8 @@
 .foo.com	TRUE	/	FALSE	1896263787	test3	three
 .host.foo.com	TRUE	/	FALSE	2061978987	test4	overwritten4
 .host.foo.com	TRUE	/	FALSE	1896263787	test5	five
+.www.host.foo.com	TRUE	/	FALSE	1993463787	test6	six
+www.host.foo.com	FALSE	/	FALSE	1993463787	test6	six_more
 </file>
 </verify>
 </testcase>
diff --git a/tests/data/test517 b/tests/data/test517
index c81a45e..513634f 100644
--- a/tests/data/test517
+++ b/tests/data/test517
@@ -116,6 +116,12 @@
 81: 20111323 12:34:56 => -1
 82: 20110623 12:34:79 => -1
 83: Wed, 31 Dec 2008 23:59:60 GMT => 1230768000
+84: 20110623 12:3 => 1308830580
+85: 20110623 1:3 => 1308790980
+86: 20110623 1:30 => 1308792600
+87: 20110623 12:12:3 => 1308831123
+88: 20110623 01:12:3 => 1308791523
+89: 20110623 01:99:30 => -1
 </stdout>
 
 # This test case previously tested an overflow case ("2094 Nov 6 =>
diff --git a/tests/data/test523 b/tests/data/test523
index d021ae3..9abe0ed 100644
--- a/tests/data/test523
+++ b/tests/data/test523
@@ -54,6 +54,7 @@
 Host: www.example.com:19999

 Authorization: Basic eHh4Onl5eQ==

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <stdout>
diff --git a/tests/data/test540 b/tests/data/test540
index 19a13f1..8decaea 100644
--- a/tests/data/test540
+++ b/tests/data/test540
@@ -78,16 +78,19 @@
 GET http://test.remote.example.com/path/540 HTTP/1.1

 Host: custom.set.host.name

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.example.com/path/540 HTTP/1.1

 Host: custom.set.host.name

 Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="/path/540", response="ca507dcf189196b6a5374d3233042261"

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.example.com/path/540 HTTP/1.1

 Host: custom.set.host.name

 Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="/path/540", response="ca507dcf189196b6a5374d3233042261"

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test547 b/tests/data/test547
index 7cf3e91..cee22c6 100644
--- a/tests/data/test547
+++ b/tests/data/test547
@@ -106,6 +106,7 @@
 Host: test.remote.example.com

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

@@ -115,6 +116,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 Content-Type: application/x-www-form-urlencoded

 

@@ -123,6 +125,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test548 b/tests/data/test548
index e9d2262..34cf5e2 100644
--- a/tests/data/test548
+++ b/tests/data/test548
@@ -106,6 +106,7 @@
 Host: test.remote.example.com

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

@@ -115,6 +116,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 Content-Type: application/x-www-form-urlencoded

 

@@ -123,6 +125,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test549 b/tests/data/test549
index 59925ce..a248edb 100644
--- a/tests/data/test549
+++ b/tests/data/test549
@@ -55,6 +55,7 @@
 GET ftp://www.example.com/moo/549;type=i HTTP/1.1

 Host: www.example.com:21

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <stdout>
diff --git a/tests/data/test550 b/tests/data/test550
index 9a717ee..a609aa2 100644
--- a/tests/data/test550
+++ b/tests/data/test550
@@ -55,6 +55,7 @@
 GET ftp://www.example.com/moo/550;type=a HTTP/1.1

 Host: www.example.com:21

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <stdout>
diff --git a/tests/data/test551 b/tests/data/test551
index 6dd0133..ed6aee2 100644
--- a/tests/data/test551
+++ b/tests/data/test551
@@ -81,6 +81,7 @@
 POST http://test.remote.example.com/path/551 HTTP/1.1

 Host: test.remote.example.com

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

@@ -89,6 +90,7 @@
 Host: test.remote.example.com

 Proxy-Authorization: Digest username="s1lly", realm="something fun to read", nonce="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", uri="/path/551", response="3325240726fbdaf1e61f3a0dd40b930c"

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test552 b/tests/data/test552
index c20e204..b44ca34 100644
--- a/tests/data/test552
+++ b/tests/data/test552
Binary files differ
diff --git a/tests/data/test555 b/tests/data/test555
index 6c09e3c..0f3bb07 100644
--- a/tests/data/test555
+++ b/tests/data/test555
@@ -115,6 +115,7 @@
 Host: test.remote.example.com

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

@@ -124,6 +125,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 0

 Content-Type: application/x-www-form-urlencoded

 

@@ -132,6 +134,7 @@
 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 Content-Length: 36

 Content-Type: application/x-www-form-urlencoded

 

diff --git a/tests/data/test558 b/tests/data/test558
index a1ac7d4..27457ff 100644
--- a/tests/data/test558
+++ b/tests/data/test558
@@ -41,8 +41,8 @@
 MEM lib558.c: malloc()
 MEM lib558.c: free()
 MEM escape.c: malloc()
-MEM escape.c: realloc()
-MEM escape.c: realloc()
+MEM strdup.c: realloc()
+MEM strdup.c: realloc()
 MEM escape.c: free()
 </file>
 <stripfile>
diff --git a/tests/data/test561 b/tests/data/test561
index 905e756..a6188ea 100644
--- a/tests/data/test561
+++ b/tests/data/test561
@@ -56,6 +56,7 @@
 GET ftp://www.example.com/moo/561;type=i HTTP/1.1

 Host: www.example.com:21

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 <stdout>
diff --git a/tests/data/test563 b/tests/data/test563
index e4c00f5..7851523 100644
--- a/tests/data/test563
+++ b/tests/data/test563
@@ -50,6 +50,7 @@
 GET FTP://%HOSTIP:%FTPPORT/563;type=A HTTP/1.1

 Host: %HOSTIP:%FTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test590 b/tests/data/test590
index 3341776..55ea4f0 100644
--- a/tests/data/test590
+++ b/tests/data/test590
@@ -104,18 +104,21 @@
 Host: test.remote.example.com

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.example.com/path/590 HTTP/1.1

 Host: test.remote.example.com

 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://test.remote.example.com/path/590 HTTP/1.1

 Host: test.remote.example.com

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAAAgACAPYAAAAIAAgA+AAAAAAAAAAAAAAABoKBAB3Hr6SDn3NDNkgebbaP88ExMjM0MjIzNFIW4N7aYT44bAIg1jt2blUBAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAbWVjdXJsaG9zdA==

 User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test63 b/tests/data/test63
index 2a96449..ccc19dd 100644
--- a/tests/data/test63
+++ b/tests/data/test63
@@ -45,6 +45,7 @@
 Host: we.want.that.site.com

 Proxy-Authorization: Basic ZmFrZTp1c2Vy

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test79 b/tests/data/test79
index 55fc245..b2566e2 100644
--- a/tests/data/test79
+++ b/tests/data/test79
@@ -48,6 +48,7 @@
 GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/79 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test80 b/tests/data/test80
index 8a635b4..147a6aa 100644
--- a/tests/data/test80
+++ b/tests/data/test80
@@ -68,6 +68,7 @@
 Host: test.80:%HTTPPORT

 Proxy-Authorization: Basic eW91YXJlOnlvdXJzZWxm

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test81 b/tests/data/test81
index 53affa0..dc054d2 100644
--- a/tests/data/test81
+++ b/tests/data/test81
@@ -89,12 +89,14 @@
 Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=

 User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 GET http://%HOSTIP:%HTTPPORT/81 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAACeAJ4AWAAAAAAAAAD2AAAACAAIAPYAAAAIAAgA/gAAAAAAAAAAAAAABoKBAL9LNW5+nkyHZRmyFaL/LJ4xMjM0MjIzNGUCyhgQ9hw6eWAT13EbDa0BAQAAAAAAAACAPtXesZ0BMTIzNDIyMzQAAAAAAgAEAEMAQwABABIARQBMAEkAUwBBAEIARQBUAEgABAAYAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAMALABlAGwAaQBzAGEAYgBlAHQAaAAuAGMAYwAuAGkAYwBlAGQAZQB2AC4AbgB1AAAAAAAAAAAAdGVzdHVzZXJjdXJsaG9zdA==

 User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test82 b/tests/data/test82
index de3fcba..8b58f75 100644
--- a/tests/data/test82
+++ b/tests/data/test82
@@ -49,6 +49,7 @@
 Proxy-Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=

 User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test83 b/tests/data/test83
index 4fe8ba3..120bcc6 100644
--- a/tests/data/test83
+++ b/tests/data/test83
@@ -64,6 +64,7 @@
 CONNECT test.83:%HTTPPORT HTTP/1.1

 Host: test.83:%HTTPPORT

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol>
diff --git a/tests/data/test84 b/tests/data/test84
index cf667d6..629dae2 100644
--- a/tests/data/test84
+++ b/tests/data/test84
@@ -47,6 +47,7 @@
 Authorization: Basic aWFtOm15c2VsZg==

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test85 b/tests/data/test85
index a11363f..cb5e6e0 100644
--- a/tests/data/test85
+++ b/tests/data/test85
@@ -51,6 +51,7 @@
 Authorization: Basic aWFtOm15c2VsZg==

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test864 b/tests/data/test864
index 9ad98f7..ebdebd6 100644
--- a/tests/data/test864
+++ b/tests/data/test864
@@ -11,7 +11,7 @@
 <reply>
 <servercmd>
 CAPA APOP
-REPLY welcome +OK cURL POP3 server ready to serve <1972.987654321\@curl>
+REPLY welcome +OK curl POP3 server ready to serve <1972.987654321\@curl>
 </servercmd>
 <data>
 From: me@somewhere

diff --git a/tests/data/test93 b/tests/data/test93
index 948d29c..1387248 100644
--- a/tests/data/test93
+++ b/tests/data/test93
@@ -43,6 +43,7 @@
 GET http://%HOSTIP:%HTTPPORT/93 HTTP/1.1

 Host: %HOSTIP:%HTTPPORT

 Accept: */*

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test94 b/tests/data/test94
index 94c894c..2f3f482 100644
--- a/tests/data/test94
+++ b/tests/data/test94
@@ -51,6 +51,7 @@
 CONNECT test.anything.really.com:94 HTTP/1.0

 User-Agent: curl/7.11.0-CVS (i686-pc-linux-gnu) libcurl/7.11.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4

 Host: test.anything.really.com:94

+Proxy-Connection: Keep-Alive

 

 </protocol>
 </verify>
diff --git a/tests/data/test95 b/tests/data/test95
index 2b3e2c2..1cd88ac 100644
--- a/tests/data/test95
+++ b/tests/data/test95
@@ -64,6 +64,7 @@
 CONNECT test.95:%HTTPPORT HTTP/1.1

 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3

 Host: test.95:%HTTPPORT

+Proxy-Connection: Keep-Alive

 

 </proxy>
 <protocol nonewline="yes">
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index 01a7df8..081298f 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -609,7 +609,7 @@
             '   / __| | | | |_) | |    '."\r\n",
             '  | (__| |_| |  _ {| |___ '."\r\n",
             '   \___|\___/|_| \_\_____|'."\r\n",
-            '+OK cURL POP3 server ready to serve '."\r\n")
+            '+OK curl POP3 server ready to serve '."\r\n")
         );
     }
     elsif($proto eq 'imap') {
@@ -643,7 +643,7 @@
             '   / __| | | | |_) | |    '."\r\n",
             '  | (__| |_| |  _ {| |___ '."\r\n",
             '   \___|\___/|_| \_\_____|'."\r\n",
-            '* OK cURL IMAP server ready to serve'."\r\n")
+            '* OK curl IMAP server ready to serve'."\r\n")
         );
     }
     elsif($proto eq 'smtp') {
@@ -1057,7 +1057,7 @@
 }
 
 sub QUIT_smtp {
-    sendcontrol "221 cURL $smtp_type server signing off\r\n";
+    sendcontrol "221 curl $smtp_type server signing off\r\n";
 
     return 0;
 }
@@ -1605,7 +1605,7 @@
 }
 
 sub LOGOUT_imap {
-    sendcontrol "* BYE cURL IMAP server signing off\r\n";
+    sendcontrol "* BYE curl IMAP server signing off\r\n";
     sendcontrol "$cmdid OK LOGOUT completed\r\n";
 
     return 0;
@@ -1941,7 +1941,7 @@
         @deleted = ();
     }
 
-    sendcontrol "+OK cURL POP3 server signing off\r\n";
+    sendcontrol "+OK curl POP3 server signing off\r\n";
 
     return 0;
 }
diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt
index cc9d7e1..a7449c3 100644
--- a/tests/libtest/CMakeLists.txt
+++ b/tests/libtest/CMakeLists.txt
@@ -43,6 +43,10 @@
   # library at (tests)/libtest/.libs/libhostname.so
   set_target_properties(hostname PROPERTIES
       LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.libs)
+  if(HIDES_CURL_PRIVATE_SYMBOLS)
+    set_property(TARGET hostname APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
+    set_property(TARGET hostname APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
+  endif()
 endif()
 
 # # files used only in some libcurl test programs
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 7ae66d7..c1dc2f5 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -23,7 +23,8 @@
  lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \
  lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515         lib1517 \
  lib1520 \
- lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 \
+ lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 lib1533 \
+ lib1534 \
  lib1900 \
  lib2033
 
@@ -391,6 +392,18 @@
 lib1531_LDADD = $(TESTUTIL_LIBS)
 lib1531_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1531
 
+lib1532_SOURCES = lib1532.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1532_LDADD = $(TESTUTIL_LIBS)
+lib1532_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1532
+
+lib1533_SOURCES = lib1533.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1533_LDADD = $(TESTUTIL_LIBS)
+lib1533_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1533
+
+lib1534_SOURCES = lib1534.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1534_LDADD = $(TESTUTIL_LIBS)
+lib1534_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1534
+
 lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
 lib1900_LDADD = $(TESTUTIL_LIBS)
 lib1900_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/tests/libtest/lib1500.c b/tests/libtest/lib1500.c
index f3c4958..73d23a1 100644
--- a/tests/libtest/lib1500.c
+++ b/tests/libtest/lib1500.c
@@ -29,8 +29,8 @@
 
 int test(char *URL)
 {
-  CURL* curls = NULL;
-  CURLM* multi = NULL;
+  CURL *curls = NULL;
+  CURLM *multi = NULL;
   int still_running;
   int i = TEST_ERR_FAILURE;
   int res = 0;
diff --git a/tests/libtest/lib1502.c b/tests/libtest/lib1502.c
index e4e1a16..bd555cb 100644
--- a/tests/libtest/lib1502.c
+++ b/tests/libtest/lib1502.c
@@ -41,8 +41,8 @@
 
 int test(char *URL)
 {
-  CURL* easy = NULL;
-  CURLM* multi = NULL;
+  CURL *easy = NULL;
+  CURLM *multi = NULL;
   int still_running;
   int res = 0;
 
diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c
index 5a7994e..7ab3057 100644
--- a/tests/libtest/lib1507.c
+++ b/tests/libtest/lib1507.c
@@ -68,7 +68,7 @@
    CURLM *mcurl = NULL;
    int still_running = 1;
    struct timeval mp_start;
-   struct curl_slist* rcpt_list = NULL;
+   struct curl_slist *rcpt_list = NULL;
 
    curl_global_init(CURL_GLOBAL_DEFAULT);
 
diff --git a/tests/libtest/lib1511.c b/tests/libtest/lib1511.c
index bec3167..e1840e7 100644
--- a/tests/libtest/lib1511.c
+++ b/tests/libtest/lib1511.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,7 +26,7 @@
 int test(char *URL)
 {
   long unmet;
-  CURL* curl = NULL;
+  CURL *curl = NULL;
   int res = 0;
 
   global_init(CURL_GLOBAL_ALL);
diff --git a/tests/libtest/lib1515.c b/tests/libtest/lib1515.c
index 2fd19bb..aeaf6b2 100644
--- a/tests/libtest/lib1515.c
+++ b/tests/libtest/lib1515.c
@@ -113,7 +113,7 @@
 
 int test(char *URL)
 {
-  CURLM* multi = NULL;
+  CURLM *multi = NULL;
   int res = 0;
   char *address = libtest_arg2;
   char *port = libtest_arg3;
diff --git a/tests/libtest/lib1532.c b/tests/libtest/lib1532.c
new file mode 100644
index 0000000..4a3ff32
--- /dev/null
+++ b/tests/libtest/lib1532.c
@@ -0,0 +1,80 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, 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 "memdebug.h"
+
+/* Test CURLINFO_RESPONSE_CODE */
+
+int test(char *URL)
+{
+  CURL *curl;
+  long httpcode;
+  int res = CURLE_OK;
+
+  global_init(CURL_GLOBAL_ALL);
+
+  easy_init(curl);
+
+  easy_setopt(curl, CURLOPT_URL, URL);
+
+  res = curl_easy_perform(curl);
+  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;
+  }
+
+  res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(httpcode != 200) {
+    fprintf(stderr, "%s:%d unexpected response code %ld\n",
+            __FILE__, __LINE__, httpcode);
+    res = CURLE_HTTP_RETURNED_ERROR;
+    goto test_cleanup;
+  }
+
+  /* Test for a regression of github bug 1017 (response code does not reset) */
+  curl_easy_reset(curl);
+
+  res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(httpcode != 0) {
+    fprintf(stderr, "%s:%d curl_easy_reset failed to zero the response code\n"
+            "possible regression of github bug 1017\n", __FILE__, __LINE__);
+    res = CURLE_HTTP_RETURNED_ERROR;
+    goto test_cleanup;
+  }
+
+test_cleanup:
+  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+  return res;
+}
diff --git a/tests/libtest/lib1533.c b/tests/libtest/lib1533.c
new file mode 100644
index 0000000..de403e1
--- /dev/null
+++ b/tests/libtest/lib1533.c
@@ -0,0 +1,199 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, 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 test sends data with CURLOPT_KEEP_SENDING_ON_ERROR.
+ * The server responds with an early error response.
+ * The test is successful if the connection can be reused for the next request,
+ * because this implies that the data has been sent completely to the server.
+ */
+
+#include "test.h"
+
+#include "memdebug.h"
+
+struct cb_data {
+  CURL *easy_handle;
+  int response_received;
+  int paused;
+  size_t remaining_bytes;
+};
+
+
+static void reset_data(struct cb_data *data, CURL *curl)
+{
+  data->easy_handle = curl;
+  data->response_received = 0;
+  data->paused = 0;
+  data->remaining_bytes = 3;
+}
+
+
+static size_t read_callback(void *ptr, size_t size, size_t nitems,
+                            void *userdata)
+{
+  struct cb_data *data = (struct cb_data *)userdata;
+
+  /* wait until the server has sent all response headers */
+  if(data->response_received) {
+    size_t totalsize = nitems * size;
+
+    size_t bytes_to_send = data->remaining_bytes;
+    if(bytes_to_send > totalsize) {
+      bytes_to_send = totalsize;
+    }
+
+    memset(ptr, 'a', bytes_to_send);
+    data->remaining_bytes -= bytes_to_send;
+
+    return bytes_to_send;
+  }
+  else {
+    data->paused = 1;
+    return CURL_READFUNC_PAUSE;
+  }
+}
+
+
+static size_t write_callback(char *ptr, size_t size, size_t nmemb,
+                             void *userdata)
+{
+  struct cb_data *data = (struct cb_data *)userdata;
+  size_t totalsize = nmemb * size;
+
+  /* unused parameter */
+  (void)ptr;
+
+  /* all response headers have been received */
+  data->response_received = 1;
+
+  if(data->paused) {
+    /* continue to send request body data */
+    data->paused = 0;
+    curl_easy_pause(data->easy_handle, CURLPAUSE_CONT);
+  }
+
+  return totalsize;
+}
+
+
+static int perform_and_check_connections(CURL *curl, const char *description,
+                                         long expected_connections)
+{
+  CURLcode res;
+  long connections = 0;
+
+  res = curl_easy_perform(curl);
+  if(res != CURLE_OK) {
+    fprintf(stderr, "curl_easy_perform() failed\n");
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  res = curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &connections);
+  if(res != CURLE_OK) {
+    fprintf(stderr, "curl_easy_getinfo() failed\n");
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  fprintf(stderr, "%s: expected: %ld connections; actual: %ld connections\n",
+          description, expected_connections, connections);
+
+  if(connections != expected_connections) {
+    return TEST_ERR_FAILURE;
+  }
+
+  return TEST_ERR_SUCCESS;
+}
+
+
+int test(char *URL)
+{
+  struct cb_data data;
+  CURL *curl = NULL;
+  CURLcode res = CURLE_FAILED_INIT;
+
+  if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+    fprintf(stderr, "curl_global_init() failed\n");
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  if((curl = curl_easy_init()) == NULL) {
+    fprintf(stderr, "curl_easy_init() failed\n");
+    curl_global_cleanup();
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  reset_data(&data, curl);
+
+  test_setopt(curl, CURLOPT_URL, URL);
+  test_setopt(curl, CURLOPT_POST, 1L);
+  test_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
+              (curl_off_t)data.remaining_bytes);
+  test_setopt(curl, CURLOPT_VERBOSE, 1L);
+  test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+  test_setopt(curl, CURLOPT_READDATA, &data);
+  test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+  test_setopt(curl, CURLOPT_WRITEDATA, &data);
+
+  res = perform_and_check_connections(curl,
+    "First request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
+  if(res != TEST_ERR_SUCCESS) {
+    goto test_cleanup;
+  }
+
+  reset_data(&data, curl);
+
+  res = perform_and_check_connections(curl,
+    "Second request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
+  if(res != TEST_ERR_SUCCESS) {
+    goto test_cleanup;
+  }
+
+  test_setopt(curl, CURLOPT_KEEP_SENDING_ON_ERROR, 1L);
+
+  reset_data(&data, curl);
+
+  res = perform_and_check_connections(curl,
+    "First request with CURLOPT_KEEP_SENDING_ON_ERROR", 1);
+  if(res != TEST_ERR_SUCCESS) {
+    goto test_cleanup;
+  }
+
+  reset_data(&data, curl);
+
+  res = perform_and_check_connections(curl,
+    "Second request with CURLOPT_KEEP_SENDING_ON_ERROR", 0);
+  if(res != TEST_ERR_SUCCESS) {
+    goto test_cleanup;
+  }
+
+  res = TEST_ERR_SUCCESS;
+
+test_cleanup:
+
+  curl_easy_cleanup(curl);
+
+  curl_global_cleanup();
+
+  return (int)res;
+}
+
diff --git a/tests/libtest/lib1534.c b/tests/libtest/lib1534.c
new file mode 100644
index 0000000..61e72ab
--- /dev/null
+++ b/tests/libtest/lib1534.c
@@ -0,0 +1,129 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, 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 "memdebug.h"
+
+/* Test CURLINFO_FILETIME */
+
+int test(char *URL)
+{
+  CURL *curl, *dupe = NULL;
+  long filetime;
+  int res = CURLE_OK;
+
+  global_init(CURL_GLOBAL_ALL);
+
+  easy_init(curl);
+
+  /* Test that a filetime is properly initialized on curl_easy_init.
+  */
+
+  res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(filetime != -1) {
+    fprintf(stderr, "%s:%d filetime init failed; expected -1 but is %ld\n",
+            __FILE__, __LINE__, filetime);
+    res = CURLE_FAILED_INIT;
+    goto test_cleanup;
+  }
+
+  easy_setopt(curl, CURLOPT_URL, URL);
+  easy_setopt(curl, CURLOPT_FILETIME, 1L);
+
+  res = curl_easy_perform(curl);
+  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 that a filetime is properly set after receiving an HTTP resource.
+  */
+
+  res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(filetime != 30) {
+    fprintf(stderr, "%s:%d filetime of http resource is incorrect; "
+            "expected 30 but is %ld\n",
+            __FILE__, __LINE__, filetime);
+    res = CURLE_HTTP_RETURNED_ERROR;
+    goto test_cleanup;
+  }
+
+  /* Test that a filetime is properly initialized on curl_easy_duphandle.
+  */
+
+  dupe = curl_easy_duphandle(curl);
+  if(!dupe) {
+    fprintf(stderr, "%s:%d curl_easy_duphandle() failed\n",
+            __FILE__, __LINE__);
+    res = CURLE_FAILED_INIT;
+    goto test_cleanup;
+  }
+
+  res = curl_easy_getinfo(dupe, CURLINFO_FILETIME, &filetime);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(filetime != -1) {
+    fprintf(stderr, "%s:%d filetime init failed; expected -1 but is %ld\n",
+            __FILE__, __LINE__, filetime);
+    res = CURLE_FAILED_INIT;
+    goto test_cleanup;
+  }
+
+
+  /* Test that a filetime is properly initialized on curl_easy_reset.
+  */
+
+  curl_easy_reset(curl);
+
+  res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
+  if(res) {
+    fprintf(stderr, "%s:%d curl_easy_getinfo() failed with code %d (%s)\n",
+            __FILE__, __LINE__, res, curl_easy_strerror(res));
+    goto test_cleanup;
+  }
+  if(filetime != -1) {
+    fprintf(stderr, "%s:%d filetime init failed; expected -1 but is %ld\n",
+            __FILE__, __LINE__, filetime);
+    res = CURLE_FAILED_INIT;
+    goto test_cleanup;
+  }
+
+test_cleanup:
+  curl_easy_cleanup(curl);
+  curl_easy_cleanup(dupe);
+  curl_global_cleanup();
+  return res;
+}
diff --git a/tests/libtest/lib507.c b/tests/libtest/lib507.c
index 7487992..ebe897a 100644
--- a/tests/libtest/lib507.c
+++ b/tests/libtest/lib507.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,8 +29,8 @@
 
 int test(char *URL)
 {
-  CURL* curls = NULL;
-  CURLM* multi = NULL;
+  CURL *curls = NULL;
+  CURLM *multi = NULL;
   int still_running;
   int i = -1;
   int res = 0;
diff --git a/tests/libtest/lib517.c b/tests/libtest/lib517.c
index 2f68ebd..22162ff 100644
--- a/tests/libtest/lib517.c
+++ b/tests/libtest/lib517.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -116,6 +116,12 @@
   "20111323 12:34:56",
   "20110623 12:34:79",
   "Wed, 31 Dec 2008 23:59:60 GMT", /* leap second */
+  "20110623 12:3",
+  "20110623 1:3",
+  "20110623 1:30",
+  "20110623 12:12:3",
+  "20110623 01:12:3",
+  "20110623 01:99:30",
   NULL
 };
 
diff --git a/tests/libtest/lib539.c b/tests/libtest/lib539.c
index 9f0f8fa..ec4ea53 100644
--- a/tests/libtest/lib539.c
+++ b/tests/libtest/lib539.c
@@ -42,7 +42,7 @@
    }
 
    /*
-    * Begin with cURL set to use a single CWD to the URL's directory.
+    * Begin with curl set to use a single CWD to the URL's directory.
     */
    test_setopt(curl, CURLOPT_URL, URL);
    test_setopt(curl, CURLOPT_VERBOSE, 1L);
@@ -53,7 +53,7 @@
    /*
     * Change the FTP_FILEMETHOD option to use full paths rather than a CWD
     * command.  Alter the URL's path a bit, appending a "./".  Use an innocuous
-    * QUOTE command, after which cURL will CWD to ftp_conn->entrypath and then
+    * QUOTE command, after which curl will CWD to ftp_conn->entrypath and then
     * (on the next call to ftp_statemach_act) find a non-zero ftpconn->dirdepth
     * even though no directories are stored in the ftpconn->dirs array (after a
     * call to freedirs).
diff --git a/tests/libtest/lib540.c b/tests/libtest/lib540.c
index 9b3b5a4..f5d89c4 100644
--- a/tests/libtest/lib540.c
+++ b/tests/libtest/lib540.c
@@ -48,7 +48,7 @@
 
 CURL *eh[NUM_HANDLES];
 
-static int init(int num, CURLM *cm, const char* url, const char* userpwd,
+static int init(int num, CURLM *cm, const char *url, const char *userpwd,
                 struct curl_slist *headers)
 {
   int res = 0;
@@ -99,7 +99,7 @@
   return res; /* failure */
 }
 
-static int loop(int num, CURLM *cm, const char* url, const char* userpwd,
+static int loop(int num, CURLM *cm, const char *url, const char *userpwd,
                 struct curl_slist *headers)
 {
   CURLMsg *msg;
diff --git a/tests/libtest/lib543.c b/tests/libtest/lib543.c
index 8fec052..90aed21 100644
--- a/tests/libtest/lib543.c
+++ b/tests/libtest/lib543.c
@@ -43,7 +43,7 @@
 
   asize = (int)sizeof(a);
 
-  s = curl_easy_escape(easy, (char*)a, asize);
+  s = curl_easy_escape(easy, (char *)a, asize);
 
   if(s)
     printf("%s\n", s);
diff --git a/tests/libtest/lib552.c b/tests/libtest/lib552.c
index 9fe4a71..94c9325 100644
--- a/tests/libtest/lib552.c
+++ b/tests/libtest/lib552.c
@@ -147,7 +147,7 @@
 }
 
 
-static curlioerr ioctl_callback(CURL * handle, int cmd, void *clientp)
+static curlioerr ioctl_callback(CURL *handle, int cmd, void *clientp)
 {
   (void)clientp;
   if(cmd == CURLIOCMD_RESTARTREAD) {
diff --git a/tests/libtest/lib557.c b/tests/libtest/lib557.c
index 5bdb8ab..683ca08 100644
--- a/tests/libtest/lib557.c
+++ b/tests/libtest/lib557.c
@@ -1422,11 +1422,115 @@
   return errors;
 }
 
+static int test_weird_arguments(void)
+{
+  int errors = 0;
+  char buf[256];
+  int rc;
+
+  /* MAX_PARAMETERS is 128, try exact 128! */
+  rc = curl_msnprintf(buf, sizeof(buf),
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 1 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 2 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 3 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 4 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 5 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 6 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 7 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 8 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 9 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 10 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 11 */
+                      "%d%d%d%d%d%d%d%d"     /* 8 */
+                      ,
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 1 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 2 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 3 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 4 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 5 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 6 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 7 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 8 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 9 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 10 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 11 */
+                      0, 1, 2, 3, 4, 5, 6, 7); /* 8 */
+
+  if(rc != 128) {
+    printf("curl_mprintf() returned %d and not 128!\n", rc);
+    errors++;
+  }
+
+  errors += string_check(buf,
+                         "0123456789" /* 10 */
+                         "0123456789" /* 10 1 */
+                         "0123456789" /* 10 2 */
+                         "0123456789" /* 10 3 */
+                         "0123456789" /* 10 4 */
+                         "0123456789" /* 10 5 */
+                         "0123456789" /* 10 6 */
+                         "0123456789" /* 10 7 */
+                         "0123456789" /* 10 8 */
+                         "0123456789" /* 10 9 */
+                         "0123456789" /* 10 10*/
+                         "0123456789" /* 10 11 */
+                         "01234567"   /* 8 */
+    );
+
+  /* MAX_PARAMETERS is 128, try more! */
+  buf[0] = 0;
+  rc = curl_msnprintf(buf, sizeof(buf),
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 1 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 2 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 3 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 4 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 5 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 6 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 7 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 8 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 9 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 10 */
+                      "%d%d%d%d%d%d%d%d%d%d" /* 10 11 */
+                      "%d%d%d%d%d%d%d%d%d"   /* 9 */
+                      ,
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 1 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 2 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 3 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 4 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 5 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 6 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 7 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 8 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 9 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 10 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 10 11 */
+                      0, 1, 2, 3, 4, 5, 6, 7, 8);   /* 9 */
+
+  if(rc != -1) {
+    printf("curl_mprintf() returned %d and not -1!\n", rc);
+    errors++;
+  }
+
+  errors += string_check(buf, "");
+
+  if(errors)
+    printf("Some curl_mprintf() weird arguments tests failed!\n");
+
+  return errors;
+}
+
+
 int test(char *URL)
 {
   int errors = 0;
   (void)URL; /* not used */
 
+  errors += test_weird_arguments();
+
   errors += test_unsigned_short_formatting();
 
   errors += test_signed_short_formatting();
diff --git a/tests/libtest/lib571.c b/tests/libtest/lib571.c
index ad6c366..32648ad 100644
--- a/tests/libtest/lib571.c
+++ b/tests/libtest/lib571.c
@@ -50,7 +50,8 @@
 
 static int rtp_packet_count = 0;
 
-static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *stream) {
+static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *stream)
+{
   char *data = (char *)ptr;
   int channel = RTP_PKT_CHANNEL(data);
   int message_size;
diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c
index 444b416..eec0455 100644
--- a/tests/libtest/lib582.c
+++ b/tests/libtest/lib582.c
@@ -145,10 +145,10 @@
 /**
  * Check for curl completion.
  */
-static int checkForCompletion(CURLM* curl, int* success)
+static int checkForCompletion(CURLM *curl, int *success)
 {
   int numMessages;
-  CURLMsg* message;
+  CURLMsg *message;
   int result = 0;
   *success = 0;
   while((message = curl_multi_info_read(curl, &numMessages)) != NULL) {
diff --git a/tests/libtest/lib583.c b/tests/libtest/lib583.c
index 9af48d2..5b11fab 100644
--- a/tests/libtest/lib583.c
+++ b/tests/libtest/lib583.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,8 +33,8 @@
 int test(char *URL)
 {
   int stillRunning;
-  CURLM* multiHandle = NULL;
-  CURL* curl = NULL;
+  CURLM *multiHandle = NULL;
+  CURL *curl = NULL;
   int res = 0;
 
   global_init(CURL_GLOBAL_ALL);
diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c
index 994f9de..065a79d 100644
--- a/tests/libtest/libauthretry.c
+++ b/tests/libtest/libauthretry.c
@@ -25,7 +25,6 @@
  */
 
 #include "test.h"
-#include "strequal.h"
 #include "memdebug.h"
 
 static CURLcode send_request(CURL *curl, const char *url, int seq,
@@ -33,7 +32,7 @@
 {
   CURLcode res;
   size_t len = strlen(url) + 4 + 1;
-  char* full_url = malloc(len);
+  char *full_url = malloc(len);
   if(!full_url) {
     fprintf(stderr, "Not enough memory for full url\n");
     return CURLE_OUT_OF_MEMORY;
@@ -72,11 +71,11 @@
 {
   if(!arg)
     return CURLAUTH_NONE;
-  if(strequal(arg, "basic"))
+  if(curl_strequal(arg, "basic"))
     return CURLAUTH_BASIC;
-  if(strequal(arg, "digest"))
+  if(curl_strequal(arg, "digest"))
     return CURLAUTH_DIGEST;
-  if(strequal(arg, "ntlm"))
+  if(curl_strequal(arg, "ntlm"))
     return CURLAUTH_NTLM;
   return CURLAUTH_NONE;
 }
diff --git a/tests/libtest/libntlmconnect.c b/tests/libtest/libntlmconnect.c
index 736222d..40a837c 100644
--- a/tests/libtest/libntlmconnect.c
+++ b/tests/libtest/libntlmconnect.c
@@ -37,7 +37,7 @@
 static curl_socket_t sockets[MAX_EASY_HANDLES];
 static int res = 0;
 
-static size_t callback(char* ptr, size_t size, size_t nmemb, void* data)
+static size_t callback(char *ptr, size_t size, size_t nmemb, void *data)
 {
   ssize_t idx = ((CURL **) data) - easy;
   curl_socket_t sock;
@@ -104,7 +104,7 @@
   int num_handles = 0;
   enum HandleState state = ReadyForNewHandle;
   size_t urllen = strlen(url) + 4 + 1;
-  char* full_url = malloc(urllen);
+  char *full_url = malloc(urllen);
 
   start_test_timing();
 
diff --git a/tests/libtest/test.h b/tests/libtest/test.h
index 9647658..9fd33aa 100644
--- a/tests/libtest/test.h
+++ b/tests/libtest/test.h
@@ -112,7 +112,7 @@
 ** label 'test_cleanup' is performed.
 **
 ** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro
-** counterpart that operates in tha same way with the exception that no
+** counterpart that operates in the same way with the exception that no
 ** jump takes place in case of failure. res_easy_* and res_multi_* macros
 ** should be immediately followed by checking if 'res' variable has been
 ** set.
diff --git a/tests/pathhelp.pm b/tests/pathhelp.pm
index 391ef6c..10a87aa 100644
--- a/tests/pathhelp.pm
+++ b/tests/pathhelp.pm
@@ -20,7 +20,7 @@
 #
 ###########################################################################
 
-# This Perl package helps with path transforming when running cURL tests on
+# This Perl package helps with path transforming when running curl tests on
 # Win32 platform with Msys or Cygwin.
 # Three main functions 'sys_native_abs_path', 'sys_native_path' and
 # 'build_sys_abs_path' autodetect format of given pathnames. Following formats
diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc
index 6e81dfd..c3ea664 100644
--- a/tests/server/Makefile.inc
+++ b/tests/server/Makefile.inc
@@ -3,7 +3,6 @@
 CURLX_SRCS = \
  ../../lib/mprintf.c \
  ../../lib/nonblock.c \
- ../../lib/strequal.c \
  ../../lib/strtoofft.c \
  ../../lib/timeval.c \
  ../../lib/warnless.c
@@ -11,7 +10,6 @@
 CURLX_HDRS = \
  ../../lib/curlx.h \
  ../../lib/nonblock.h \
- ../../lib/strequal.h \
  ../../lib/strtoofft.h \
  ../../lib/timeval.h \
  ../../lib/warnless.h
diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c
index 91ef6c6..e759e88 100644
--- a/tests/server/rtspd.c
+++ b/tests/server/rtspd.c
@@ -129,7 +129,7 @@
 
 const char *serverlogfile = DEFAULT_LOGFILE;
 
-#define RTSPDVERSION "cURL test suite RTSP server/0.1"
+#define RTSPDVERSION "curl test suite RTSP server/0.1"
 
 #define REQUEST_DUMP  "log/server.input"
 #define RESPONSE_DUMP "log/server.response"
@@ -590,7 +590,7 @@
     if(got_exit_signal)
       return 1; /* done */
 
-    if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) {
+    if((req->cl==0) && strncasecompare("Content-Length:", line, 15)) {
       /* If we don't ignore content-length, we read it and we read the whole
          request including the body before we return. If we've been told to
          ignore the content-length, we will return as soon as all headers
@@ -616,7 +616,7 @@
         logmsg("... but will abort after %zu bytes", req->cl);
       break;
     }
-    else if(curlx_strnequal("Transfer-Encoding: chunked", line,
+    else if(strncasecompare("Transfer-Encoding: chunked", line,
                             strlen("Transfer-Encoding: chunked"))) {
       /* chunked data coming in */
       chunked = TRUE;
diff --git a/tests/server/sws.c b/tests/server/sws.c
index 27c86e0..af0904e 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -140,7 +140,7 @@
 
 const char *serverlogfile = DEFAULT_LOGFILE;
 
-#define SWSVERSION "cURL test suite HTTP server/0.1"
+#define SWSVERSION "curl test suite HTTP server/0.1"
 
 #define REQUEST_DUMP  "log/server.input"
 #define RESPONSE_DUMP "log/server.response"
@@ -697,7 +697,7 @@
     if(got_exit_signal)
       return 1; /* done */
 
-    if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) {
+    if((req->cl==0) && strncasecompare("Content-Length:", line, 15)) {
       /* If we don't ignore content-length, we read it and we read the whole
          request including the body before we return. If we've been told to
          ignore the content-length, we will return as soon as all headers
@@ -723,7 +723,7 @@
         logmsg("... but will abort after %zu bytes", req->cl);
       break;
     }
-    else if(curlx_strnequal("Transfer-Encoding: chunked", line,
+    else if(strncasecompare("Transfer-Encoding: chunked", line,
                             strlen("Transfer-Encoding: chunked"))) {
       /* chunked data coming in */
       chunked = TRUE;
@@ -2231,9 +2231,9 @@
     /* Clear out closed sockets */
     for(socket_idx = num_sockets - 1; socket_idx >= 1; --socket_idx) {
       if(CURL_SOCKET_BAD == all_sockets[socket_idx]) {
-        char* dst = (char *) (all_sockets + socket_idx);
-        char* src = (char *) (all_sockets + socket_idx + 1);
-        char* end = (char *) (all_sockets + num_sockets);
+        char *dst = (char *) (all_sockets + socket_idx);
+        char *src = (char *) (all_sockets + socket_idx + 1);
+        char *end = (char *) (all_sockets + num_sockets);
         memmove(dst, src, end - src);
         num_sockets -= 1;
       }
diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c
index afc0884..8a4ed0b 100644
--- a/tests/server/tftpd.c
+++ b/tests/server/tftpd.c
@@ -15,7 +15,7 @@
  */
 
 /*
- * Copyright (c) 1983 Regents of the University of California.
+ * Copyright (c) 1983, 2016 Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1040,10 +1040,10 @@
 #ifdef USE_WINSOCK
   recvtimeout = sizeof(recvtimeoutbak);
   getsockopt(peer, SOL_SOCKET, SO_RCVTIMEO,
-             (char*)&recvtimeoutbak, (int*)&recvtimeout);
+             (char *)&recvtimeoutbak, (int *)&recvtimeout);
   recvtimeout = TIMEOUT*1000;
   setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO,
-             (const char*)&recvtimeout, sizeof(recvtimeout));
+             (const char *)&recvtimeout, sizeof(recvtimeout));
 #endif
 
   if(tp->th_opcode == opcode_WRQ)
@@ -1054,7 +1054,7 @@
 #ifdef USE_WINSOCK
   recvtimeout = recvtimeoutbak;
   setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO,
-             (const char*)&recvtimeout, sizeof(recvtimeout));
+             (const char *)&recvtimeout, sizeof(recvtimeout));
 #endif
 
   return 0;
@@ -1232,19 +1232,17 @@
 {
   int size;
   ssize_t n;
-  /* This is volatile to live through a siglongjmp */
+  /* These are volatile to live through a siglongjmp */
   volatile unsigned short sendblock; /* block count */
-  struct tftphdr *sdp;      /* data buffer */
-  struct tftphdr *sap;      /* ack buffer */
+  struct tftphdr * volatile sdp = r_init(); /* data buffer */
+  struct tftphdr * const sap = &ackbuf.hdr; /* ack buffer */
 
   sendblock = 1;
 #if defined(HAVE_ALARM) && defined(SIGALRM)
   mysignal(SIGALRM, timer);
 #endif
-  sdp = r_init();
-  sap = &ackbuf.hdr;
   do {
-    size = readit(test, &sdp, pf->f_convert);
+    size = readit(test, (struct tftphdr **)&sdp, pf->f_convert);
     if(size < 0) {
       nak(errno + 100);
       return;
diff --git a/tests/server/util.c b/tests/server/util.c
index d993363..e654707 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -305,3 +305,87 @@
     logmsg("Error removing lock file %s error: %d %s",
            filename, error, strerror(error));
 }
+
+
+/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
+   its behavior is altered by the current locale. */
+static char raw_toupper(char in)
+{
+#if !defined(CURL_DOES_CONVERSIONS)
+  if(in >= 'a' && in <= 'z')
+    return (char)('A' + in - 'a');
+#else
+  switch (in) {
+  case 'a':
+    return 'A';
+  case 'b':
+    return 'B';
+  case 'c':
+    return 'C';
+  case 'd':
+    return 'D';
+  case 'e':
+    return 'E';
+  case 'f':
+    return 'F';
+  case 'g':
+    return 'G';
+  case 'h':
+    return 'H';
+  case 'i':
+    return 'I';
+  case 'j':
+    return 'J';
+  case 'k':
+    return 'K';
+  case 'l':
+    return 'L';
+  case 'm':
+    return 'M';
+  case 'n':
+    return 'N';
+  case 'o':
+    return 'O';
+  case 'p':
+    return 'P';
+  case 'q':
+    return 'Q';
+  case 'r':
+    return 'R';
+  case 's':
+    return 'S';
+  case 't':
+    return 'T';
+  case 'u':
+    return 'U';
+  case 'v':
+    return 'V';
+  case 'w':
+    return 'W';
+  case 'x':
+    return 'X';
+  case 'y':
+    return 'Y';
+  case 'z':
+    return 'Z';
+  }
+#endif
+
+  return in;
+}
+
+int strncasecompare(const char *first, const char *second, size_t max)
+{
+  while(*first && *second && max) {
+    if(raw_toupper(*first) != raw_toupper(*second)) {
+      break;
+    }
+    max--;
+    first++;
+    second++;
+  }
+  if(0 == max)
+    return 1; /* they are equal this far */
+
+  return raw_toupper(*first) == raw_toupper(*second);
+}
diff --git a/tests/server/util.h b/tests/server/util.h
index 2a19a61..c90fcdf 100644
--- a/tests/server/util.h
+++ b/tests/server/util.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,4 +63,6 @@
 
 void clear_advisor_read_lock(const char *filename);
 
+int strncasecompare(const char *first, const char *second, size_t max);
+
 #endif  /* HEADER_CURL_SERVER_UTIL_H */
diff --git a/tests/testcurl.1 b/tests/testcurl.1
index 509f5dc..ee07d64 100644
--- a/tests/testcurl.1
+++ b/tests/testcurl.1
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2016, 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 @@
 mailed to curl-autocompile@haxx.se to be dealt with automatically (make sure
 the subject includes the word "autobuild" as the mail gets silently discarded
 otherwise).  The most current build status (with a reasonable backlog) will be
-published on the curl site, at https://curl.haxx.se/auto/
+published on the curl site, at https://curl.haxx.se/dev/builds.html
 
 \fIoptions\fP may be omitted. See \fI--setup\fP for what happens then.
 
@@ -78,13 +78,13 @@
 \&'borland' and 'netware'.
 .SH "INITIAL SETUP"
 First you make a checkout from git (or you write a script that downloads daily
-snapshots automatically, find inspiration at
-https://curl.haxx.se/auto/autocurl.txt):
+snapshots automatically, find inspiration in
+https://curl.haxx.se/dev/autocurl.txt ):
 
 .nf
   $ mkdir daily-curl
   $ cd daily-curl
-  $ git clone git://github.com/curl/curl.git
+  $ git clone https://github.com/curl/curl.git
 .fi
 
 With the curl sources checked out, or downloaded, you can start testing right
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index e666798..14589d6 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -40,7 +40,15 @@
   set_target_properties(${_testname}
       PROPERTIES COMPILE_DEFINITIONS "UNITTESTS")
 
-  add_test(NAME ${_testname}
-           COMMAND ${_testname} "http://www.google.com"
-           )
+  if(HIDES_CURL_PRIVATE_SYMBOLS)
+    set_target_properties(${_testname}
+	  PROPERTIES
+		EXCLUDE_FROM_ALL TRUE
+		EXCLUDE_FROM_DEFAULT_BUILD TRUE
+	)
+  else()
+    add_test(NAME ${_testname}
+             COMMAND ${_testname} "http://www.google.com"
+    )
+  endif()
 endforeach()
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index d4987d6..7075f8c 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -54,7 +54,7 @@
               -I$(top_srcdir)/tests/libtest
 endif
 
-EXTRA_DIST = Makefile.inc
+EXTRA_DIST = Makefile.inc CMakeLists.txt
 
 # Prevent LIBS from being used for all link targets
 LIBS = $(BLANK_AT_MAKETIME)
diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc
index c5a1523..e7db96f 100644
--- a/tests/unit/Makefile.inc
+++ b/tests/unit/Makefile.inc
@@ -7,7 +7,7 @@
 # These are all unit test programs
 UNITPROGS = unit1300 unit1301 unit1302 unit1303 unit1304 unit1305 unit1307	\
  unit1308 unit1309 unit1330 unit1394 unit1395 unit1396 unit1397 unit1398	\
- unit1600 unit1601 unit1602 unit1603 unit1604
+ unit1600 unit1601 unit1602 unit1603 unit1604 unit1605
 
 unit1300_SOURCES = unit1300.c $(UNITFILES)
 unit1300_CPPFLAGS = $(AM_CPPFLAGS)
@@ -72,3 +72,5 @@
 unit1604_SOURCES = unit1604.c $(UNITFILES)
 unit1604_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
 
+unit1605_SOURCES = unit1605.c $(UNITFILES)
+unit1605_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/tests/unit/unit1301.c b/tests/unit/unit1301.c
index 928076e..aa86101 100644
--- a/tests/unit/unit1301.c
+++ b/tests/unit/unit1301.c
@@ -21,7 +21,7 @@
  ***************************************************************************/
 #include "curlcheck.h"
 
-#include "strequal.h"
+#include "strcase.h"
 
 static CURLcode unit_setup(void) {return CURLE_OK;}
 static void unit_stop(void) {}
diff --git a/tests/unit/unit1303.c b/tests/unit/unit1303.c
index a4bd598..c39e147 100644
--- a/tests/unit/unit1303.c
+++ b/tests/unit/unit1303.c
@@ -69,12 +69,12 @@
 };
 
 UNITTEST_START
+{
+  struct timeval now;
+  long timeout;
+  unsigned int i;
 
-struct timeval now;
-long timeout;
-unsigned int i;
-
-const struct timetest run[] = {
+  const struct timetest run[] = {
   /* both timeouts set, not connecting */
   {BASE + 4, 0,      10000, 8000, FALSE, 6000, "6 seconds should be left"},
   {BASE + 4, 990000, 10000, 8000, FALSE, 5010, "5010 ms should be left"},
@@ -126,21 +126,20 @@
   /* both timeouts set, connecting, connect timeout the longer one */
   {BASE + 4, 0,      10000, 12000, TRUE, 6000, "6 seconds should be left"},
 
-};
+  };
 
-/* this is the pretended start time of the transfer */
-data->progress.t_startsingle.tv_sec = BASE;
-data->progress.t_startsingle.tv_usec = 0;
-data->progress.t_startop.tv_sec = BASE;
-data->progress.t_startop.tv_usec = 0;
+  /* this is the pretended start time of the transfer */
+  data->progress.t_startsingle.tv_sec = BASE;
+  data->progress.t_startsingle.tv_usec = 0;
+  data->progress.t_startop.tv_sec = BASE;
+  data->progress.t_startop.tv_usec = 0;
 
-for(i=0; i < sizeof(run)/sizeof(run[0]); i++) {
-  NOW(run[i].now_s, run[i].now_us);
-  TIMEOUTS(run[i].timeout_ms, run[i].connecttimeout_ms);
-  timeout =  Curl_timeleft(data, &now, run[i].connecting);
-  if(timeout != run[i].result)
-    fail(run[i].comment);
+  for(i=0; i < sizeof(run)/sizeof(run[0]); i++) {
+    NOW(run[i].now_s, run[i].now_us);
+    TIMEOUTS(run[i].timeout_ms, run[i].connecttimeout_ms);
+    timeout =  Curl_timeleft(data, &now, run[i].connecting);
+    if(timeout != run[i].result)
+      fail(run[i].comment);
+  }
 }
-
-
 UNITTEST_STOP
diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
index 11bba39..83375f5 100644
--- a/tests/unit/unit1304.c
+++ b/tests/unit/unit1304.c
@@ -48,7 +48,7 @@
 UNITTEST_START
   int result;
 
-  static const char* const filename1 = "log/netrc1304";
+  static const char * const filename1 = "log/netrc1304";
   memcpy(filename, filename1, strlen(filename1));
 
   /*
diff --git a/tests/unit/unit1308.c b/tests/unit/unit1308.c
index 968bcff..5c1a008 100644
--- a/tests/unit/unit1308.c
+++ b/tests/unit/unit1308.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,8 +42,8 @@
 
 UNITTEST_START
   int rc;
-  struct curl_httppost* post = NULL;
-  struct curl_httppost* last = NULL;
+  struct curl_httppost *post = NULL;
+  struct curl_httppost *last = NULL;
   size_t total_size = 0;
   char buffer[] = "test buffer";
 
diff --git a/tests/unit/unit1602.c b/tests/unit/unit1602.c
index c67c0a5..5f1ee9f 100644
--- a/tests/unit/unit1602.c
+++ b/tests/unit/unit1602.c
@@ -32,7 +32,7 @@
 
 static void mydtor(void *p)
 {
-  int *ptr = (int*)p;
+  int *ptr = (int *)p;
   free(ptr);
 }
 
diff --git a/tests/unit/unit1604.c b/tests/unit/unit1604.c
index 242be00..5f1ea95 100644
--- a/tests/unit/unit1604.c
+++ b/tests/unit/unit1604.c
@@ -42,7 +42,8 @@
 
 #if defined(MSDOS) || defined(WIN32)
 
-static char *getflagstr(int flags) {
+static char *getflagstr(int flags)
+{
   char *buf = malloc(256);
   fail_unless(buf, "out of memory");
   snprintf(buf, 256, "%s,%s,%s,%s",
@@ -53,7 +54,8 @@
   return buf;
 }
 
-static char *getcurlcodestr(int cc) {
+static char *getcurlcodestr(int cc)
+{
   char *buf = malloc(256);
   fail_unless(buf, "out of memory");
   snprintf(buf, 256, "%s (%d)",
diff --git a/lib/strequal.h b/tests/unit/unit1605.c
similarity index 63%
rename from lib/strequal.h
rename to tests/unit/unit1605.c
index ff56df5..c807cb3 100644
--- a/lib/strequal.h
+++ b/tests/unit/unit1605.c
@@ -1,5 +1,3 @@
-#ifndef HEADER_CURL_STREQUAL_H
-#define HEADER_CURL_STREQUAL_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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,11 +19,31 @@
  * KIND, either express or implied.
  *
  ***************************************************************************/
+#include "curlcheck.h"
 
-#include <curl/curl.h>
+#include "llist.h"
 
-#define strequal(a,b) curl_strequal(a,b)
-#define strnequal(a,b,c) curl_strnequal(a,b,c)
+static CURLcode unit_setup(void)
+{
+  return CURLE_OK;
+}
 
-#endif /* HEADER_CURL_STREQUAL_H */
+static void unit_stop(void)
+{
 
+}
+
+UNITTEST_START
+  CURL *easy = curl_easy_init();
+  int len;
+  char *esc;
+
+  esc = curl_easy_escape(easy, "", -1);
+  fail_unless(esc == NULL, "negative string length can't work");
+
+  esc = curl_easy_unescape(easy, "%41%41%41%41", -1, &len);
+  fail_unless(esc == NULL, "negative string length can't work");
+
+  curl_easy_cleanup(easy);
+
+UNITTEST_STOP
diff --git a/winbuild/Makefile.vc b/winbuild/Makefile.vc
index 4f90e4a..9ef7c14 100644
--- a/winbuild/Makefile.vc
+++ b/winbuild/Makefile.vc
@@ -21,9 +21,11 @@
 !MESSAGE                                  Libraries can be fetched at http://pecl2.php.net/downloads/php-windows-builds/
 !MESSAGE                                  Uncompress them into the deps folder.
 !MESSAGE   WITH_SSL=<dll or static>     - Enable OpenSSL support, DLL or static
+!MESSAGE   WITH_NGHTTP2=<dll or static> - Enable HTTP/2 support, DLL or static
 !MESSAGE   WITH_CARES=<dll or static>   - Enable c-ares support, DLL or static
 !MESSAGE   WITH_ZLIB=<dll or static>    - Enable zlib support, DLL or static
 !MESSAGE   WITH_SSH2=<dll or static>    - Enable libSSH2 support, DLL or static
+!MESSAGE   WITH_MBEDTLS=<dll or static> - Enable mbedTLS support, DLL or static
 !MESSAGE   ENABLE_IDN=<yes or no>       - Enable use of Windows IDN APIs, defaults to yes
 !MESSAGE                                  Requires Windows Vista or later, or installation from:
 !MESSAGE                                  https://www.microsoft.com/en-us/download/details.aspx?id=734
@@ -54,7 +56,10 @@
 !ENDIF
 
 # default options
+
 !IFNDEF MACHINE
+# Note: nmake magically changes the value of PROCESSOR_ARCHITECTURE from "AMD64"
+# to "x86" when building in a 32 bit build environment on a 64 bit machine.
 !IF "$(PROCESSOR_ARCHITECTURE)"=="AMD64"
 MACHINE = x64
 !ELSE
@@ -87,7 +92,7 @@
 !ENDIF
 
 !IFNDEF ENABLE_WINSSL
-!IFDEF WITH_SSL
+!IF DEFINED(WITH_SSL) || DEFINED(WITH_MBEDTLS)
 USE_WINSSL = false
 !ELSE
 USE_WINSSL = $(USE_SSPI)
@@ -108,6 +113,34 @@
 SSL     = static
 !ENDIF
 
+!IF "$(ENABLE_NGHTTP2)"=="yes"
+# compatibility bit, WITH_NGHTTP2 is the correct flag
+WITH_NGHTTP2 = dll
+USE_NGHTTP2  = true
+NGHTTP2      = dll
+!ELSEIF "$(WITH_NGHTTP2)"=="dll"
+USE_NGHTTP2 = true
+NGHTTP2     = dll
+!ELSEIF "$(WITH_NGHTTP2)"=="static"
+USE_NGHTTP2 = true
+NGHTTP2     = static
+!ENDIF
+
+!IFNDEF USE_NGHTTP2
+USE_NGHTTP2 = false
+!ENDIF
+
+!IF "$(WITH_MBEDTLS)"=="dll" || "$(WITH_MBEDTLS)"=="static"
+USE_MBEDTLS = true
+MBEDTLS     = $(WITH_MBEDTLS)
+!ENDIF
+
+!IF ( "$(USE_SSL)"=="true" && "$(USE_WINSSL)"=="true" ) \
+ || ( "$(USE_SSL)"=="true" && "$(USE_MBEDTLS)"=="true" ) \
+ || ( "$(USE_MBEDTLS)"=="true" && "$(USE_WINSSL)"=="true" )
+!ERROR SSL, MBEDTLS and WINSSL are mutual exclusive options.
+!ENDIF
+
 !IF "$(WITH_CARES)"=="dll"
 USE_CARES = true
 CARES     = dll
@@ -150,6 +183,10 @@
 CONFIG_NAME_LIB = $(CONFIG_NAME_LIB)-ssl-$(SSL)
 !ENDIF
 
+!IF "$(USE_MBEDTLS)"=="true"
+CONFIG_NAME_LIB = $(CONFIG_NAME_LIB)-mbedtls-$(MBEDTLS)
+!ENDIF
+
 !IF "$(USE_CARES)"=="true"
 CONFIG_NAME_LIB = $(CONFIG_NAME_LIB)-cares-$(CARES)
 !ENDIF
@@ -174,6 +211,10 @@
 CONFIG_NAME_LIB = $(CONFIG_NAME_LIB)-winssl
 !ENDIF
 
+!IF "$(USE_NGHTTP2)"=="true"
+CONFIG_NAME_LIB = $(CONFIG_NAME_LIB)-nghttp2-$(NGHTTP2)
+!ENDIF
+
 !MESSAGE configuration name: $(CONFIG_NAME_LIB)
 
 BUILD_DIR=../builds/$(CONFIG_NAME_LIB)
@@ -197,10 +238,14 @@
 
 	@SET CONFIG_NAME_LIB=$(CONFIG_NAME_LIB)
 	@SET MACHINE=$(MACHINE)
+	@SET USE_NGHTTP2=$(USE_NGHTTP2)
 	@SET USE_IDN=$(USE_IDN)
 	@SET USE_IPV6=$(USE_IPV6)
 	@SET USE_SSPI=$(USE_SSPI)
 	@SET USE_WINSSL=$(USE_WINSSL)
+# compatibility bit
+	@SET WITH_NGHTTP2=$(WITH_NGHTTP2)
+
 	@$(MAKE) /NOLOGO /F MakefileBuild.vc
 
 copy_from_lib:
diff --git a/winbuild/MakefileBuild.vc b/winbuild/MakefileBuild.vc
index 62a5719..9351440 100644
--- a/winbuild/MakefileBuild.vc
+++ b/winbuild/MakefileBuild.vc
@@ -47,13 +47,19 @@
 WINBUILD_DIR=`cd`

 ZIP        = zip.exe

 

+# Allow changing C compiler via environment variable CC (default cl.exe)

+# This command macro is not set by default: https://msdn.microsoft.com/en-us/library/ms933742.aspx

+!If "$(CC)" == ""

+CC = cl.exe

+!Endif

+

 !IF "$(VC)"=="6"

-CC_NODEBUG  = cl.exe /O2 /DNDEBUG

-CC_DEBUG    = cl.exe /Od /Gm /Zi /D_DEBUG /GZ

+CC_NODEBUG  = $(CC) /O2 /DNDEBUG

+CC_DEBUG    = $(CC) /Od /Gm /Zi /D_DEBUG /GZ

 CFLAGS     = /I. /I../lib /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL

 !ELSE

-CC_NODEBUG  = cl.exe /O2 /DNDEBUG

-CC_DEBUG    = cl.exe /Od /D_DEBUG /RTC1 /Z7 /LDd /W3

+CC_NODEBUG  = $(CC) /O2 /DNDEBUG

+CC_DEBUG    = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd /W3

 CFLAGS      = /I. /I ../lib /I../include /nologo /W3 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL

 !ENDIF

 

@@ -117,8 +123,22 @@
 SSL          = static

 !ENDIF

 

+!IFNDEF USE_NGHTTP2

+USE_NGHTTP2  = false

+!ENDIF

+

 !IFDEF USE_SSL

 SSL_CFLAGS   = /DUSE_OPENSSL /I"$(DEVEL_INCLUDE)/openssl"

+

+!IF "$(USE_NGHTTP2)"=="yes"

+USE_NGHTTP2  = true

+!ENDIF

+

+!IF "$(USE_NGHTTP2)"=="true"

+SSL_CFLAGS   = $(SSL_CFLAGS) /DUSE_NGHTTP2

+SSL_LIBS     = $(SSL_LIBS) nghttp2.lib

+!ENDIF

+

 !ENDIF

 

 !IF "$(WITH_CARES)"=="dll"

@@ -268,20 +288,14 @@
 

 !IF "$(DEBUG)"=="yes"

 RC_FLAGS = /dDEBUGBUILD=1 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc

-CC              = $(CC_DEBUG) $(RTLIB_DEBUG)

-

-CURL_CC         = $(CC)

+CURL_CC       = $(CC_DEBUG) $(RTLIB_DEBUG)

 CURL_RC_FLAGS = /i../include /dDEBUGBUILD=1 /Fo $@ $(CURL_SRC_DIR)\curl.rc

 !ELSE

 RC_FLAGS = /dDEBUGBUILD=0 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc

-CC              = $(CC_NODEBUG) $(RTLIB)

-

-CURL_CC         = $(CC)

+CURL_CC       = $(CC_NODEBUG) $(RTLIB)

 CURL_RC_FLAGS = /i../include /dDEBUGBUILD=0 /Fo $@ $(CURL_SRC_DIR)\curl.rc

 !ENDIF

 

-CURL_CC = $(CURL_CC) $(CURL_CFLAGS)

-

 !IF "$(AS_DLL)" == "true"

 

 LNK       = $(LNKDLL) $(WIN_LIBS) /out:$(LIB_DIROBJ)\$(TARGET)

@@ -309,7 +323,7 @@
 PDB      = $(PDB_NAME_STATIC)

 !ENDIF

 LNK      = $(LNKLIB) $(WIN_LIBS) /out:$(LIB_DIROBJ)\$(TARGET)

-CC       = $(CC) $(CFLAGS_LIBCURL_STATIC)

+CURL_CC  = $(CURL_CC) $(CFLAGS_LIBCURL_STATIC)

 

 # AS_DLL

 !ENDIF

@@ -403,6 +417,7 @@
 

 $(TARGET): $(LIB_OBJS) $(LIB_DIROBJ) $(DISTDIR)

 	@echo Using SSL: $(USE_SSL)

+	@echo Using NGHTTP2: $(USE_NGHTTP2)

 	@echo Using c-ares: $(USE_CARES)

 	@echo Using SSH2: $(USE_SSH2)

 	@echo Using ZLIB: $(USE_ZLIB)

@@ -449,13 +464,13 @@
 .SUFFIXES: .c .obj .res

 

 {$(LIBCURL_SRC_DIR)\}.c{$(LIB_DIROBJ)\}.obj:

-	$(CC) $(CFLAGS) /Fo"$@"  $<

+	$(CURL_CC) $(CFLAGS) /Fo"$@"  $<

 

 {$(LIBCURL_SRC_DIR)\vauth\}.c{$(LIB_DIROBJ)\vauth\}.obj:

-	$(CC) $(CFLAGS) /Fo"$@"  $<

+	$(CURL_CC) $(CFLAGS) /Fo"$@"  $<

 

 {$(LIBCURL_SRC_DIR)\vtls\}.c{$(LIB_DIROBJ)\vtls\}.obj:

-	$(CC) $(CFLAGS) /Fo"$@"  $<

+	$(CURL_CC) $(CFLAGS) /Fo"$@"  $<

 

 $(LIB_DIROBJ)\libcurl.res: $(LIBCURL_SRC_DIR)\libcurl.rc

 	rc $(RC_FLAGS)

@@ -481,7 +496,6 @@
 

 CURL_FROM_LIBCURL=$(CURL_DIROBJ)\tool_hugehelp.obj \

  $(CURL_DIROBJ)\nonblock.obj \

- $(CURL_DIROBJ)\rawstr.obj \

  $(CURL_DIROBJ)\strtoofft.obj \

  $(CURL_DIROBJ)\warnless.obj

  

@@ -490,14 +504,12 @@
 	$(MANIFESTTOOL)

 

 {$(CURL_SRC_DIR)\}.c{$(CURL_DIROBJ)\}.obj:

-	$(CC) $(CURL_CFLAGS) /Fo"$@"  $<

+	$(CURL_CC) $(CURL_CFLAGS) /Fo"$@"  $<

 

 $(CURL_DIROBJ)\tool_hugehelp.obj: $(CURL_SRC_DIR)\tool_hugehelp.c

 	$(CURL_CC) $(CURL_CFLAGS) /Zm200 /Fo"$@" $(CURL_SRC_DIR)\tool_hugehelp.c

 $(CURL_DIROBJ)\nonblock.obj: ../lib/nonblock.c

 	$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/nonblock.c

-$(CURL_DIROBJ)\rawstr.obj: ../lib/rawstr.c

-	$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/rawstr.c

 $(CURL_DIROBJ)\strtoofft.obj: ../lib/strtoofft.c

 	$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/strtoofft.c

 $(CURL_DIROBJ)\warnless.obj: ../lib/warnless.c