mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 10:50:16 -06:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2020-06-23 (e9db32a0)
This commit is contained in:
@@ -1 +1,22 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
@CMAKE_CONFIGURABLE_FILE_CONTENT@
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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(CheckCSourceCompiles)
|
||||
|
||||
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
|
||||
|
||||
find_library(BEARSSL_LIBRARY bearssl)
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
# - Find c-ares
|
||||
# Find the c-ares includes and library
|
||||
# This module defines
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
# - Try to find the GSS Kerberos library
|
||||
# Once done this will define
|
||||
#
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
# - Try to find the libssh2 library
|
||||
# Once done this will define
|
||||
#
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
||||
|
||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
|
||||
|
||||
76
Utilities/cmcurl/CMake/FindNGHTTP3.cmake
Normal file
76
Utilities/cmcurl/CMake/FindNGHTTP3.cmake
Normal file
@@ -0,0 +1,76 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindNGHTTP3
|
||||
----------
|
||||
|
||||
Find the nghttp3 library
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
``NGHTTP3_FOUND``
|
||||
System has nghttp3
|
||||
``NGHTTP3_INCLUDE_DIRS``
|
||||
The nghttp3 include directories.
|
||||
``NGHTTP3_LIBRARIES``
|
||||
The libraries needed to use nghttp3
|
||||
``NGHTTP3_VERSION``
|
||||
version of nghttp3.
|
||||
#]=======================================================================]
|
||||
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_NGHTTP3 libnghttp3)
|
||||
endif()
|
||||
|
||||
find_path(NGHTTP3_INCLUDE_DIR nghttp3/nghttp3.h
|
||||
HINTS
|
||||
${PC_NGHTTP3_INCLUDEDIR}
|
||||
${PC_NGHTTP3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(NGHTTP3_LIBRARY NAMES nghttp3
|
||||
HINTS
|
||||
${PC_NGHTTP3_LIBDIR}
|
||||
${PC_NGHTTP3_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_NGHTTP3_VERSION)
|
||||
set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION})
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGHTTP3
|
||||
REQUIRED_VARS
|
||||
NGHTTP3_LIBRARY
|
||||
NGHTTP3_INCLUDE_DIR
|
||||
VERSION_VAR NGHTTP3_VERSION
|
||||
)
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY})
|
||||
set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGHTTP3_INCLUDE_DIRS NGHTTP3_LIBRARIES)
|
||||
113
Utilities/cmcurl/CMake/FindNGTCP2.cmake
Normal file
113
Utilities/cmcurl/CMake/FindNGTCP2.cmake
Normal file
@@ -0,0 +1,113 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindNGTCP2
|
||||
----------
|
||||
|
||||
Find the ngtcp2 library
|
||||
|
||||
This module accepts optional COMPONENTS to control the crypto library (these are
|
||||
mutually exclusive)::
|
||||
|
||||
OpenSSL: Use libngtcp2_crypto_openssl
|
||||
GnuTLS: Use libngtcp2_crypto_gnutls
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
``NGTCP2_FOUND``
|
||||
System has ngtcp2
|
||||
``NGTCP2_INCLUDE_DIRS``
|
||||
The ngtcp2 include directories.
|
||||
``NGTCP2_LIBRARIES``
|
||||
The libraries needed to use ngtcp2
|
||||
``NGTCP2_VERSION``
|
||||
version of ngtcp2.
|
||||
#]=======================================================================]
|
||||
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_NGTCP2 libngtcp2)
|
||||
endif()
|
||||
|
||||
find_path(NGTCP2_INCLUDE_DIR ngtcp2/ngtcp2.h
|
||||
HINTS
|
||||
${PC_NGTCP2_INCLUDEDIR}
|
||||
${PC_NGTCP2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(NGTCP2_LIBRARY NAMES ngtcp2
|
||||
HINTS
|
||||
${PC_NGTCP2_LIBDIR}
|
||||
${PC_NGTCP2_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_NGTCP2_VERSION)
|
||||
set(NGTCP2_VERSION ${PC_NGTCP2_VERSION})
|
||||
endif()
|
||||
|
||||
if(NGTCP2_FIND_COMPONENTS)
|
||||
set(NGTCP2_CRYPTO_BACKEND "")
|
||||
foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
|
||||
if(component MATCHES "^(OpenSSL|GnuTLS)")
|
||||
if(NGTCP2_CRYPTO_BACKEND)
|
||||
message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
|
||||
endif()
|
||||
set(NGTCP2_CRYPTO_BACKEND ${component})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NGTCP2_CRYPTO_BACKEND)
|
||||
string(TOLOWER "ngtcp2_crypto_${NGTCP2_CRYPTO_BACKEND}" _crypto_library)
|
||||
if(UNIX)
|
||||
pkg_search_module(PC_${_crypto_library} lib${_crypto_library})
|
||||
endif()
|
||||
find_library(${_crypto_library}_LIBRARY
|
||||
NAMES
|
||||
${_crypto_library}
|
||||
HINTS
|
||||
${PC_${_crypto_library}_LIBDIR}
|
||||
${PC_${_crypto_library}_LIBRARY_DIRS}
|
||||
)
|
||||
if(${_crypto_library}_LIBRARY)
|
||||
set(NGTCP2_${NGTCP2_CRYPTO_BACKEND}_FOUND TRUE)
|
||||
set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGTCP2
|
||||
REQUIRED_VARS
|
||||
NGTCP2_LIBRARY
|
||||
NGTCP2_INCLUDE_DIR
|
||||
VERSION_VAR NGTCP2_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
|
||||
set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGTCP2_INCLUDE_DIRS NGTCP2_LIBRARIES)
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_NSS nss)
|
||||
|
||||
68
Utilities/cmcurl/CMake/FindQUICHE.cmake
Normal file
68
Utilities/cmcurl/CMake/FindQUICHE.cmake
Normal file
@@ -0,0 +1,68 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindQUICHE
|
||||
----------
|
||||
|
||||
Find the quiche library
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
``QUICHE_FOUND``
|
||||
System has quiche
|
||||
``QUICHE_INCLUDE_DIRS``
|
||||
The quiche include directories.
|
||||
``QUICHE_LIBRARIES``
|
||||
The libraries needed to use quiche
|
||||
#]=======================================================================]
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_QUICHE quiche)
|
||||
endif()
|
||||
|
||||
find_path(QUICHE_INCLUDE_DIR quiche.h
|
||||
HINTS
|
||||
${PC_QUICHE_INCLUDEDIR}
|
||||
${PC_QUICHE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(QUICHE_LIBRARY NAMES quiche
|
||||
HINTS
|
||||
${PC_QUICHE_LIBDIR}
|
||||
${PC_QUICHE_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(QUICHE
|
||||
REQUIRED_VARS
|
||||
QUICHE_LIBRARY
|
||||
QUICHE_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(QUICHE_FOUND)
|
||||
set(QUICHE_LIBRARIES ${QUICHE_LIBRARY})
|
||||
set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(QUICHE_INCLUDE_DIRS QUICHE_LIBRARIES)
|
||||
34
Utilities/cmcurl/CMake/FindWolfSSL.cmake
Normal file
34
Utilities/cmcurl/CMake/FindWolfSSL.cmake
Normal file
@@ -0,0 +1,34 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
|
||||
find_library(WolfSSL_LIBRARY NAMES wolfssl)
|
||||
mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(WolfSSL
|
||||
REQUIRED_VARS WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY
|
||||
)
|
||||
|
||||
if(WolfSSL_FOUND)
|
||||
set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR})
|
||||
set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY})
|
||||
endif()
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
#File defines convenience macros for available feature testing
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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(CheckCSourceCompiles)
|
||||
# The begin of the sources (macros and includes)
|
||||
set(_source_epilogue "#undef inline")
|
||||
@@ -49,6 +70,9 @@ if(curl_cv_recv)
|
||||
unset(curl_cv_func_recv_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${recv_retv} ${signature_call_conv}
|
||||
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
|
||||
int main(void) {
|
||||
@@ -122,6 +146,9 @@ if(curl_cv_send)
|
||||
unset(curl_cv_func_send_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${send_retv} ${signature_call_conv}
|
||||
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
|
||||
int main(void) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
if(NOT UNIX)
|
||||
if(WIN32)
|
||||
set(HAVE_LIBDL 0)
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
# File containing various utilities
|
||||
|
||||
# Returns a list of arguments that evaluate to true
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
@@ -118,7 +118,6 @@ endif()
|
||||
# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file
|
||||
# Add full (4 or 5 libs) SSL support
|
||||
# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include).
|
||||
# Add CTests(?)
|
||||
# Check on all possible platforms
|
||||
# Test with as many configurations possible (With or without any option)
|
||||
# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest:
|
||||
@@ -274,6 +273,8 @@ option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMTP)
|
||||
option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_GOPHER)
|
||||
option(CURL_ENABLE_MQTT "to enable MQTT" OFF)
|
||||
mark_as_advanced(CURL_ENABLE_MQTT)
|
||||
|
||||
if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_FTP ON)
|
||||
@@ -323,10 +324,6 @@ cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual"
|
||||
ON "NROFF_USEFUL;PERL_FOUND"
|
||||
OFF)
|
||||
|
||||
if(NOT PERL_FOUND)
|
||||
message(STATUS "Perl not found, testing disabled.")
|
||||
set(BUILD_TESTING OFF)
|
||||
endif()
|
||||
if(ENABLE_MANUAL)
|
||||
set(USE_MANUAL ON)
|
||||
endif()
|
||||
@@ -337,6 +334,7 @@ set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
|
||||
|
||||
if(CURL_STATIC_CRT)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
|
||||
endif()
|
||||
@@ -411,7 +409,7 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
# check SSL libraries
|
||||
# TODO support GnuTLS and WolfSSL
|
||||
# TODO support GnuTLS
|
||||
|
||||
if(APPLE)
|
||||
option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
|
||||
@@ -424,9 +422,10 @@ endif()
|
||||
option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
|
||||
option(CMAKE_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF)
|
||||
option(CMAKE_USE_NSS "Enable NSS for SSL/TLS" OFF)
|
||||
option(CMAKE_USE_WOLFSSL "enable wolfSSL for SSL/TLS" OFF)
|
||||
|
||||
set(openssl_default ON)
|
||||
if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR CMAKE_USE_NSS)
|
||||
if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR CMAKE_USE_NSS OR CMAKE_USE_WOLFSSL)
|
||||
set(openssl_default OFF)
|
||||
endif()
|
||||
|
||||
@@ -437,6 +436,7 @@ count_true(enabled_ssl_options_count
|
||||
CMAKE_USE_MBEDTLS
|
||||
CMAKE_USE_BEARSSL
|
||||
CMAKE_USE_NSS
|
||||
CMAKE_USE_WOLFSSL
|
||||
)
|
||||
if(enabled_ssl_options_count GREATER "1")
|
||||
set(CURL_WITH_MULTI_SSL ON)
|
||||
@@ -523,6 +523,14 @@ if(CMAKE_USE_BEARSSL)
|
||||
include_directories(${BEARSSL_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_WOLFSSL)
|
||||
find_package(WolfSSL REQUIRED)
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_WOLFSSL ON)
|
||||
list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES})
|
||||
include_directories(${WolfSSL_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_NSS)
|
||||
find_package(NSS REQUIRED)
|
||||
include_directories(${NSS_INCLUDE_DIRS})
|
||||
@@ -543,6 +551,56 @@ if(USE_NGHTTP2)
|
||||
list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
function(CheckQuicSupportInOpenSSL)
|
||||
# Be sure that the OpenSSL library actually supports QUIC.
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}")
|
||||
check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
|
||||
if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD)
|
||||
message(FATAL_ERROR "QUIC support is missing in OpenSSL/boringssl. Try setting -DOPENSSL_ROOT_DIR")
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endfunction()
|
||||
|
||||
option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF)
|
||||
if(USE_NGTCP2)
|
||||
if(USE_OPENSSL)
|
||||
find_package(NGTCP2 REQUIRED OpenSSL)
|
||||
CheckQuicSupportInOpenSSL()
|
||||
elseif(USE_GNUTLS)
|
||||
# TODO add GnuTLS support as vtls library.
|
||||
find_package(NGTCP2 REQUIRED GnuTLS)
|
||||
else()
|
||||
message(FATAL_ERROR "ngtcp2 requires OpenSSL or GnuTLS")
|
||||
endif()
|
||||
set(USE_NGTCP2 ON)
|
||||
include_directories(${NGTCP2_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
|
||||
|
||||
find_package(NGHTTP3 REQUIRED)
|
||||
set(USE_NGHTTP3 ON)
|
||||
include_directories(${NGHTTP3_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
|
||||
endif()
|
||||
|
||||
option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
|
||||
if(USE_QUICHE)
|
||||
if(USE_NGTCP2)
|
||||
message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
|
||||
endif()
|
||||
find_package(QUICHE REQUIRED)
|
||||
CheckQuicSupportInOpenSSL()
|
||||
set(USE_QUICHE ON)
|
||||
include_directories(${QUICHE_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${QUICHE_LIBRARIES}")
|
||||
check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(USE_WIN32_CRYPTO ON)
|
||||
endif()
|
||||
@@ -744,6 +802,20 @@ if(CMAKE_USE_LIBSSH2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# libssh
|
||||
option(CMAKE_USE_LIBSSH "Use libSSH" OFF)
|
||||
mark_as_advanced(CMAKE_USE_LIBSSH)
|
||||
if(NOT HAVE_LIBSSH2 AND CMAKE_USE_LIBSSH)
|
||||
find_package(libssh CONFIG)
|
||||
if(libssh_FOUND)
|
||||
message(STATUS "Found libssh ${libssh_VERSION}")
|
||||
# Use imported target for include and library paths.
|
||||
list(APPEND CURL_LIBS ssh)
|
||||
set(USE_LIBSSH ON)
|
||||
set(HAVE_LIBSSH_LIBSSH_H 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
|
||||
mark_as_advanced(CMAKE_USE_GSSAPI)
|
||||
|
||||
@@ -812,6 +884,8 @@ else()
|
||||
unset(USE_UNIX_SOCKETS CACHE)
|
||||
endif()
|
||||
|
||||
option(ENABLE_ALT_SVC "Enable alt-svc support" OFF)
|
||||
set(USE_ALTSVC ${ENABLE_ALT_SVC})
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
#
|
||||
@@ -882,7 +956,7 @@ elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
|
||||
endif()
|
||||
|
||||
if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
|
||||
message(FATAL_ERROR
|
||||
message(STATUS
|
||||
"CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
|
||||
"Set CURL_CA_PATH=none or enable one of those TLS backends.")
|
||||
endif()
|
||||
@@ -926,7 +1000,6 @@ check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
|
||||
check_include_file_concat("assert.h" HAVE_ASSERT_H)
|
||||
check_include_file_concat("crypto.h" HAVE_CRYPTO_H)
|
||||
check_include_file_concat("des.h" HAVE_DES_H)
|
||||
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)
|
||||
@@ -1314,7 +1387,7 @@ function(transform_makefile_inc INPUT_FILE OUTPUT_FILE)
|
||||
string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${}
|
||||
string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts.
|
||||
file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}")
|
||||
endfunction()
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
@@ -1350,8 +1423,10 @@ install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
include(CTest)
|
||||
if(BUILD_TESTING)
|
||||
option(BUILD_TESTING "Build tests" "${PERL_FOUND}")
|
||||
if(NOT PERL_FOUND)
|
||||
message(STATUS "Perl not found, testing disabled.")
|
||||
elseif(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -1385,6 +1460,7 @@ _add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
|
||||
# TODO SSP1 (WinSSL) check is missing
|
||||
_add_if("SSPI" USE_WINDOWS_SSPI)
|
||||
_add_if("GSS-API" HAVE_GSSAPI)
|
||||
_add_if("alt-svc" ENABLE_ALT_SVC)
|
||||
# TODO SSP1 missing for SPNEGO
|
||||
_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
@@ -1399,6 +1475,8 @@ _add_if("NTLM_WB" use_ntlm AND NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
|
||||
_add_if("TLS-SRP" USE_TLS_SRP)
|
||||
# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
|
||||
_add_if("HTTP2" USE_NGHTTP2)
|
||||
_add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE)
|
||||
_add_if("MultiSSL" CURL_WITH_MULTI_SSL)
|
||||
_add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
|
||||
string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
|
||||
message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
|
||||
@@ -1428,10 +1506,11 @@ _add_if("SMB" NOT CURL_DISABLE_SMB AND use_ntlm)
|
||||
_add_if("SMBS" NOT CURL_DISABLE_SMB AND SSL_ENABLED AND use_ntlm)
|
||||
_add_if("SMTP" NOT CURL_DISABLE_SMTP)
|
||||
_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
|
||||
_add_if("SCP" USE_LIBSSH2)
|
||||
_add_if("SFTP" USE_LIBSSH2)
|
||||
_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH)
|
||||
_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
|
||||
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
|
||||
_add_if("RTMP" USE_LIBRTMP)
|
||||
_add_if("MQTT" CURL_ENABLE_MQTT)
|
||||
if(_items)
|
||||
list(SORT _items)
|
||||
endif()
|
||||
@@ -1446,6 +1525,7 @@ _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
|
||||
_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
|
||||
_add_if("BearSSL" SSL_ENABLED AND USE_BEARSSL)
|
||||
_add_if("NSS" SSL_ENABLED AND USE_NSS)
|
||||
_add_if("wolfSSL" SSL_ENABLED AND USE_WOLFSSL)
|
||||
if(_items)
|
||||
list(SORT _items)
|
||||
endif()
|
||||
@@ -1459,25 +1539,43 @@ set(CONFIGURE_OPTIONS "")
|
||||
# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
|
||||
set(CPPFLAG_CURL_STATICLIB "")
|
||||
set(CURLVERSION "${CURL_VERSION}")
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(ENABLE_SHARED "yes")
|
||||
set(ENABLE_STATIC "no")
|
||||
else()
|
||||
set(ENABLE_SHARED "no")
|
||||
set(ENABLE_STATIC "yes")
|
||||
endif()
|
||||
set(exec_prefix "\${prefix}")
|
||||
set(includedir "\${prefix}/include")
|
||||
set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(LIBCURL_LIBS "")
|
||||
set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
|
||||
if(TARGET "${_lib}")
|
||||
set(_libname "${_lib}")
|
||||
get_target_property(_libtype "${_libname}" TYPE)
|
||||
if(_libtype STREQUAL INTERFACE_LIBRARY)
|
||||
# Interface libraries can occur when an external project embeds curl and
|
||||
# defined targets such as ZLIB::ZLIB by themselves. Ignore these as
|
||||
# reading the LOCATION property will error out. Assume the user won't need
|
||||
# this information in the .pc file.
|
||||
continue()
|
||||
endif()
|
||||
get_target_property(_lib "${_libname}" LOCATION)
|
||||
if(NOT _lib)
|
||||
message(WARNING "Bad lib in library list: ${_libname}")
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-")
|
||||
set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}")
|
||||
else()
|
||||
set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(ENABLE_SHARED "yes")
|
||||
set(ENABLE_STATIC "no")
|
||||
set(LIBCURL_NO_SHARED "")
|
||||
else()
|
||||
set(ENABLE_SHARED "no")
|
||||
set(ENABLE_STATIC "yes")
|
||||
set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}")
|
||||
endif()
|
||||
# "a" (Linux) or "lib" (Windows)
|
||||
string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
@@ -833,6 +833,15 @@ typedef enum {
|
||||
if possible. The OpenSSL backend has this ability. */
|
||||
#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
|
||||
|
||||
/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
|
||||
checks and ignore missing revocation list for those SSL backends where such
|
||||
behavior is present. */
|
||||
#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
|
||||
|
||||
/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
|
||||
operating system. Currently implemented under MS-Windows. */
|
||||
#define CURLSSLOPT_NATIVE_CA (1<<4)
|
||||
|
||||
/* The default connection attempt delay in milliseconds for happy eyeballs.
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
|
||||
this value, keep them in sync. */
|
||||
@@ -932,6 +941,7 @@ typedef enum {
|
||||
#define CURLPROTO_GOPHER (1<<25)
|
||||
#define CURLPROTO_SMB (1<<26)
|
||||
#define CURLPROTO_SMBS (1<<27)
|
||||
#define CURLPROTO_MQTT (1<<28)
|
||||
#define CURLPROTO_ALL (~0) /* enable everything */
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
@@ -940,6 +950,7 @@ typedef enum {
|
||||
#define CURLOPTTYPE_OBJECTPOINT 10000
|
||||
#define CURLOPTTYPE_FUNCTIONPOINT 20000
|
||||
#define CURLOPTTYPE_OFF_T 30000
|
||||
#define CURLOPTTYPE_BLOB 40000
|
||||
|
||||
/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
|
||||
string options from the header file */
|
||||
@@ -1949,6 +1960,17 @@ typedef enum {
|
||||
/* allow RCPT TO command to fail for some recipients */
|
||||
CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
|
||||
|
||||
/* the private SSL-certificate as a "blob" */
|
||||
CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
|
||||
CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292),
|
||||
CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293),
|
||||
CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),
|
||||
CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295),
|
||||
|
||||
/* Issuer certificate for proxy */
|
||||
CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
|
||||
CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -2105,8 +2127,8 @@ CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
|
||||
CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/* Mime/form handling support. */
|
||||
typedef struct curl_mime_s curl_mime; /* Mime context. */
|
||||
typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */
|
||||
typedef struct curl_mime curl_mime; /* Mime context. */
|
||||
typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
|
||||
|
||||
/*
|
||||
* NAME curl_mime_init()
|
||||
@@ -2428,7 +2450,7 @@ CURL_EXTERN CURLcode curl_global_init(long flags);
|
||||
* initialize libcurl and set user defined memory management callback
|
||||
* functions. Users can implement memory management routines to check for
|
||||
* memory leaks, check for mis-use of the curl library etc. User registered
|
||||
* callback routines with be invoked by this library instead of the system
|
||||
* callback routines will be invoked by this library instead of the system
|
||||
* memory management routines like malloc, free etc.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_global_init_mem(long flags,
|
||||
@@ -2480,10 +2502,11 @@ struct curl_slist {
|
||||
* subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct curl_ssl_backend {
|
||||
curl_sslbackend id;
|
||||
const char *name;
|
||||
} curl_ssl_backend;
|
||||
};
|
||||
typedef struct curl_ssl_backend curl_ssl_backend;
|
||||
|
||||
typedef enum {
|
||||
CURLSSLSET_OK = 0,
|
||||
@@ -2724,6 +2747,7 @@ typedef enum {
|
||||
CURLVERSION_FOURTH,
|
||||
CURLVERSION_FIFTH,
|
||||
CURLVERSION_SIXTH,
|
||||
CURLVERSION_SEVENTH,
|
||||
CURLVERSION_LAST /* never actually use this */
|
||||
} CURLversion;
|
||||
|
||||
@@ -2732,9 +2756,9 @@ typedef enum {
|
||||
meant to be a built-in version number for what kind of struct the caller
|
||||
expects. If the struct ever changes, we redefine the NOW to another enum
|
||||
from above. */
|
||||
#define CURLVERSION_NOW CURLVERSION_SIXTH
|
||||
#define CURLVERSION_NOW CURLVERSION_SEVENTH
|
||||
|
||||
typedef struct {
|
||||
struct curl_version_info_data {
|
||||
CURLversion age; /* age of the returned struct */
|
||||
const char *version; /* LIBCURL_VERSION */
|
||||
unsigned int version_num; /* LIBCURL_VERSION_NUM */
|
||||
@@ -2771,7 +2795,15 @@ typedef struct {
|
||||
const char *nghttp2_version; /* human readable string. */
|
||||
const char *quic_version; /* human readable quic (+ HTTP/3) library +
|
||||
version or NULL */
|
||||
} curl_version_info_data;
|
||||
|
||||
/* These fields were added in CURLVERSION_SEVENTH */
|
||||
const char *cainfo; /* the built-in default CURLOPT_CAINFO, might
|
||||
be NULL */
|
||||
const char *capath; /* the built-in default CURLOPT_CAPATH, might
|
||||
be NULL */
|
||||
|
||||
};
|
||||
typedef struct curl_version_info_data curl_version_info_data;
|
||||
|
||||
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
|
||||
@@ -2805,8 +2837,6 @@ typedef struct {
|
||||
#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
|
||||
#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
|
||||
|
||||
#define CURL_VERSION_ESNI (1<<26) /* ESNI support */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
*
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.69.0"
|
||||
#define LIBCURL_VERSION "7.71.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 69
|
||||
#define LIBCURL_VERSION_MINOR 71
|
||||
#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
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
@@ -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 0x074500
|
||||
#define LIBCURL_VERSION_NUM 0x074700
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -25,6 +25,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Flag bits in the curl_blob struct: */
|
||||
#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
|
||||
#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
|
||||
|
||||
struct curl_blob {
|
||||
void *data;
|
||||
size_t len;
|
||||
unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
|
||||
left zeroes */
|
||||
};
|
||||
|
||||
CURL_EXTERN CURL *curl_easy_init(void);
|
||||
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
|
||||
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
|
||||
|
||||
@@ -377,12 +377,10 @@ typedef enum {
|
||||
will not be considered for pipelining */
|
||||
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
|
||||
|
||||
/* a list of site names(+port) that are blacklisted from
|
||||
pipelining */
|
||||
/* a list of site names(+port) that are blocked from pipelining */
|
||||
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
|
||||
|
||||
/* a list of server types that are blacklisted from
|
||||
pipelining */
|
||||
/* a list of server types that are blocked from pipelining */
|
||||
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
|
||||
|
||||
/* maximum number of open connections in total */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -248,7 +248,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
|
||||
|
||||
#define curlcheck_off_t_option(option) \
|
||||
((option) > CURLOPTTYPE_OFF_T)
|
||||
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
#define curlcheck_string_option(option) \
|
||||
@@ -392,8 +392,9 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
/* groups of curl_easy_getinfo infos that take the same type of argument */
|
||||
|
||||
/* evaluates to true if info expects a pointer to char * argument */
|
||||
#define curlcheck_string_info(info) \
|
||||
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
|
||||
#define curlcheck_string_info(info) \
|
||||
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
|
||||
(info) != CURLINFO_PRIVATE)
|
||||
|
||||
/* evaluates to true if info expects a pointer to long argument */
|
||||
#define curlcheck_long_info(info) \
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
#
|
||||
###########################################################################
|
||||
set(LIB_NAME cmcurl)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
@@ -96,6 +117,11 @@ add_library(
|
||||
${CMAKE_CURL_SSL_DLLS}
|
||||
)
|
||||
|
||||
add_library(
|
||||
${PROJECT_NAME}::${LIB_NAME}
|
||||
ALIAS ${LIB_NAME}
|
||||
)
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
||||
endif()
|
||||
@@ -146,7 +172,7 @@ install(TARGETS ${LIB_NAME}
|
||||
|
||||
export(TARGETS ${LIB_NAME}
|
||||
APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
|
||||
NAMESPACE CURL::
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -20,71 +20,66 @@
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
|
||||
vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c \
|
||||
vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c \
|
||||
vauth/spnego_gssapi.c vauth/spnego_sspi.c
|
||||
LIB_VAUTH_CFILES = vauth/cleartext.c vauth/cram.c vauth/digest.c \
|
||||
vauth/digest_sspi.c vauth/krb5_gssapi.c vauth/krb5_sspi.c vauth/ntlm.c \
|
||||
vauth/ntlm_sspi.c vauth/oauth2.c vauth/spnego_gssapi.c vauth/spnego_sspi.c \
|
||||
vauth/vauth.c
|
||||
|
||||
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
|
||||
LIB_VAUTH_HFILES = vauth/digest.h vauth/ntlm.h vauth/vauth.h
|
||||
|
||||
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
||||
vtls/mbedtls_threadlock.c vtls/wolfssl.c vtls/schannel.c \
|
||||
vtls/schannel_verify.c vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c \
|
||||
vtls/mesalink.c vtls/bearssl.c
|
||||
LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/keylog.c \
|
||||
vtls/mbedtls.c vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c \
|
||||
vtls/openssl.c vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c \
|
||||
vtls/vtls.c vtls/wolfssl.c
|
||||
|
||||
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h vtls/nssg.h \
|
||||
vtls/mbedtls_threadlock.h vtls/wolfssl.h vtls/schannel.h \
|
||||
vtls/sectransp.h vtls/gskit.h vtls/mbedtls.h vtls/mesalink.h \
|
||||
vtls/bearssl.h
|
||||
LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/keylog.h \
|
||||
vtls/mbedtls.h vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h \
|
||||
vtls/openssl.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
|
||||
|
||||
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
|
||||
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c
|
||||
|
||||
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
|
||||
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h vquic/vquic.h
|
||||
|
||||
LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c vssh/wolfssh.c
|
||||
LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
|
||||
|
||||
LIB_VSSH_HFILES = vssh/ssh.h
|
||||
|
||||
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 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 \
|
||||
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 rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
|
||||
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
|
||||
doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c rename.c
|
||||
LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \
|
||||
conncache.c connect.c content_encoding.c cookie.c curl_addrinfo.c \
|
||||
curl_ctype.c curl_des.c curl_endian.c curl_fnmatch.c curl_get_line.c \
|
||||
curl_gethostname.c curl_gssapi.c curl_memrchr.c curl_multibyte.c \
|
||||
curl_ntlm_core.c curl_ntlm_wb.c curl_path.c curl_range.c curl_rtmp.c \
|
||||
curl_sasl.c curl_sspi.c curl_threads.c dict.c dotdot.c easy.c escape.c \
|
||||
file.c fileinfo.c formdata.c ftp.c url.c ftplistparser.c getenv.c getinfo.c \
|
||||
gopher.c hash.c hmac.c hostasyn.c hostcheck.c hostip.c hostip4.c hostip6.c \
|
||||
hostsyn.c http.c http2.c http_chunks.c http_digest.c http_negotiate.c \
|
||||
http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \
|
||||
krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c \
|
||||
multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c \
|
||||
pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c \
|
||||
sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
|
||||
socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \
|
||||
strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \
|
||||
transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.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 \
|
||||
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 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 \
|
||||
http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
|
||||
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
|
||||
curl_get_line.h altsvc.h quic.h socketpair.h rename.h
|
||||
LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
|
||||
content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \
|
||||
curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h \
|
||||
curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h \
|
||||
curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \
|
||||
curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h \
|
||||
curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h \
|
||||
dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h \
|
||||
ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h \
|
||||
http2.h http_chunks.h http_digest.h http_negotiate.h http_ntlm.h \
|
||||
http_proxy.h if2ip.h imap.h inet_ntop.h inet_pton.h llist.h memdebug.h \
|
||||
mime.h mqtt.h multihandle.h multiif.h netrc.h non-ascii.h nonblock.h \
|
||||
parsedate.h pingpong.h pop3.h progress.h psl.h doh.h quic.h rand.h rename.h \
|
||||
rtsp.h select.h sendf.h setopt.h setup-vms.h share.h sigpipe.h slist.h \
|
||||
smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
|
||||
strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \
|
||||
timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \
|
||||
x509asn1.h dynbuf.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
||||
@@ -50,8 +50,10 @@
|
||||
#define MAX_ALTSVC_ALPNLENSTR "10"
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
|
||||
#if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
|
||||
#define H3VERSION "h3-27"
|
||||
#if defined(USE_QUICHE) && !defined(UNITTESTS)
|
||||
#define H3VERSION "h3-29"
|
||||
#elif defined(USE_NGTCP2) && !defined(UNITTESTS)
|
||||
#define H3VERSION "h3-29"
|
||||
#else
|
||||
#define H3VERSION "h3"
|
||||
#endif
|
||||
@@ -167,7 +169,6 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
||||
as->prio = prio;
|
||||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,7 +409,6 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
|
||||
strcasecompare(srchost, as->src.host)) {
|
||||
Curl_llist_remove(&asi->list, e, NULL);
|
||||
altsvc_free(as);
|
||||
asi->num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,6 +429,8 @@ static time_t debugtime(void *unused)
|
||||
#define time(x) debugtime(x)
|
||||
#endif
|
||||
|
||||
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
||||
|
||||
/*
|
||||
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
|
||||
* the data correctly in the cache.
|
||||
@@ -474,7 +476,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
dstalpnid = alpn2alpnid(alpnbuf);
|
||||
p++;
|
||||
if(*p == '\"') {
|
||||
const char *dsthost;
|
||||
const char *dsthost = "";
|
||||
const char *value_ptr;
|
||||
char option[32];
|
||||
unsigned long num;
|
||||
@@ -518,12 +520,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
/* Handle the optional 'ma' and 'persist' flags. Unknown flags
|
||||
are skipped. */
|
||||
for(;;) {
|
||||
while(*p && ISBLANK(*p) && *p != ';' && *p != ',')
|
||||
while(ISBLANK(*p))
|
||||
p++;
|
||||
if(!*p || *p == ',')
|
||||
if(*p != ';')
|
||||
break;
|
||||
p++; /* pass the semicolon */
|
||||
if(!*p)
|
||||
if(!*p || ISNEWLINE(*p))
|
||||
break;
|
||||
result = getalnum(&p, option, sizeof(option));
|
||||
if(result) {
|
||||
@@ -573,7 +575,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
as->expires = maxage + time(NULL);
|
||||
as->persist = persist;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
|
||||
Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ struct altsvc {
|
||||
struct altsvcinfo {
|
||||
char *filename;
|
||||
struct curl_llist list; /* list of entries */
|
||||
size_t num; /* number of alt-svc entries */
|
||||
long flags; /* the publicly set bitmask */
|
||||
};
|
||||
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
|
||||
struct ResolverResults {
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int last_status;
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
};
|
||||
@@ -285,7 +286,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
* return number of sockets it worked on
|
||||
*/
|
||||
|
||||
static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
int nfds;
|
||||
@@ -352,8 +353,8 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
conn->async.os_specific;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(dns)
|
||||
*dns = NULL;
|
||||
DEBUGASSERT(dns);
|
||||
*dns = NULL;
|
||||
|
||||
waitperform(conn, 0);
|
||||
|
||||
@@ -381,19 +382,18 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(res && !res->num_pending) {
|
||||
if(dns) {
|
||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||
them */
|
||||
res->temp_ai = NULL;
|
||||
}
|
||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||
them */
|
||||
res->temp_ai = NULL;
|
||||
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve: %s (%s)",
|
||||
conn->async.hostname, ares_strerror(conn->async.status));
|
||||
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else if(dns)
|
||||
else
|
||||
*dns = conn->async.dns;
|
||||
|
||||
destroy_async_data(&conn->async);
|
||||
@@ -408,7 +408,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
* 'entry' MUST be non-NULL.
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
@@ -420,10 +420,9 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
timediff_t timeout;
|
||||
struct curltime now = Curl_now();
|
||||
struct Curl_dns_entry *temp_entry;
|
||||
|
||||
if(entry)
|
||||
*entry = NULL; /* clear on entry */
|
||||
DEBUGASSERT(entry);
|
||||
*entry = NULL; /* clear on entry */
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(timeout < 0) {
|
||||
@@ -438,9 +437,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
while(!result) {
|
||||
struct timeval *tvp, tv, store;
|
||||
int itimeout;
|
||||
int timeout_ms;
|
||||
timediff_t timeout_ms;
|
||||
|
||||
itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
|
||||
#else
|
||||
itimeout = (int)timeout;
|
||||
#endif
|
||||
|
||||
store.tv_sec = itimeout/1000;
|
||||
store.tv_usec = (itimeout%1000)*1000;
|
||||
@@ -451,12 +454,12 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
second is left, otherwise just use 1000ms to make sure the progress
|
||||
callback gets called frequent enough */
|
||||
if(!tvp->tv_sec)
|
||||
timeout_ms = (int)(tvp->tv_usec/1000);
|
||||
timeout_ms = (timediff_t)(tvp->tv_usec/1000);
|
||||
else
|
||||
timeout_ms = 1000;
|
||||
|
||||
waitperform(conn, timeout_ms);
|
||||
result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
|
||||
result = Curl_resolver_is_resolved(conn, entry);
|
||||
|
||||
if(result || conn->async.done)
|
||||
break;
|
||||
@@ -471,7 +474,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
else if(timediff > timeout)
|
||||
timeout = -1;
|
||||
else
|
||||
timeout -= (long)timediff;
|
||||
timeout -= timediff;
|
||||
now = now2; /* for next loop */
|
||||
}
|
||||
if(timeout < 0)
|
||||
@@ -496,9 +499,9 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
|
||||
/* Connects results to the list */
|
||||
static void compound_results(struct ResolverResults *res,
|
||||
Curl_addrinfo *ai)
|
||||
struct Curl_addrinfo *ai)
|
||||
{
|
||||
Curl_addrinfo *ai_tail;
|
||||
struct Curl_addrinfo *ai_tail;
|
||||
if(!ai)
|
||||
return;
|
||||
ai_tail = ai;
|
||||
@@ -540,7 +543,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
res->num_pending--;
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
|
||||
struct Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
|
||||
if(ai) {
|
||||
compound_results(res, ai);
|
||||
}
|
||||
@@ -619,10 +622,10 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
char *bufp;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
@@ -158,7 +158,7 @@ static bool init_resolve_thread(struct connectdata *conn,
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
curl_mutex_t * mtx;
|
||||
curl_mutex_t *mtx;
|
||||
int done;
|
||||
|
||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
||||
@@ -169,7 +169,7 @@ struct thread_sync_data {
|
||||
curl_socket_t sock_pair[2]; /* socket pair */
|
||||
#endif
|
||||
int sock_error;
|
||||
Curl_addrinfo *res;
|
||||
struct Curl_addrinfo *res;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
@@ -179,7 +179,7 @@ struct thread_sync_data {
|
||||
struct thread_data {
|
||||
curl_thread_t thread_hnd;
|
||||
unsigned int poll_interval;
|
||||
time_t interval_end;
|
||||
timediff_t interval_end;
|
||||
struct thread_sync_data tsd;
|
||||
};
|
||||
|
||||
@@ -190,7 +190,7 @@ static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
|
||||
|
||||
/* Destroy resolver thread synchronization data */
|
||||
static
|
||||
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
void destroy_thread_sync_data(struct thread_sync_data *tsd)
|
||||
{
|
||||
if(tsd->mtx) {
|
||||
Curl_mutex_destroy(tsd->mtx);
|
||||
@@ -216,7 +216,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
|
||||
/* Initialize resolver thread synchronization data */
|
||||
static
|
||||
int init_thread_sync_data(struct thread_data * td,
|
||||
int init_thread_sync_data(struct thread_data *td,
|
||||
const char *hostname,
|
||||
int port,
|
||||
const struct addrinfo *hints)
|
||||
@@ -494,11 +494,14 @@ static CURLcode resolver_error(struct connectdata *conn)
|
||||
const char *host_or_proxy;
|
||||
CURLcode result;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy) {
|
||||
host_or_proxy = "proxy";
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
host_or_proxy = "host";
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
@@ -509,6 +512,9 @@ static CURLcode resolver_error(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'entry' may be NULL and then no data is returned
|
||||
*/
|
||||
static CURLcode thread_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry,
|
||||
bool report)
|
||||
@@ -593,6 +599,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
int done = 0;
|
||||
|
||||
DEBUGASSERT(entry);
|
||||
*entry = NULL;
|
||||
|
||||
if(!td) {
|
||||
@@ -618,8 +625,8 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
else {
|
||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||
/* should be fine even if this converts to 32 bit */
|
||||
time_t elapsed = (time_t)Curl_timediff(Curl_now(),
|
||||
data->progress.t_startsingle);
|
||||
timediff_t elapsed = Curl_timediff(Curl_now(),
|
||||
data->progress.t_startsingle);
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
@@ -644,7 +651,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
int ret_val = 0;
|
||||
time_t milli;
|
||||
timediff_t milli;
|
||||
timediff_t ms;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||
@@ -668,7 +675,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
if(ms < 3)
|
||||
milli = 0;
|
||||
else if(ms <= 50)
|
||||
milli = (time_t)ms/3;
|
||||
milli = ms/3;
|
||||
else if(ms <= 250)
|
||||
milli = 50;
|
||||
else
|
||||
@@ -686,10 +693,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||
@@ -714,10 +721,10 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
int pf = PF_INET;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -153,10 +153,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
* Each resolver backend must of course make sure to return data in the
|
||||
* correct format to comply with this.
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
/* convert these functions if an asynch resolver isn't used */
|
||||
|
||||
@@ -49,53 +49,51 @@ static void conn_llist_dtor(void *user, void *element)
|
||||
conn->bundle = NULL;
|
||||
}
|
||||
|
||||
static CURLcode bundle_create(struct Curl_easy *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
static CURLcode bundle_create(struct connectbundle **bundlep)
|
||||
{
|
||||
(void)data;
|
||||
DEBUGASSERT(*cb_ptr == NULL);
|
||||
*cb_ptr = malloc(sizeof(struct connectbundle));
|
||||
if(!*cb_ptr)
|
||||
DEBUGASSERT(*bundlep == NULL);
|
||||
*bundlep = malloc(sizeof(struct connectbundle));
|
||||
if(!*bundlep)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(*cb_ptr)->num_connections = 0;
|
||||
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
||||
(*bundlep)->num_connections = 0;
|
||||
(*bundlep)->multiuse = BUNDLE_UNKNOWN;
|
||||
|
||||
Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
|
||||
Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||
static void bundle_destroy(struct connectbundle *bundle)
|
||||
{
|
||||
if(!cb_ptr)
|
||||
if(!bundle)
|
||||
return;
|
||||
|
||||
Curl_llist_destroy(&cb_ptr->conn_list, NULL);
|
||||
Curl_llist_destroy(&bundle->conn_list, NULL);
|
||||
|
||||
free(cb_ptr);
|
||||
free(bundle);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
static void bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
static void bundle_add_conn(struct connectbundle *bundle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
|
||||
Curl_llist_insert_next(&bundle->conn_list, bundle->conn_list.tail, conn,
|
||||
&conn->bundle_node);
|
||||
conn->bundle = cb_ptr;
|
||||
cb_ptr->num_connections++;
|
||||
conn->bundle = bundle;
|
||||
bundle->num_connections++;
|
||||
}
|
||||
|
||||
/* Remove a connection from a bundle */
|
||||
static int bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
static int bundle_remove_conn(struct connectbundle *bundle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = cb_ptr->conn_list.head;
|
||||
curr = bundle->conn_list.head;
|
||||
while(curr) {
|
||||
if(curr->ptr == conn) {
|
||||
Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
|
||||
cb_ptr->num_connections--;
|
||||
Curl_llist_remove(&bundle->conn_list, curr, NULL);
|
||||
bundle->num_connections--;
|
||||
conn->bundle = NULL;
|
||||
return 1; /* we removed a handle */
|
||||
}
|
||||
@@ -145,12 +143,15 @@ static void hashkey(struct connectdata *conn, char *buf,
|
||||
const char *hostname;
|
||||
long port = conn->remote_port;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
hostname = conn->http_proxy.host.name;
|
||||
port = conn->port;
|
||||
}
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
#endif
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
@@ -162,20 +163,15 @@ static void hashkey(struct connectdata *conn, char *buf,
|
||||
msnprintf(buf, len, "%ld%s", port, hostname);
|
||||
}
|
||||
|
||||
void Curl_conncache_unlock(struct Curl_easy *data)
|
||||
{
|
||||
CONN_UNLOCK(data);
|
||||
}
|
||||
|
||||
/* Returns number of connections currently held in the connection cache.
|
||||
Locks/unlocks the cache itself!
|
||||
*/
|
||||
size_t Curl_conncache_size(struct Curl_easy *data)
|
||||
{
|
||||
size_t num;
|
||||
CONN_LOCK(data);
|
||||
CONNCACHE_LOCK(data);
|
||||
num = data->state.conn_cache->num_conn;
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -188,7 +184,7 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
const char **hostp)
|
||||
{
|
||||
struct connectbundle *bundle = NULL;
|
||||
CONN_LOCK(conn->data);
|
||||
CONNCACHE_LOCK(conn->data);
|
||||
if(connc) {
|
||||
char key[HASHKEY_SIZE];
|
||||
hashkey(conn, key, sizeof(key), hostp);
|
||||
@@ -235,8 +231,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectbundle *bundle;
|
||||
struct connectbundle *new_bundle = NULL;
|
||||
struct connectbundle *bundle = NULL;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* *find_bundle() locks the connection cache */
|
||||
@@ -245,20 +240,19 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
int rc;
|
||||
char key[HASHKEY_SIZE];
|
||||
|
||||
result = bundle_create(data, &new_bundle);
|
||||
result = bundle_create(&bundle);
|
||||
if(result) {
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hashkey(conn, key, sizeof(key), NULL);
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, bundle);
|
||||
|
||||
if(!rc) {
|
||||
bundle_destroy(new_bundle);
|
||||
bundle_destroy(bundle);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto unlock;
|
||||
}
|
||||
bundle = new_bundle;
|
||||
}
|
||||
|
||||
bundle_add_conn(bundle, conn);
|
||||
@@ -270,15 +264,17 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
conn->connection_id, connc->num_conn));
|
||||
|
||||
unlock:
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the connectdata object from the connection cache *and* clears the
|
||||
* ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
|
||||
* depending on if the parent function already holds the lock or not.
|
||||
* Removes the connectdata object from the connection cache, but does *not*
|
||||
* clear the conn->data association. The transfer still owns this connection.
|
||||
*
|
||||
* Pass TRUE/FALSE in the 'lock' argument depending on if the parent function
|
||||
* already holds the lock or not.
|
||||
*/
|
||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool lock)
|
||||
@@ -290,7 +286,7 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
due to a failed connection attempt, before being added to a bundle */
|
||||
if(bundle) {
|
||||
if(lock) {
|
||||
CONN_LOCK(data);
|
||||
CONNCACHE_LOCK(data);
|
||||
}
|
||||
bundle_remove_conn(bundle, conn);
|
||||
if(bundle->num_connections == 0)
|
||||
@@ -301,9 +297,8 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
connc->num_conn));
|
||||
}
|
||||
conn->data = NULL; /* clear the association */
|
||||
if(lock) {
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,7 +327,7 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
if(!connc)
|
||||
return FALSE;
|
||||
|
||||
CONN_LOCK(data);
|
||||
CONNCACHE_LOCK(data);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
@@ -350,12 +345,12 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
curr = curr->next;
|
||||
|
||||
if(1 == func(conn, param)) {
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -494,7 +489,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
|
||||
now = Curl_now();
|
||||
|
||||
CONN_LOCK(data);
|
||||
CONNCACHE_LOCK(data);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
@@ -531,7 +526,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
connc->num_conn));
|
||||
conn_candidate->data = data; /* associate! */
|
||||
}
|
||||
CONN_UNLOCK(data);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
|
||||
return conn_candidate;
|
||||
}
|
||||
@@ -539,6 +534,11 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
{
|
||||
struct connectdata *conn;
|
||||
char buffer[READBUFFER_MIN + 1];
|
||||
if(!connc->closure_handle)
|
||||
return;
|
||||
connc->closure_handle->state.buffer = buffer;
|
||||
connc->closure_handle->set.buffer_size = READBUFFER_MIN;
|
||||
|
||||
conn = conncache_find_first_connection(connc);
|
||||
while(conn) {
|
||||
@@ -548,12 +548,14 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
sigpipe_ignore(conn->data, &pipe_st);
|
||||
/* This will remove the connection from the cache */
|
||||
connclose(conn, "kill all");
|
||||
Curl_conncache_remove_conn(conn->data, conn, TRUE);
|
||||
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
conn = conncache_find_first_connection(connc);
|
||||
}
|
||||
|
||||
connc->closure_handle->state.buffer = NULL;
|
||||
if(connc->closure_handle) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
||||
|
||||
@@ -45,21 +45,21 @@ struct conncache {
|
||||
#ifdef CURLDEBUG
|
||||
/* the debug versions of these macros make extra certain that the lock is
|
||||
never doubly locked or unlocked */
|
||||
#define CONN_LOCK(x) if((x)->share) { \
|
||||
#define CONNCACHE_LOCK(x) if((x)->share) { \
|
||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \
|
||||
DEBUGASSERT(!(x)->state.conncache_lock); \
|
||||
(x)->state.conncache_lock = TRUE; \
|
||||
}
|
||||
|
||||
#define CONN_UNLOCK(x) if((x)->share) { \
|
||||
#define CONNCACHE_UNLOCK(x) if((x)->share) { \
|
||||
DEBUGASSERT((x)->state.conncache_lock); \
|
||||
(x)->state.conncache_lock = FALSE; \
|
||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \
|
||||
}
|
||||
#else
|
||||
#define CONN_LOCK(x) if((x)->share) \
|
||||
#define CONNCACHE_LOCK(x) if((x)->share) \
|
||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
|
||||
#define CONN_UNLOCK(x) if((x)->share) \
|
||||
#define CONNCACHE_UNLOCK(x) if((x)->share) \
|
||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
|
||||
#endif
|
||||
|
||||
@@ -77,7 +77,6 @@ void Curl_conncache_destroy(struct conncache *connc);
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc,
|
||||
const char **hostp);
|
||||
void Curl_conncache_unlock(struct Curl_easy *data);
|
||||
/* returns number of connections currently held in the connection cache */
|
||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
||||
|
||||
|
||||
@@ -166,12 +166,13 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
|
||||
static CURLcode
|
||||
singleipconnect(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai, /* start connecting to this */
|
||||
int sockindex); /* 0 or 1 among the temp ones */
|
||||
const struct Curl_addrinfo *ai, /* start connecting to this */
|
||||
int tempindex); /* 0 or 1 among the temp ones */
|
||||
|
||||
/*
|
||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||
* transfer/connection. If the value is negative, the timeout time has already
|
||||
* transfer/connection. If the value is 0, there's no timeout (ie there's
|
||||
* infinite time left). If the value is negative, the timeout time has already
|
||||
* elapsed.
|
||||
*
|
||||
* The start time is stored in progress.t_startsingle - as set with
|
||||
@@ -555,13 +556,27 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Used within the multi interface. Try next IP address, return TRUE if no
|
||||
/* update tempaddr[tempindex] (to the next entry), makes sure to stick
|
||||
to the correct family */
|
||||
static struct Curl_addrinfo *ainext(struct connectdata *conn,
|
||||
int tempindex,
|
||||
bool next) /* use next entry? */
|
||||
{
|
||||
struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
|
||||
if(ai && next)
|
||||
ai = ai->ai_next;
|
||||
while(ai && (ai->ai_family != conn->tempfamily[tempindex]))
|
||||
ai = ai->ai_next;
|
||||
conn->tempaddr[tempindex] = ai;
|
||||
return ai;
|
||||
}
|
||||
|
||||
/* Used within the multi interface. Try next IP address, returns error if no
|
||||
more address exists or error */
|
||||
static CURLcode trynextip(struct connectdata *conn,
|
||||
int sockindex,
|
||||
int tempindex)
|
||||
{
|
||||
const int other = tempindex ^ 1;
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
|
||||
/* First clean up after the failed socket.
|
||||
@@ -572,38 +587,15 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
conn->tempsock[tempindex] = CURL_SOCKET_BAD;
|
||||
|
||||
if(sockindex == FIRSTSOCKET) {
|
||||
Curl_addrinfo *ai = NULL;
|
||||
int family = AF_UNSPEC;
|
||||
|
||||
if(conn->tempaddr[tempindex]) {
|
||||
/* find next address in the same protocol family */
|
||||
family = conn->tempaddr[tempindex]->ai_family;
|
||||
ai = conn->tempaddr[tempindex]->ai_next;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(conn->tempaddr[0]) {
|
||||
/* happy eyeballs - try the other protocol family */
|
||||
int firstfamily = conn->tempaddr[0]->ai_family;
|
||||
family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
|
||||
ai = conn->tempaddr[0]->ai_next;
|
||||
}
|
||||
#endif
|
||||
struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
|
||||
|
||||
while(ai) {
|
||||
if(conn->tempaddr[other]) {
|
||||
/* we can safely skip addresses of the other protocol family */
|
||||
while(ai && ai->ai_family != family)
|
||||
ai = ai->ai_next;
|
||||
}
|
||||
|
||||
if(ai) {
|
||||
result = singleipconnect(conn, ai, tempindex);
|
||||
if(result == CURLE_COULDNT_CONNECT) {
|
||||
ai = ai->ai_next;
|
||||
ai = ainext(conn, tempindex, TRUE);
|
||||
continue;
|
||||
}
|
||||
|
||||
conn->tempaddr[tempindex] = ai;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -688,58 +680,56 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
connection */
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
if(conn->transport != TRNSPRT_TCP)
|
||||
/* there's no TCP connection! */
|
||||
return;
|
||||
|
||||
if(conn->transport == TRNSPRT_TCP) {
|
||||
#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
char buffer[STRERROR_LEN];
|
||||
struct Curl_sockaddr_storage ssrem;
|
||||
struct Curl_sockaddr_storage ssloc;
|
||||
curl_socklen_t plen;
|
||||
curl_socklen_t slen;
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
char buffer[STRERROR_LEN];
|
||||
struct Curl_sockaddr_storage ssrem;
|
||||
struct Curl_sockaddr_storage ssloc;
|
||||
curl_socklen_t plen;
|
||||
curl_socklen_t slen;
|
||||
#ifdef HAVE_GETPEERNAME
|
||||
plen = sizeof(struct Curl_sockaddr_storage);
|
||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
plen = sizeof(struct Curl_sockaddr_storage);
|
||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
slen = sizeof(struct Curl_sockaddr_storage);
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
slen = sizeof(struct Curl_sockaddr_storage);
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETPEERNAME
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
|
||||
conn->primary_ip, &conn->primary_port)) {
|
||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
|
||||
conn->primary_ip, &conn->primary_port)) {
|
||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
#endif
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
conn->local_ip, &conn->local_port)) {
|
||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
conn->local_ip, &conn->local_port)) {
|
||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
|
||||
(void)sockfd; /* unused */
|
||||
(void)sockfd; /* unused */
|
||||
#endif
|
||||
} /* end of TCP-only section */
|
||||
|
||||
/* persist connection info in session handle */
|
||||
Curl_persistconninfo(conn);
|
||||
@@ -757,8 +747,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->bits.socksproxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.socksproxy) {
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
@@ -791,11 +781,12 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
|
||||
failf(conn->data, "unknown proxytype option given");
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
} /* switch proxytype */
|
||||
#else
|
||||
(void)sockindex;
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
}
|
||||
else
|
||||
#else
|
||||
(void)conn;
|
||||
(void)sockindex;
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
*done = TRUE; /* no SOCKS proxy, so consider us connected */
|
||||
|
||||
return result;
|
||||
@@ -816,6 +807,7 @@ static void post_SOCKS(struct connectdata *conn,
|
||||
Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
|
||||
Curl_updateconninfo(conn, conn->sock[sockindex]);
|
||||
Curl_verboseconnect(conn);
|
||||
conn->data->info.numconnects++; /* to track the number of connections made */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -831,8 +823,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
timediff_t allow;
|
||||
int error = 0;
|
||||
struct curltime now;
|
||||
int rc;
|
||||
int i;
|
||||
int rc = 0;
|
||||
unsigned int i;
|
||||
|
||||
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||
|
||||
@@ -867,47 +859,50 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
const int other = i ^ 1;
|
||||
if(conn->tempsock[i] == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
|
||||
error = 0;
|
||||
#ifdef ENABLE_QUIC
|
||||
if(conn->transport == TRNSPRT_QUIC) {
|
||||
result = Curl_quic_is_connected(conn, i, connected);
|
||||
if(result) {
|
||||
error = SOCKERRNO;
|
||||
goto error;
|
||||
}
|
||||
if(*connected) {
|
||||
if(!result && *connected) {
|
||||
/* use this socket from now on */
|
||||
conn->sock[sockindex] = conn->tempsock[i];
|
||||
conn->ip_addr = conn->tempaddr[i];
|
||||
conn->tempsock[i] = CURL_SOCKET_BAD;
|
||||
post_SOCKS(conn, sockindex, connected);
|
||||
connkeep(conn, "HTTP/3 default");
|
||||
return CURLE_OK;
|
||||
}
|
||||
return result;
|
||||
if(result)
|
||||
error = SOCKERRNO;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
#ifdef mpeix
|
||||
/* Call this function once now, and ignore the results. We do this to
|
||||
"clear" the error state on the socket so that we can later read it
|
||||
reliably. This is reported necessary on the MPE/iX operating system. */
|
||||
(void)verifyconnect(conn->tempsock[i], NULL);
|
||||
/* Call this function once now, and ignore the results. We do this to
|
||||
"clear" the error state on the socket so that we can later read it
|
||||
reliably. This is reported necessary on the MPE/iX operating
|
||||
system. */
|
||||
(void)verifyconnect(conn->tempsock[i], NULL);
|
||||
#endif
|
||||
|
||||
/* check socket for connect */
|
||||
rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
|
||||
/* check socket for connect */
|
||||
rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
|
||||
}
|
||||
|
||||
if(rc == 0) { /* no connection yet */
|
||||
error = 0;
|
||||
if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
||||
if(Curl_timediff(now, conn->connecttime) >=
|
||||
conn->timeoutms_per_addr[i]) {
|
||||
infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
|
||||
"ms connect time, move on!\n", conn->timeoutms_per_addr);
|
||||
"ms connect time, move on!\n", conn->timeoutms_per_addr[i]);
|
||||
error = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* should we try another protocol family? */
|
||||
if(i == 0 && conn->tempaddr[1] == NULL &&
|
||||
if(i == 0 && !conn->bits.parallel_connect &&
|
||||
(Curl_timediff(now, conn->connecttime) >=
|
||||
data->set.happy_eyeballs_timeout)) {
|
||||
conn->bits.parallel_connect = TRUE; /* starting now */
|
||||
trynextip(conn, sockindex, 1);
|
||||
}
|
||||
}
|
||||
@@ -944,9 +939,6 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
else if(rc & CURL_CSELECT_ERR)
|
||||
(void)verifyconnect(conn->tempsock[i], &error);
|
||||
|
||||
#ifdef ENABLE_QUIC
|
||||
error:
|
||||
#endif
|
||||
/*
|
||||
* The connection failed here, we should attempt to connect to the "next
|
||||
* address" for the given host. But first remember the latest error.
|
||||
@@ -959,15 +951,16 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
char buffer[STRERROR_LEN];
|
||||
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
|
||||
#endif
|
||||
Curl_printable_address(conn->tempaddr[i], ipaddress,
|
||||
sizeof(ipaddress));
|
||||
infof(data, "connect to %s port %ld failed: %s\n",
|
||||
ipaddress, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
#endif
|
||||
|
||||
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
|
||||
conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
|
||||
allow : allow / 2;
|
||||
|
||||
ainext(conn, i, TRUE);
|
||||
status = trynextip(conn, sockindex, i);
|
||||
if((status != CURLE_COULDNT_CONNECT) ||
|
||||
conn->tempsock[other] == CURL_SOCKET_BAD)
|
||||
@@ -977,25 +970,28 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
if(result) {
|
||||
if(result &&
|
||||
(conn->tempsock[0] == CURL_SOCKET_BAD) &&
|
||||
(conn->tempsock[1] == CURL_SOCKET_BAD)) {
|
||||
/* no more addresses to try */
|
||||
const char *hostname;
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
/* if the first address family runs out of addresses to try before
|
||||
the happy eyeball timeout, go ahead and try the next family now */
|
||||
if(conn->tempaddr[1] == NULL) {
|
||||
result = trynextip(conn, sockindex, 1);
|
||||
if(!result)
|
||||
return result;
|
||||
}
|
||||
/* if the first address family runs out of addresses to try before the
|
||||
happy eyeball timeout, go ahead and try the next family now */
|
||||
result = trynextip(conn, sockindex, 1);
|
||||
if(!result)
|
||||
return result;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
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
|
||||
#endif
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
@@ -1003,6 +999,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
hostname, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
Curl_quic_disconnect(conn, 0);
|
||||
Curl_quic_disconnect(conn, 1);
|
||||
|
||||
#ifdef WSAETIMEDOUT
|
||||
if(WSAETIMEDOUT == data->state.os_errno)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
@@ -1011,6 +1010,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = CURLE_OK; /* still trying */
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1112,8 +1113,8 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
* having connected.
|
||||
*/
|
||||
static CURLcode singleipconnect(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai,
|
||||
int sockindex)
|
||||
const struct Curl_addrinfo *ai,
|
||||
int tempindex)
|
||||
{
|
||||
struct Curl_sockaddr_ex addr;
|
||||
int rc = -1;
|
||||
@@ -1129,15 +1130,12 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
int optval = 1;
|
||||
#endif
|
||||
char buffer[STRERROR_LEN];
|
||||
curl_socket_t *sockp = &conn->tempsock[sockindex];
|
||||
curl_socket_t *sockp = &conn->tempsock[tempindex];
|
||||
*sockp = CURL_SOCKET_BAD;
|
||||
|
||||
result = Curl_socket(conn, ai, &addr, &sockfd);
|
||||
if(result)
|
||||
/* Failed to create the socket, but still return OK since we signal the
|
||||
lack of socket as well. This allows the parent function to keep looping
|
||||
over alternative addresses/socket families etc. */
|
||||
return CURLE_OK;
|
||||
return result;
|
||||
|
||||
/* store remote address and port used in this connection attempt */
|
||||
if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen,
|
||||
@@ -1205,8 +1203,10 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
(void)curlx_nonblock(sockfd, TRUE);
|
||||
|
||||
conn->connecttime = Curl_now();
|
||||
if(conn->num_addr > 1)
|
||||
Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME);
|
||||
if(conn->num_addr > 1) {
|
||||
Curl_expire(data, conn->timeoutms_per_addr[0], EXPIRE_DNS_PER_NAME);
|
||||
Curl_expire(data, conn->timeoutms_per_addr[1], EXPIRE_DNS_PER_NAME2);
|
||||
}
|
||||
|
||||
/* Connect TCP and QUIC sockets */
|
||||
if(!isconnected && (conn->transport != TRNSPRT_UDP)) {
|
||||
@@ -1257,7 +1257,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
else if(conn->transport == TRNSPRT_QUIC) {
|
||||
/* pass in 'sockfd' separately since it hasn't been put into the
|
||||
tempsock array at this point */
|
||||
result = Curl_quic_connect(conn, sockfd, sockindex,
|
||||
result = Curl_quic_connect(conn, sockfd, tempindex,
|
||||
&addr.sa_addr, addr.addrlen);
|
||||
if(result)
|
||||
error = SOCKERRNO;
|
||||
@@ -1315,7 +1315,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct curltime before = Curl_now();
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
|
||||
int i;
|
||||
timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
@@ -1325,30 +1325,37 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
|
||||
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
||||
conn->tempaddr[0] = remotehost->addr;
|
||||
conn->tempaddr[1] = NULL;
|
||||
conn->tempsock[0] = CURL_SOCKET_BAD;
|
||||
conn->tempsock[1] = CURL_SOCKET_BAD;
|
||||
conn->tempaddr[0] = conn->tempaddr[1] = remotehost->addr;
|
||||
conn->tempsock[0] = conn->tempsock[1] = CURL_SOCKET_BAD;
|
||||
|
||||
/* Max time for the next connection attempt */
|
||||
conn->timeoutms_per_addr =
|
||||
conn->timeoutms_per_addr[0] =
|
||||
conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
|
||||
conn->timeoutms_per_addr[1] =
|
||||
conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
|
||||
|
||||
/* start connecting to first IP */
|
||||
while(conn->tempaddr[0]) {
|
||||
result = singleipconnect(conn, conn->tempaddr[0], 0);
|
||||
if(!result)
|
||||
break;
|
||||
conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
|
||||
conn->tempfamily[0] = conn->tempaddr[0]?
|
||||
conn->tempaddr[0]->ai_family:0;
|
||||
conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
|
||||
AF_INET : AF_INET6;
|
||||
ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
|
||||
|
||||
DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
|
||||
conn->tempfamily[0] == AF_INET ? "v4" : "v6",
|
||||
conn->tempfamily[1] == AF_INET ? "v4" : "v6"));
|
||||
|
||||
/* get through the list in family order in case of quick failures */
|
||||
for(i = 0; (i < 2) && result; i++) {
|
||||
while(conn->tempaddr[i]) {
|
||||
result = singleipconnect(conn, conn->tempaddr[i], i);
|
||||
if(!result)
|
||||
break;
|
||||
ainext(conn, i, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if(conn->tempsock[0] == CURL_SOCKET_BAD) {
|
||||
if(!result)
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
data->info.numconnects++; /* to track the number of connections made */
|
||||
Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
|
||||
EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
@@ -1448,11 +1455,11 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
curl_socket_t sock)
|
||||
{
|
||||
if(conn && conn->fclosesocket) {
|
||||
if((sock == conn->sock[SECONDARYSOCKET]) && conn->sock_accepted)
|
||||
if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
|
||||
/* if this socket matches the second socket, and that was created with
|
||||
accept, then we MUST NOT call the callback but clear the accepted
|
||||
status */
|
||||
conn->sock_accepted = FALSE;
|
||||
conn->bits.sock_accepted = FALSE;
|
||||
else {
|
||||
int rc;
|
||||
Curl_multi_closed(conn->data, sock);
|
||||
@@ -1482,7 +1489,7 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_socket(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
@@ -1564,6 +1571,7 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
/* close if a connection, or a stream that isn't multiplexed */
|
||||
bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
|
||||
DEBUGASSERT(conn);
|
||||
if((ctrl == CONNCTRL_STREAM) &&
|
||||
(conn->handler->flags & PROTOPT_STREAM))
|
||||
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
|
||||
@@ -1579,6 +1587,7 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
int readable;
|
||||
DEBUGASSERT(conn);
|
||||
|
||||
if(Curl_ssl_data_pending(conn, sockindex) ||
|
||||
Curl_recv_has_postponed_data(conn, sockindex))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -105,7 +105,7 @@ struct Curl_sockaddr_ex {
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_socket(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -81,11 +81,11 @@ typedef enum {
|
||||
} zlibInitState;
|
||||
|
||||
/* Writer parameters. */
|
||||
typedef struct {
|
||||
struct zlib_params {
|
||||
zlibInitState zlib_init; /* zlib init state */
|
||||
uInt trailerlen; /* Remaining trailer byte count. */
|
||||
z_stream z; /* State structure for zlib. */
|
||||
} zlib_params;
|
||||
};
|
||||
|
||||
|
||||
static voidpf
|
||||
@@ -133,7 +133,8 @@ exit_zlib(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
|
||||
static CURLcode process_trailer(struct connectdata *conn,
|
||||
struct zlib_params *zp)
|
||||
{
|
||||
z_stream *z = &zp->z;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -157,9 +158,10 @@ static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
|
||||
}
|
||||
|
||||
static CURLcode inflate_stream(struct connectdata *conn,
|
||||
contenc_writer *writer, zlibInitState started)
|
||||
struct contenc_writer *writer,
|
||||
zlibInitState started)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
uInt nread = z->avail_in;
|
||||
Bytef *orig_in = z->next_in;
|
||||
@@ -259,9 +261,9 @@ static CURLcode inflate_stream(struct connectdata *conn,
|
||||
|
||||
/* Deflate handler. */
|
||||
static CURLcode deflate_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!writer->downstream)
|
||||
@@ -278,10 +280,10 @@ static CURLcode deflate_init_writer(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static CURLcode deflate_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
/* Set the compressed input when this function is called */
|
||||
@@ -296,29 +298,29 @@ static CURLcode deflate_unencode_write(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static void deflate_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
|
||||
}
|
||||
|
||||
static const content_encoding deflate_encoding = {
|
||||
static const struct content_encoding deflate_encoding = {
|
||||
"deflate",
|
||||
NULL,
|
||||
deflate_init_writer,
|
||||
deflate_unencode_write,
|
||||
deflate_close_writer,
|
||||
sizeof(zlib_params)
|
||||
sizeof(struct zlib_params)
|
||||
};
|
||||
|
||||
|
||||
/* Gzip handler. */
|
||||
static CURLcode gzip_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!writer->downstream)
|
||||
@@ -432,10 +434,10 @@ static enum {
|
||||
#endif
|
||||
|
||||
static CURLcode gzip_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(zp->zlib_init == ZLIB_INIT_GZIP) {
|
||||
@@ -560,33 +562,31 @@ static CURLcode gzip_unencode_write(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static void gzip_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
zlib_params *zp = (zlib_params *) &writer->params;
|
||||
struct zlib_params *zp = (struct zlib_params *) &writer->params;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
|
||||
}
|
||||
|
||||
static const content_encoding gzip_encoding = {
|
||||
static const struct content_encoding gzip_encoding = {
|
||||
"gzip",
|
||||
"x-gzip",
|
||||
gzip_init_writer,
|
||||
gzip_unencode_write,
|
||||
gzip_close_writer,
|
||||
sizeof(zlib_params)
|
||||
sizeof(struct zlib_params)
|
||||
};
|
||||
|
||||
#endif /* HAVE_LIBZ */
|
||||
|
||||
|
||||
#ifdef HAVE_BROTLI
|
||||
|
||||
/* Writer parameters. */
|
||||
typedef struct {
|
||||
struct brotli_params {
|
||||
BrotliDecoderState *br; /* State structure for brotli. */
|
||||
} brotli_params;
|
||||
|
||||
};
|
||||
|
||||
static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
||||
{
|
||||
@@ -627,10 +627,9 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
||||
}
|
||||
|
||||
static CURLcode brotli_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
brotli_params *bp = (brotli_params *) &writer->params;
|
||||
|
||||
struct brotli_params *bp = (struct brotli_params *) &writer->params;
|
||||
(void) conn;
|
||||
|
||||
if(!writer->downstream)
|
||||
@@ -641,10 +640,10 @@ static CURLcode brotli_init_writer(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static CURLcode brotli_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
brotli_params *bp = (brotli_params *) &writer->params;
|
||||
struct brotli_params *bp = (struct brotli_params *) &writer->params;
|
||||
const uint8_t *src = (const uint8_t *) buf;
|
||||
char *decomp;
|
||||
uint8_t *dst;
|
||||
@@ -689,10 +688,9 @@ static CURLcode brotli_unencode_write(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static void brotli_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
brotli_params *bp = (brotli_params *) &writer->params;
|
||||
|
||||
struct brotli_params *bp = (struct brotli_params *) &writer->params;
|
||||
(void) conn;
|
||||
|
||||
if(bp->br) {
|
||||
@@ -701,40 +699,40 @@ static void brotli_close_writer(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
static const content_encoding brotli_encoding = {
|
||||
static const struct content_encoding brotli_encoding = {
|
||||
"br",
|
||||
NULL,
|
||||
brotli_init_writer,
|
||||
brotli_unencode_write,
|
||||
brotli_close_writer,
|
||||
sizeof(brotli_params)
|
||||
sizeof(struct brotli_params)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Identity handler. */
|
||||
static CURLcode identity_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
static CURLcode identity_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
return Curl_unencode_write(conn, writer->downstream, buf, nbytes);
|
||||
}
|
||||
|
||||
static void identity_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
(void) writer;
|
||||
}
|
||||
|
||||
static const content_encoding identity_encoding = {
|
||||
static const struct content_encoding identity_encoding = {
|
||||
"identity",
|
||||
"none",
|
||||
identity_init_writer,
|
||||
@@ -745,7 +743,7 @@ static const content_encoding identity_encoding = {
|
||||
|
||||
|
||||
/* supported content encodings table. */
|
||||
static const content_encoding * const encodings[] = {
|
||||
static const struct content_encoding * const encodings[] = {
|
||||
&identity_encoding,
|
||||
#ifdef HAVE_LIBZ
|
||||
&deflate_encoding,
|
||||
@@ -762,8 +760,8 @@ static const content_encoding * const encodings[] = {
|
||||
char *Curl_all_content_encodings(void)
|
||||
{
|
||||
size_t len = 0;
|
||||
const content_encoding * const *cep;
|
||||
const content_encoding *ce;
|
||||
const struct content_encoding * const *cep;
|
||||
const struct content_encoding *ce;
|
||||
char *ace;
|
||||
|
||||
for(cep = encodings; *cep; cep++) {
|
||||
@@ -796,14 +794,14 @@ char *Curl_all_content_encodings(void)
|
||||
|
||||
/* Real client writer: no downstream. */
|
||||
static CURLcode client_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode client_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
@@ -818,13 +816,13 @@ static CURLcode client_unencode_write(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static void client_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
(void) writer;
|
||||
}
|
||||
|
||||
static const content_encoding client_encoding = {
|
||||
static const struct content_encoding client_encoding = {
|
||||
NULL,
|
||||
NULL,
|
||||
client_init_writer,
|
||||
@@ -836,14 +834,14 @@ static const content_encoding client_encoding = {
|
||||
|
||||
/* Deferred error dummy writer. */
|
||||
static CURLcode error_init_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
static CURLcode error_unencode_write(struct connectdata *conn,
|
||||
contenc_writer *writer,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
char *all = Curl_all_content_encodings();
|
||||
@@ -861,13 +859,13 @@ static CURLcode error_unencode_write(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static void error_close_writer(struct connectdata *conn,
|
||||
contenc_writer *writer)
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) conn;
|
||||
(void) writer;
|
||||
}
|
||||
|
||||
static const content_encoding error_encoding = {
|
||||
static const struct content_encoding error_encoding = {
|
||||
NULL,
|
||||
NULL,
|
||||
error_init_writer,
|
||||
@@ -877,12 +875,13 @@ static const content_encoding error_encoding = {
|
||||
};
|
||||
|
||||
/* Create an unencoding writer stage using the given handler. */
|
||||
static contenc_writer *new_unencoding_writer(struct connectdata *conn,
|
||||
const content_encoding *handler,
|
||||
contenc_writer *downstream)
|
||||
static struct contenc_writer *
|
||||
new_unencoding_writer(struct connectdata *conn,
|
||||
const struct content_encoding *handler,
|
||||
struct contenc_writer *downstream)
|
||||
{
|
||||
size_t sz = offsetof(contenc_writer, params) + handler->paramsize;
|
||||
contenc_writer *writer = (contenc_writer *) calloc(1, sz);
|
||||
size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize;
|
||||
struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz);
|
||||
|
||||
if(writer) {
|
||||
writer->handler = handler;
|
||||
@@ -897,7 +896,8 @@ static contenc_writer *new_unencoding_writer(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Write data using an unencoding writer stack. */
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
if(!nbytes)
|
||||
@@ -910,7 +910,7 @@ void Curl_unencode_cleanup(struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
contenc_writer *writer = k->writer_stack;
|
||||
struct contenc_writer *writer = k->writer_stack;
|
||||
|
||||
while(writer) {
|
||||
k->writer_stack = writer->downstream;
|
||||
@@ -921,12 +921,13 @@ void Curl_unencode_cleanup(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Find the content encoding by name. */
|
||||
static const content_encoding *find_encoding(const char *name, size_t len)
|
||||
static const struct content_encoding *find_encoding(const char *name,
|
||||
size_t len)
|
||||
{
|
||||
const content_encoding * const *cep;
|
||||
const struct content_encoding * const *cep;
|
||||
|
||||
for(cep = encodings; *cep; cep++) {
|
||||
const content_encoding *ce = *cep;
|
||||
const struct content_encoding *ce = *cep;
|
||||
if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
|
||||
(ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
|
||||
return ce;
|
||||
@@ -962,8 +963,8 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
|
||||
Curl_httpchunk_init(conn); /* init our chunky engine. */
|
||||
}
|
||||
else if(namelen) {
|
||||
const content_encoding *encoding = find_encoding(name, namelen);
|
||||
contenc_writer *writer;
|
||||
const struct content_encoding *encoding = find_encoding(name, namelen);
|
||||
struct contenc_writer *writer;
|
||||
|
||||
if(!k->writer_stack) {
|
||||
k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL);
|
||||
@@ -997,7 +998,8 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
(void) conn;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,31 +23,31 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* Decoding writer. */
|
||||
typedef struct contenc_writer_s contenc_writer;
|
||||
typedef struct content_encoding_s content_encoding;
|
||||
|
||||
struct contenc_writer_s {
|
||||
const content_encoding *handler; /* Encoding handler. */
|
||||
contenc_writer *downstream; /* Downstream writer. */
|
||||
struct contenc_writer {
|
||||
const struct content_encoding *handler; /* Encoding handler. */
|
||||
struct contenc_writer *downstream; /* Downstream writer. */
|
||||
void *params; /* Encoding-specific storage (variable length). */
|
||||
};
|
||||
|
||||
/* Content encoding writer. */
|
||||
struct content_encoding_s {
|
||||
struct content_encoding {
|
||||
const char *name; /* Encoding name. */
|
||||
const char *alias; /* Encoding name alias. */
|
||||
CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer);
|
||||
CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer,
|
||||
CURLcode (*init_writer)(struct connectdata *conn,
|
||||
struct contenc_writer *writer);
|
||||
CURLcode (*unencode_write)(struct connectdata *conn,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void (*close_writer)(struct connectdata *conn, contenc_writer *writer);
|
||||
void (*close_writer)(struct connectdata *conn,
|
||||
struct contenc_writer *writer);
|
||||
size_t paramsize;
|
||||
};
|
||||
|
||||
|
||||
CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
|
||||
const char *enclist, int maybechunked);
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void Curl_unencode_cleanup(struct connectdata *conn);
|
||||
char *Curl_all_content_encodings(void);
|
||||
|
||||
@@ -245,18 +245,17 @@ pathmatched:
|
||||
*/
|
||||
static const char *get_top_domain(const char * const domain, size_t *outlen)
|
||||
{
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
const char *first = NULL, *last;
|
||||
|
||||
if(!domain)
|
||||
return NULL;
|
||||
|
||||
len = strlen(domain);
|
||||
last = memrchr(domain, '.', len);
|
||||
if(last) {
|
||||
first = memrchr(domain, '.', (last - domain));
|
||||
if(first)
|
||||
len -= (++first - domain);
|
||||
if(domain) {
|
||||
len = strlen(domain);
|
||||
last = memrchr(domain, '.', len);
|
||||
if(last) {
|
||||
first = memrchr(domain, '.', (last - domain));
|
||||
if(first)
|
||||
len -= (++first - domain);
|
||||
}
|
||||
}
|
||||
|
||||
if(outlen)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,10 +50,6 @@
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && defined(USE_UNIX_SOCKETS)
|
||||
#include <afunix.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
@@ -82,16 +78,13 @@
|
||||
#endif
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead)
|
||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
||||
{
|
||||
Curl_addrinfo *vqualifier canext;
|
||||
Curl_addrinfo *ca;
|
||||
struct Curl_addrinfo *vqualifier canext;
|
||||
struct Curl_addrinfo *ca;
|
||||
|
||||
for(ca = cahead; ca != NULL; ca = canext) {
|
||||
free(ca->ai_addr);
|
||||
free(ca->ai_canonname);
|
||||
for(ca = cahead; ca; ca = canext) {
|
||||
canext = ca->ai_next;
|
||||
|
||||
free(ca);
|
||||
}
|
||||
}
|
||||
@@ -116,13 +109,13 @@ int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result)
|
||||
struct Curl_addrinfo **result)
|
||||
{
|
||||
const struct addrinfo *ai;
|
||||
struct addrinfo *aihead;
|
||||
Curl_addrinfo *cafirst = NULL;
|
||||
Curl_addrinfo *calast = NULL;
|
||||
Curl_addrinfo *ca;
|
||||
struct Curl_addrinfo *cafirst = NULL;
|
||||
struct Curl_addrinfo *calast = NULL;
|
||||
struct Curl_addrinfo *ca;
|
||||
size_t ss_size;
|
||||
int error;
|
||||
|
||||
@@ -135,7 +128,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
/* traverse the addrinfo list */
|
||||
|
||||
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
|
||||
|
||||
size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0;
|
||||
/* ignore elements with unsupported address family, */
|
||||
/* settle family-specific sockaddr structure size. */
|
||||
if(ai->ai_family == AF_INET)
|
||||
@@ -155,7 +148,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(Curl_addrinfo));
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
@@ -173,22 +166,12 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
ca->ai_addr = malloc(ss_size);
|
||||
if(!ca->ai_addr) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
ca->ai_canonname = strdup(ai->ai_canonname);
|
||||
if(!ca->ai_canonname) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
if(namelen) {
|
||||
ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
|
||||
memcpy(ca->ai_canonname, ai->ai_canonname, namelen);
|
||||
}
|
||||
|
||||
/* if the return list is empty, this becomes the first element */
|
||||
@@ -256,7 +239,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
* struct sockaddr *ai_addr;
|
||||
* struct Curl_addrinfo *ai_next;
|
||||
* };
|
||||
* typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
*
|
||||
* hostent defined in <netdb.h>
|
||||
*
|
||||
@@ -273,12 +255,12 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
* #define h_addr h_addr_list[0]
|
||||
*/
|
||||
|
||||
Curl_addrinfo *
|
||||
struct Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *prevai = NULL;
|
||||
Curl_addrinfo *firstai = NULL;
|
||||
struct Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *prevai = NULL;
|
||||
struct Curl_addrinfo *firstai = NULL;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
@@ -294,8 +276,8 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
|
||||
|
||||
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
size_t ss_size;
|
||||
size_t namelen = strlen(he->h_name) + 1; /* include zero termination */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof(struct sockaddr_in6);
|
||||
@@ -303,24 +285,17 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
#endif
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
/* allocate memory to told the struct, the address and the name */
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
ai->ai_canonname = strdup(he->h_name);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
/* put the address after the struct */
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
/* then put the name after the address */
|
||||
ai->ai_canonname = (char *)ai->ai_addr + ss_size;
|
||||
memcpy(ai->ai_canonname, he->h_name, namelen);
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
@@ -393,10 +368,10 @@ struct namebuff {
|
||||
* given address/host
|
||||
*/
|
||||
|
||||
Curl_addrinfo *
|
||||
struct Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *ai;
|
||||
|
||||
#if defined(__VMS) && \
|
||||
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
|
||||
@@ -469,7 +444,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
|
||||
* allocated Curl_addrinfo struct and returns it.
|
||||
*/
|
||||
Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
struct Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(Curl_inet_pton(AF_INET, address, &in) > 0)
|
||||
@@ -492,22 +467,19 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
* struct initialized with this path.
|
||||
* Set '*longpath' to TRUE if the error is a too long path.
|
||||
*/
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
bool abstract)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *ai;
|
||||
struct sockaddr_un *sa_un;
|
||||
size_t path_len;
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
@@ -515,7 +487,6 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
@@ -598,9 +569,9 @@ curl_dbg_getaddrinfo(const char *hostname,
|
||||
* Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
|
||||
* 10.11.5.
|
||||
*/
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
|
||||
void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port)
|
||||
{
|
||||
Curl_addrinfo *ca;
|
||||
struct Curl_addrinfo *ca;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Curl_addrinfo is our internal struct definition that we use to allow
|
||||
* consistent internal handling of this data. We use this even when the
|
||||
@@ -58,29 +57,29 @@ struct Curl_addrinfo {
|
||||
struct sockaddr *ai_addr;
|
||||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead);
|
||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result);
|
||||
struct Curl_addrinfo **result);
|
||||
#endif
|
||||
|
||||
Curl_addrinfo *
|
||||
struct Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port);
|
||||
|
||||
Curl_addrinfo *
|
||||
struct Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
bool abstract);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
@@ -98,7 +97,7 @@ curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef USE_RESOLVE_ON_IPS
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
|
||||
void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port);
|
||||
#else
|
||||
#define Curl_addrinfo_set_port(x,y)
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* lib/curl_config.h.in. Generated somehow by cmake. */
|
||||
|
||||
#include <cm3p/kwiml/abi.h>
|
||||
@@ -35,6 +56,9 @@
|
||||
/* to disable LDAPS */
|
||||
#cmakedefine CURL_DISABLE_LDAPS 1
|
||||
|
||||
/* to enable MQTT */
|
||||
#undef CURL_ENABLE_MQTT
|
||||
|
||||
/* to disable POP3 */
|
||||
#cmakedefine CURL_DISABLE_POP3 1
|
||||
|
||||
@@ -138,9 +162,6 @@
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
#cmakedefine HAVE_CRYPTO_H 1
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
#cmakedefine HAVE_DES_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
@@ -400,6 +421,9 @@
|
||||
/* Define to 1 if you have the <libssh2.h> header file. */
|
||||
#cmakedefine HAVE_LIBSSH2_H 1
|
||||
|
||||
/* Define to 1 if you have the <libssh/libssh.h> header file. */
|
||||
#cmakedefine HAVE_LIBSSH_LIBSSH_H 1
|
||||
|
||||
/* if zlib is available */
|
||||
#cmakedefine HAVE_LIBZ 1
|
||||
|
||||
@@ -948,6 +972,12 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if BearSSL is enabled */
|
||||
#cmakedefine USE_BEARSSL 1
|
||||
|
||||
/* if WolfSSL is enabled */
|
||||
#cmakedefine USE_WOLFSSL 1
|
||||
|
||||
/* if libSSH is in use */
|
||||
#cmakedefine USE_LIBSSH 1
|
||||
|
||||
/* if libSSH2 is in use */
|
||||
#cmakedefine USE_LIBSSH2 1
|
||||
|
||||
@@ -969,9 +999,24 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* to enable NGHTTP2 */
|
||||
#cmakedefine USE_NGHTTP2 1
|
||||
|
||||
/* to enable NGTCP2 */
|
||||
#cmakedefine USE_NGTCP2 1
|
||||
|
||||
/* to enable NGHTTP3 */
|
||||
#cmakedefine USE_NGHTTP3 1
|
||||
|
||||
/* to enable quiche */
|
||||
#cmakedefine USE_QUICHE 1
|
||||
|
||||
/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */
|
||||
#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
/* to enable alt-svc */
|
||||
#cmakedefine USE_ALTSVC 1
|
||||
|
||||
/* to enable SSPI support */
|
||||
#cmakedefine USE_WINDOWS_SSPI 1
|
||||
|
||||
|
||||
@@ -34,37 +34,35 @@ typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context);
|
||||
|
||||
|
||||
/* Per-hash function HMAC parameters. */
|
||||
|
||||
typedef struct {
|
||||
HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */
|
||||
struct HMAC_params {
|
||||
HMAC_hinit_func
|
||||
hmac_hinit; /* Initialize context procedure. */
|
||||
HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
|
||||
HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
|
||||
unsigned int hmac_ctxtsize; /* Context structure size. */
|
||||
unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
|
||||
unsigned int hmac_resultlen; /* Result length (bytes). */
|
||||
} HMAC_params;
|
||||
};
|
||||
|
||||
|
||||
/* HMAC computation context. */
|
||||
|
||||
typedef struct {
|
||||
const HMAC_params *hmac_hash; /* Hash function definition. */
|
||||
struct HMAC_context {
|
||||
const struct 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,
|
||||
unsigned int keylen);
|
||||
int Curl_HMAC_update(HMAC_context *context,
|
||||
struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key,
|
||||
unsigned int keylen);
|
||||
int Curl_HMAC_update(struct HMAC_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
|
||||
int Curl_HMAC_final(struct HMAC_context *context, unsigned char *result);
|
||||
|
||||
CURLcode Curl_hmacit(const HMAC_params *hashparams,
|
||||
CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key, const size_t keylen,
|
||||
const unsigned char *data, const size_t datalen,
|
||||
unsigned char *output);
|
||||
|
||||
@@ -33,30 +33,30 @@ typedef void (* Curl_MD5_update_func)(void *context,
|
||||
unsigned int len);
|
||||
typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
|
||||
|
||||
typedef struct {
|
||||
struct MD5_params {
|
||||
Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
|
||||
Curl_MD5_update_func md5_update_func; /* Update context with data */
|
||||
Curl_MD5_final_func md5_final_func; /* Get final result procedure */
|
||||
unsigned int md5_ctxtsize; /* Context structure size */
|
||||
unsigned int md5_resultlen; /* Result length (bytes) */
|
||||
} MD5_params;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const MD5_params *md5_hash; /* Hash function definition */
|
||||
struct MD5_context {
|
||||
const struct MD5_params *md5_hash; /* Hash function definition */
|
||||
void *md5_hashctx; /* Hash function context */
|
||||
} MD5_context;
|
||||
};
|
||||
|
||||
extern const MD5_params Curl_DIGEST_MD5[1];
|
||||
extern const HMAC_params Curl_HMAC_MD5[1];
|
||||
extern const struct MD5_params Curl_DIGEST_MD5[1];
|
||||
extern const struct HMAC_params Curl_HMAC_MD5[1];
|
||||
|
||||
void Curl_md5it(unsigned char *output, const unsigned char *input,
|
||||
const size_t len);
|
||||
|
||||
MD5_context * Curl_MD5_init(const MD5_params *md5params);
|
||||
CURLcode Curl_MD5_update(MD5_context *context,
|
||||
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
|
||||
CURLcode Curl_MD5_update(struct MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
|
||||
CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,24 +20,21 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is 'mem-include-scan' clean. See test 1132.
|
||||
*/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
#if defined(WIN32)
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
@@ -59,7 +56,7 @@ wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
return str_w;
|
||||
}
|
||||
|
||||
char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
@@ -81,4 +78,76 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
||||
#endif /* WIN32 */
|
||||
|
||||
#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
|
||||
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
FILE *result = NULL;
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w)
|
||||
result = _wfopen(filename_w, mode_w);
|
||||
free(filename_w);
|
||||
free(mode_w);
|
||||
if(result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
return (fopen)(filename, mode);
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
int result = -1;
|
||||
#ifdef _UNICODE
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
#endif /* _UNICODE */
|
||||
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
#if defined(_UNICODE)
|
||||
if(path_w)
|
||||
result = _wstat(path_w, buffer);
|
||||
else
|
||||
#endif /* _UNICODE */
|
||||
result = _stat(path, buffer);
|
||||
#else /* USE_WIN32_SMALL_FILES */
|
||||
#if defined(_UNICODE)
|
||||
if(path_w)
|
||||
result = _wstati64(path_w, buffer);
|
||||
else
|
||||
#endif /* _UNICODE */
|
||||
result = _stati64(path, buffer);
|
||||
#endif /* USE_WIN32_SMALL_FILES */
|
||||
|
||||
#ifdef _UNICODE
|
||||
free(path_w);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int curlx_win32_access(const char *path, int mode)
|
||||
{
|
||||
int result = -1;
|
||||
#ifdef _UNICODE
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
#endif /* _UNICODE */
|
||||
|
||||
#if defined(_UNICODE)
|
||||
if(path_w)
|
||||
result = _waccess(path_w, mode);
|
||||
else
|
||||
#endif /* _UNICODE */
|
||||
result = _access(path, mode);
|
||||
|
||||
#ifdef _UNICODE
|
||||
free(path_w);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,48 +23,43 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
#if defined(WIN32)
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
|
||||
char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
|
||||
wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8);
|
||||
char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w);
|
||||
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
||||
|
||||
|
||||
#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
|
||||
* and Curl_unicodefree() main purpose is to minimize the number of
|
||||
* Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8()
|
||||
* and curlx_unicodefree() main purpose is to minimize the number of
|
||||
* preprocessor conditional directives needed by code using these
|
||||
* to differentiate UNICODE from non-UNICODE builds.
|
||||
*
|
||||
* When building with UNICODE defined, this two macros
|
||||
* Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
|
||||
* When building with UNICODE defined, these two macros
|
||||
* curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
|
||||
* return a pointer to a newly allocated memory area holding result.
|
||||
* When the result is no longer needed, allocated memory is intended
|
||||
* to be free'ed with Curl_unicodefree().
|
||||
* to be free'ed with curlx_unicodefree().
|
||||
*
|
||||
* When building without UNICODE defined, this macros
|
||||
* Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
|
||||
* return the pointer received as argument. Curl_unicodefree() does
|
||||
* curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
|
||||
* return the pointer received as argument. curlx_unicodefree() does
|
||||
* no actual free'ing of this pointer it is simply set to NULL.
|
||||
*/
|
||||
|
||||
#ifdef UNICODE
|
||||
#if defined(UNICODE) && defined(WIN32)
|
||||
|
||||
#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
|
||||
#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
|
||||
#define Curl_unicodefree(ptr) \
|
||||
#define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr))
|
||||
#define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr))
|
||||
#define curlx_unicodefree(ptr) \
|
||||
do { \
|
||||
if(ptr) { \
|
||||
free(ptr); \
|
||||
(free)(ptr); \
|
||||
(ptr) = NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
@@ -78,9 +73,9 @@ typedef union {
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
|
||||
#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
|
||||
#define Curl_unicodefree(ptr) \
|
||||
#define curlx_convert_UTF8_to_tchar(ptr) (ptr)
|
||||
#define curlx_convert_tchar_to_UTF8(ptr) (ptr)
|
||||
#define curlx_unicodefree(ptr) \
|
||||
do {(ptr) = NULL;} while(0)
|
||||
|
||||
typedef union {
|
||||
@@ -90,8 +85,6 @@ typedef union {
|
||||
const unsigned char *const_tbyte_ptr;
|
||||
} xcharp_u;
|
||||
|
||||
#endif /* UNICODE */
|
||||
|
||||
#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
|
||||
#endif /* UNICODE && WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
||||
|
||||
@@ -52,13 +52,18 @@
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
|
||||
|
||||
#ifdef USE_WOLFSSL
|
||||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
# if (defined(OPENSSL_VERSION_NUMBER) && \
|
||||
(OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
|
||||
# define DES_key_schedule des_key_schedule
|
||||
# define DES_cblock des_cblock
|
||||
# define DES_set_odd_parity des_set_odd_parity
|
||||
@@ -78,14 +83,12 @@
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <gcrypt.h>
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
# include <pk11pub.h>
|
||||
# include <hasht.h>
|
||||
# define MD5_DIGEST_LENGTH MD5_LENGTH
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
@@ -138,7 +141,7 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
}
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
@@ -342,7 +345,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
|
||||
/* Acquire the crypto provider */
|
||||
if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
return FALSE;
|
||||
|
||||
/* Setup the key blob structure */
|
||||
@@ -387,7 +390,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
@@ -462,7 +465,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
|
||||
then it must be initialized to be used by NTLM. */
|
||||
#if !defined(USE_OPENSSL) && \
|
||||
!defined(USE_WOLFSSL) && \
|
||||
!defined(USE_GNUTLS_NETTLE) && \
|
||||
!defined(USE_GNUTLS) && \
|
||||
defined(USE_NSS)
|
||||
@@ -37,7 +38,10 @@
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
|
||||
#ifdef USE_WOLFSSL
|
||||
# include <wolfssl/options.h>
|
||||
#endif
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -261,15 +261,11 @@ done:
|
||||
static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
|
||||
const char *input, curlntlm state)
|
||||
{
|
||||
char *buf = malloc(NTLM_BUFSIZE);
|
||||
size_t len_in = strlen(input), len_out = 0;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) data;
|
||||
#endif
|
||||
|
||||
if(!buf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
struct dynbuf b;
|
||||
char *ptr = NULL;
|
||||
unsigned char *buf = (unsigned char *)data->state.buffer;
|
||||
Curl_dyn_init(&b, MAX_NTLM_WB_RESPONSE);
|
||||
|
||||
while(len_in > 0) {
|
||||
ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in);
|
||||
@@ -285,10 +281,8 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
|
||||
}
|
||||
/* Read one line */
|
||||
while(1) {
|
||||
ssize_t size;
|
||||
char *newbuf;
|
||||
|
||||
size = sread(ntlm->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
|
||||
ssize_t size =
|
||||
sread(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size);
|
||||
if(size == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
@@ -297,48 +291,41 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
|
||||
else if(size == 0)
|
||||
goto done;
|
||||
|
||||
len_out += size;
|
||||
if(buf[len_out - 1] == '\n') {
|
||||
buf[len_out - 1] = '\0';
|
||||
break;
|
||||
if(Curl_dyn_addn(&b, buf, size))
|
||||
goto done;
|
||||
|
||||
len_out = Curl_dyn_len(&b);
|
||||
ptr = Curl_dyn_ptr(&b);
|
||||
if(len_out && ptr[len_out - 1] == '\n') {
|
||||
ptr[len_out - 1] = '\0';
|
||||
break; /* done! */
|
||||
}
|
||||
|
||||
if(len_out > MAX_NTLM_WB_RESPONSE) {
|
||||
failf(data, "too large ntlm_wb response!");
|
||||
free(buf);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
buf = newbuf;
|
||||
/* loop */
|
||||
}
|
||||
|
||||
/* Samba/winbind installed but not configured */
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
len_out == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
ptr[0] == 'P' && ptr[1] == 'W')
|
||||
goto done;
|
||||
/* invalid response */
|
||||
if(len_out < 4)
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
(buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
|
||||
(ptr[0]!='Y' || ptr[1]!='R' || ptr[2]!=' '))
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE2 &&
|
||||
(buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
|
||||
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
|
||||
(ptr[0]!='K' || ptr[1]!='K' || ptr[2]!=' ') &&
|
||||
(ptr[0]!='A' || ptr[1]!='F' || ptr[2]!=' '))
|
||||
goto done;
|
||||
|
||||
ntlm->response = aprintf("%.*s", len_out - 4, buf + 3);
|
||||
free(buf);
|
||||
ntlm->response = strdup(ptr + 3);
|
||||
Curl_dyn_free(&b);
|
||||
if(!ntlm->response)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
done:
|
||||
free(buf);
|
||||
Curl_dyn_free(&b);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@@ -389,8 +376,7 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
|
||||
* This is for creating ntlm header output by delegating challenge/response
|
||||
* to Samba's winbind daemon helper ntlm_auth.
|
||||
*/
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
bool proxy)
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
@@ -400,6 +386,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
struct ntlmdata *ntlm;
|
||||
curlntlm *state;
|
||||
struct auth *authp;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
@@ -407,14 +394,18 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
DEBUGASSERT(conn->data);
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
allocuserpwd = &data->state.aptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
ntlm = &conn->proxyntlm;
|
||||
state = &conn->proxy_ntlm_state;
|
||||
authp = &conn->data->state.authproxy;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
allocuserpwd = &data->state.aptr.userpwd;
|
||||
userp = conn->user;
|
||||
ntlm = &conn->ntlm;
|
||||
state = &conn->http_ntlm_state;
|
||||
|
||||
@@ -264,9 +264,14 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
size_t len = 0;
|
||||
saslstate state1 = SASL_STOP;
|
||||
saslstate state2 = SASL_FINAL;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
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;
|
||||
#else
|
||||
const char * const hostname = conn->host.name;
|
||||
const long int port = conn->remote_port;
|
||||
#endif
|
||||
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
@@ -417,18 +422,23 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
saslstate newstate = SASL_FINAL;
|
||||
char *resp = NULL;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
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;
|
||||
#else
|
||||
const char * const hostname = conn->host.name;
|
||||
const long int port = conn->remote_port;
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
char *chlg = NULL;
|
||||
size_t chlglen = 0;
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
|
||||
defined(USE_NTLM)
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
|
||||
defined(USE_NTLM)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
char *serverdata;
|
||||
#endif
|
||||
size_t len = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -234,6 +234,14 @@
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Windows setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include "setup-win32.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
|
||||
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
|
||||
@@ -243,58 +251,6 @@
|
||||
#define USE_RESOLVE_ON_IPS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include header files for windows builds before redefining anything.
|
||||
* Use this preprocessor block only to include or exclude windows.h,
|
||||
* winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
|
||||
* to any other further and independent block. Under Cygwin things work
|
||||
* just as under linux (e.g. <sys/socket.h>) and the winsock headers should
|
||||
* never be included when __CYGWIN__ is defined. configure script takes
|
||||
* care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
|
||||
* neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# if defined(UNICODE) && !defined(_UNICODE)
|
||||
# define _UNICODE
|
||||
# endif
|
||||
# if defined(_UNICODE) && !defined(UNICODE)
|
||||
# define UNICODE
|
||||
# endif
|
||||
# include <winerror.h>
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# ifdef HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
# include <tchar.h>
|
||||
# ifdef UNICODE
|
||||
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
|
||||
* define USE_WINSOCK to 1 if we have and use WINSOCK API, else
|
||||
* undefine USE_WINSOCK.
|
||||
*/
|
||||
|
||||
#undef USE_WINSOCK
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# define USE_WINSOCK 2
|
||||
#else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# define USE_WINSOCK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# include <lwip/init.h>
|
||||
# include <lwip/sockets.h>
|
||||
@@ -390,9 +346,14 @@
|
||||
# undef fstat
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# undef stat
|
||||
# define stat(fname,stp) _stati64(fname, stp)
|
||||
# define stat(fname,stp) curlx_win32_stat(fname, stp)
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
|
||||
# define access(fname,mode) curlx_win32_access(fname, mode)
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
int curlx_win32_access(const char *path, int mode);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -407,8 +368,13 @@
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes,stp) _fstat(fdes, stp)
|
||||
# define stat(fname,stp) _stat(fname, stp)
|
||||
# define stat(fname,stp) curlx_win32_stat(fname, stp)
|
||||
# define struct_stat struct _stat
|
||||
# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
|
||||
# define access(fname,mode) curlx_win32_access(fname, mode)
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
int curlx_win32_access(const char *path, int mode);
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
#endif
|
||||
@@ -686,10 +652,11 @@ int netware_init(void);
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
defined(USE_MBEDTLS)
|
||||
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
defined(USE_MBEDTLS) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_SET_ODD_PARITY))
|
||||
|
||||
#define USE_NTLM
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -481,6 +481,8 @@ typedef int sig_atomic_t;
|
||||
|
||||
#ifdef __VMS
|
||||
#define argv_item_t __char_ptr32
|
||||
#elif defined(_UNICODE)
|
||||
#define argv_item_t wchar_t *
|
||||
#else
|
||||
#define argv_item_t char *
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
/* Initialize the identity */
|
||||
memset(identity, 0, sizeof(*identity));
|
||||
|
||||
useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
|
||||
useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)userp);
|
||||
if(!useranddomain.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -173,7 +173,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
/* Setup the identity's user and length */
|
||||
dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
|
||||
if(!dup_user.tchar_ptr) {
|
||||
Curl_unicodefree(useranddomain.tchar_ptr);
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
identity->User = dup_user.tbyte_ptr;
|
||||
@@ -183,7 +183,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
/* Setup the identity's domain and length */
|
||||
dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
|
||||
if(!dup_domain.tchar_ptr) {
|
||||
Curl_unicodefree(useranddomain.tchar_ptr);
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
_tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
|
||||
@@ -192,22 +192,22 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
identity->DomainLength = curlx_uztoul(domlen);
|
||||
dup_domain.tchar_ptr = NULL;
|
||||
|
||||
Curl_unicodefree(useranddomain.tchar_ptr);
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
|
||||
/* Setup the identity's password and length */
|
||||
passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
|
||||
passwd.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
|
||||
if(!dup_passwd.tchar_ptr) {
|
||||
Curl_unicodefree(passwd.tchar_ptr);
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
identity->Password = dup_passwd.tbyte_ptr;
|
||||
identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
|
||||
dup_passwd.tchar_ptr = NULL;
|
||||
|
||||
Curl_unicodefree(passwd.tchar_ptr);
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
|
||||
/* Setup the identity's flags */
|
||||
identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,7 +48,7 @@ struct curl_actual_call {
|
||||
|
||||
static void *curl_thread_create_thunk(void *arg)
|
||||
{
|
||||
struct curl_actual_call * ac = arg;
|
||||
struct curl_actual_call *ac = arg;
|
||||
unsigned int (*func)(void *) = ac->func;
|
||||
void *real_arg = ac->arg;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -53,6 +53,16 @@
|
||||
curlx_uztosi()
|
||||
*/
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
/* "curl_multibyte.h" provides these functions and macros:
|
||||
|
||||
curlx_convert_UTF8_to_wchar()
|
||||
curlx_convert_wchar_to_UTF8()
|
||||
curlx_convert_UTF8_to_tchar()
|
||||
curlx_convert_tchar_to_UTF8()
|
||||
curlx_unicodefree()
|
||||
*/
|
||||
|
||||
/* Now setup curlx_ * names for the functions that are to become curlx_ and
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -46,6 +46,8 @@
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#elif defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
#include "curl_base64.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
#include "dynbuf.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define DNS_CLASS_IN 0x01
|
||||
#define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
static const char * const errors[]={
|
||||
@@ -174,23 +174,14 @@ UNITTEST DOHcode doh_encode(const char *host,
|
||||
}
|
||||
|
||||
static size_t
|
||||
doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct dohresponse *mem = (struct dohresponse *)userp;
|
||||
struct dynbuf *mem = (struct dynbuf *)userp;
|
||||
|
||||
if((mem->size + realsize) > DOH_MAX_RESPONSE_SIZE)
|
||||
/* suspiciously much for us */
|
||||
if(Curl_dyn_addn(mem, contents, realsize))
|
||||
return 0;
|
||||
|
||||
mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize);
|
||||
if(!mem->memory)
|
||||
/* out of memory! */
|
||||
return 0;
|
||||
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
@@ -238,10 +229,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
p->dnstype = dnstype;
|
||||
p->serverdoh.memory = NULL;
|
||||
/* the memory will be grown as needed by realloc in the doh_write_cb
|
||||
function */
|
||||
p->serverdoh.size = 0;
|
||||
Curl_dyn_init(&p->serverdoh, DYN_DOH_RESPONSE);
|
||||
|
||||
/* Note: this is code for sending the DoH request with GET but there's still
|
||||
no logic that actually enables this. We should either add that ability or
|
||||
@@ -272,7 +260,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
if(!result) {
|
||||
/* pass in the struct pointer via a local variable to please coverity and
|
||||
the gcc typecheck helpers */
|
||||
struct dohresponse *resp = &p->serverdoh;
|
||||
struct dynbuf *resp = &p->serverdoh;
|
||||
ERROR_CHECK_SETOPT(CURLOPT_URL, url);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp);
|
||||
@@ -318,6 +306,9 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
}
|
||||
if(data->set.proxy_ssl.no_revoke)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
|
||||
else if(data->set.proxy_ssl.revoke_best_effort)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS,
|
||||
CURLSSLOPT_REVOKE_BEST_EFFORT);
|
||||
if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
|
||||
data->set.str[STRING_SSL_CAPATH_PROXY]);
|
||||
@@ -351,6 +342,8 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
}
|
||||
if(data->set.ssl.no_revoke)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
|
||||
else if(data->set.ssl.revoke_best_effort)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT);
|
||||
if(data->set.ssl.fsslctx)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
|
||||
if(data->set.ssl.fsslctxp)
|
||||
@@ -380,10 +373,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
* 'Curl_addrinfo *' with the address information.
|
||||
*/
|
||||
|
||||
Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -396,6 +389,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
/* start clean, consider allocating this struct on demand */
|
||||
memset(&data->req.doh, 0, sizeof(struct dohdata));
|
||||
|
||||
conn->bits.doh = TRUE;
|
||||
data->req.doh.host = hostname;
|
||||
data->req.doh.port = port;
|
||||
data->req.doh.headers =
|
||||
@@ -434,7 +428,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DOHcode skipqname(unsigned char *doh, size_t dohlen,
|
||||
static DOHcode skipqname(const unsigned char *doh, size_t dohlen,
|
||||
unsigned int *indexp)
|
||||
{
|
||||
unsigned char length;
|
||||
@@ -458,12 +452,12 @@ static DOHcode skipqname(unsigned char *doh, size_t dohlen,
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static unsigned short get16bit(unsigned char *doh, int index)
|
||||
static unsigned short get16bit(const unsigned char *doh, int index)
|
||||
{
|
||||
return (unsigned short)((doh[index] << 8) | doh[index + 1]);
|
||||
}
|
||||
|
||||
static unsigned int get32bit(unsigned char *doh, int index)
|
||||
static unsigned int get32bit(const unsigned char *doh, int index)
|
||||
{
|
||||
/* make clang and gcc optimize this to bswap by incrementing
|
||||
the pointer first. */
|
||||
@@ -475,7 +469,7 @@ static unsigned int get32bit(unsigned char *doh, int index)
|
||||
return ( (unsigned)doh[0] << 24) | (doh[1] << 16) |(doh[2] << 8) | doh[3];
|
||||
}
|
||||
|
||||
static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d)
|
||||
static DOHcode store_a(const unsigned char *doh, int index, struct dohentry *d)
|
||||
{
|
||||
/* silently ignore addresses over the limit */
|
||||
if(d->numaddr < DOH_MAX_ADDR) {
|
||||
@@ -487,7 +481,9 @@ static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d)
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d)
|
||||
static DOHcode store_aaaa(const unsigned char *doh,
|
||||
int index,
|
||||
struct dohentry *d)
|
||||
{
|
||||
/* silently ignore addresses over the limit */
|
||||
if(d->numaddr < DOH_MAX_ADDR) {
|
||||
@@ -499,38 +495,12 @@ static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d)
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static DOHcode cnameappend(struct cnamestore *c,
|
||||
unsigned char *src,
|
||||
size_t len)
|
||||
{
|
||||
if(!c->alloc) {
|
||||
c->allocsize = len + 1;
|
||||
c->alloc = malloc(c->allocsize);
|
||||
if(!c->alloc)
|
||||
return DOH_OUT_OF_MEM;
|
||||
}
|
||||
else if(c->allocsize < (c->allocsize + len + 1)) {
|
||||
char *ptr;
|
||||
c->allocsize += len + 1;
|
||||
ptr = realloc(c->alloc, c->allocsize);
|
||||
if(!ptr) {
|
||||
free(c->alloc);
|
||||
return DOH_OUT_OF_MEM;
|
||||
}
|
||||
c->alloc = ptr;
|
||||
}
|
||||
memcpy(&c->alloc[c->len], src, len);
|
||||
c->len += len;
|
||||
c->alloc[c->len] = 0; /* keep it zero terminated */
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static DOHcode store_cname(unsigned char *doh,
|
||||
static DOHcode store_cname(const unsigned char *doh,
|
||||
size_t dohlen,
|
||||
unsigned int index,
|
||||
struct dohentry *d)
|
||||
{
|
||||
struct cnamestore *c;
|
||||
struct dynbuf *c;
|
||||
unsigned int loop = 128; /* a valid DNS name can never loop this much */
|
||||
unsigned char length;
|
||||
|
||||
@@ -559,18 +529,15 @@ static DOHcode store_cname(unsigned char *doh,
|
||||
index++;
|
||||
|
||||
if(length) {
|
||||
DOHcode rc;
|
||||
if(c->len) {
|
||||
rc = cnameappend(c, (unsigned char *)".", 1);
|
||||
if(rc)
|
||||
return rc;
|
||||
if(Curl_dyn_len(c)) {
|
||||
if(Curl_dyn_add(c, "."))
|
||||
return DOH_OUT_OF_MEM;
|
||||
}
|
||||
if((index + length) > dohlen)
|
||||
return DOH_DNS_BAD_LABEL;
|
||||
|
||||
rc = cnameappend(c, &doh[index], length);
|
||||
if(rc)
|
||||
return rc;
|
||||
if(Curl_dyn_addn(c, &doh[index], length))
|
||||
return DOH_OUT_OF_MEM;
|
||||
index += length;
|
||||
}
|
||||
} while(length && --loop);
|
||||
@@ -580,7 +547,7 @@ static DOHcode store_cname(unsigned char *doh,
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static DOHcode rdata(unsigned char *doh,
|
||||
static DOHcode rdata(const unsigned char *doh,
|
||||
size_t dohlen,
|
||||
unsigned short rdlength,
|
||||
unsigned short type,
|
||||
@@ -623,14 +590,17 @@ static DOHcode rdata(unsigned char *doh,
|
||||
return DOH_OK;
|
||||
}
|
||||
|
||||
static void init_dohentry(struct dohentry *de)
|
||||
UNITTEST void de_init(struct dohentry *de)
|
||||
{
|
||||
int i;
|
||||
memset(de, 0, sizeof(*de));
|
||||
de->ttl = INT_MAX;
|
||||
for(i = 0; i < DOH_MAX_CNAME; i++)
|
||||
Curl_dyn_init(&de->cname[i], DYN_DOH_CNAME);
|
||||
}
|
||||
|
||||
|
||||
UNITTEST DOHcode doh_decode(unsigned char *doh,
|
||||
UNITTEST DOHcode doh_decode(const unsigned char *doh,
|
||||
size_t dohlen,
|
||||
DNStype dnstype,
|
||||
struct dohentry *d)
|
||||
@@ -770,12 +740,12 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
static void showdoh(struct Curl_easy *data,
|
||||
struct dohentry *d)
|
||||
const struct dohentry *d)
|
||||
{
|
||||
int i;
|
||||
infof(data, "TTL: %u seconds\n", d->ttl);
|
||||
for(i = 0; i < d->numaddr; i++) {
|
||||
struct dohaddr *a = &d->addr[i];
|
||||
const struct dohaddr *a = &d->addr[i];
|
||||
if(a->type == DNS_TYPE_A) {
|
||||
infof(data, "DOH A: %u.%u.%u.%u\n",
|
||||
a->ip.v4[0], a->ip.v4[1],
|
||||
@@ -801,7 +771,7 @@ static void showdoh(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
for(i = 0; i < d->numcname; i++) {
|
||||
infof(data, "CNAME: %s\n", d->cname[i].alloc);
|
||||
infof(data, "CNAME: %s\n", Curl_dyn_ptr(&d->cname[i]));
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -821,18 +791,19 @@ static void showdoh(struct Curl_easy *data,
|
||||
* must be an associated call later to Curl_freeaddrinfo().
|
||||
*/
|
||||
|
||||
static Curl_addrinfo *
|
||||
static struct Curl_addrinfo *
|
||||
doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *prevai = NULL;
|
||||
Curl_addrinfo *firstai = NULL;
|
||||
struct Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *prevai = NULL;
|
||||
struct Curl_addrinfo *firstai = NULL;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
size_t hostlen = strlen(hostname) + 1; /* include zero terminator */
|
||||
|
||||
if(!de)
|
||||
/* no input == no output! */
|
||||
@@ -855,24 +826,14 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
addrtype = AF_INET;
|
||||
}
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
ai->ai_canonname = strdup(hostname);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
ai->ai_canonname = (void *)((char *)ai->ai_addr + ss_size);
|
||||
memcpy(ai->ai_canonname, hostname, hostlen);
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
@@ -934,7 +895,7 @@ UNITTEST void de_cleanup(struct dohentry *d)
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i < d->numcname; i++) {
|
||||
free(d->cname[i].alloc);
|
||||
Curl_dyn_free(&d->cname[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,7 +913,9 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else if(!data->req.doh.pending) {
|
||||
DOHcode rc[DOH_PROBE_SLOTS];
|
||||
DOHcode rc[DOH_PROBE_SLOTS] = {
|
||||
DOH_OK, DOH_OK
|
||||
};
|
||||
struct dohentry de;
|
||||
int slot;
|
||||
/* remove DOH handles from multi handle and close them */
|
||||
@@ -961,17 +924,19 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
Curl_close(&data->req.doh.probe[slot].easy);
|
||||
}
|
||||
/* parse the responses, create the struct and return it! */
|
||||
init_dohentry(&de);
|
||||
de_init(&de);
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
rc[slot] = doh_decode(data->req.doh.probe[slot].serverdoh.memory,
|
||||
data->req.doh.probe[slot].serverdoh.size,
|
||||
data->req.doh.probe[slot].dnstype,
|
||||
struct dnsprobe *p = &data->req.doh.probe[slot];
|
||||
if(!p->dnstype)
|
||||
continue;
|
||||
rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh),
|
||||
Curl_dyn_len(&p->serverdoh),
|
||||
p->dnstype,
|
||||
&de);
|
||||
Curl_safefree(data->req.doh.probe[slot].serverdoh.memory);
|
||||
Curl_dyn_free(&p->serverdoh);
|
||||
if(rc[slot]) {
|
||||
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
|
||||
type2name(data->req.doh.probe[slot].dnstype),
|
||||
data->req.doh.host);
|
||||
type2name(p->dnstype), data->req.doh.host);
|
||||
}
|
||||
} /* next slot */
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,10 +32,10 @@
|
||||
* and returns a 'Curl_addrinfo *' with the address information.
|
||||
*/
|
||||
|
||||
Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns);
|
||||
@@ -70,12 +70,6 @@ typedef enum {
|
||||
#define DOH_MAX_ADDR 24
|
||||
#define DOH_MAX_CNAME 4
|
||||
|
||||
struct cnamestore {
|
||||
size_t len; /* length of cname */
|
||||
char *alloc; /* allocated pointer */
|
||||
size_t allocsize; /* allocated size */
|
||||
};
|
||||
|
||||
struct dohaddr {
|
||||
int type;
|
||||
union {
|
||||
@@ -85,11 +79,11 @@ struct dohaddr {
|
||||
};
|
||||
|
||||
struct dohentry {
|
||||
unsigned int ttl;
|
||||
int numaddr;
|
||||
struct dynbuf cname[DOH_MAX_CNAME];
|
||||
struct dohaddr addr[DOH_MAX_ADDR];
|
||||
int numaddr;
|
||||
unsigned int ttl;
|
||||
int numcname;
|
||||
struct cnamestore cname[DOH_MAX_CNAME];
|
||||
};
|
||||
|
||||
|
||||
@@ -99,10 +93,11 @@ DOHcode doh_encode(const char *host,
|
||||
unsigned char *dnsp, /* buffer */
|
||||
size_t len, /* buffer size */
|
||||
size_t *olen); /* output length */
|
||||
DOHcode doh_decode(unsigned char *doh,
|
||||
DOHcode doh_decode(const unsigned char *doh,
|
||||
size_t dohlen,
|
||||
DNStype dnstype,
|
||||
struct dohentry *d);
|
||||
void de_init(struct dohentry *d);
|
||||
void de_cleanup(struct dohentry *d);
|
||||
#endif
|
||||
|
||||
|
||||
227
Utilities/cmcurl/lib/dynbuf.c
Normal file
227
Utilities/cmcurl/lib/dynbuf.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, 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 "strdup.h"
|
||||
#include "dynbuf.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MIN_FIRST_ALLOC 32
|
||||
|
||||
#define DYNINIT 0xbee51da /* random pattern */
|
||||
|
||||
/*
|
||||
* Init a dynbuf struct.
|
||||
*/
|
||||
void Curl_dyn_init(struct dynbuf *s, size_t toobig)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(toobig);
|
||||
s->bufr = NULL;
|
||||
s->leng = 0;
|
||||
s->allc = 0;
|
||||
s->toobig = toobig;
|
||||
#ifdef DEBUGBUILD
|
||||
s->init = DYNINIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* free the buffer and re-init the necessary fields. It doesn't touch the
|
||||
* 'init' field and thus this buffer can be reused to add data to again.
|
||||
*/
|
||||
void Curl_dyn_free(struct dynbuf *s)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
Curl_safefree(s->bufr);
|
||||
s->leng = s->allc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store/append an chunk of memory to the dynbuf.
|
||||
*/
|
||||
static CURLcode dyn_nappend(struct dynbuf *s,
|
||||
const unsigned char *mem, size_t len)
|
||||
{
|
||||
size_t indx = s->leng;
|
||||
size_t a = s->allc;
|
||||
size_t fit = len + indx + 1; /* new string + old string + zero byte */
|
||||
|
||||
/* try to detect if there's rubbish in the struct */
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(s->toobig);
|
||||
DEBUGASSERT(indx < s->toobig);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
|
||||
if(fit > s->toobig) {
|
||||
Curl_dyn_free(s);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(!a) {
|
||||
DEBUGASSERT(!indx);
|
||||
/* first invoke */
|
||||
if(fit < MIN_FIRST_ALLOC)
|
||||
a = MIN_FIRST_ALLOC;
|
||||
else
|
||||
a = fit;
|
||||
}
|
||||
else {
|
||||
while(a < fit)
|
||||
a *= 2;
|
||||
}
|
||||
|
||||
if(a != s->allc) {
|
||||
s->bufr = Curl_saferealloc(s->bufr, a);
|
||||
if(!s->bufr) {
|
||||
s->leng = s->allc = 0;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
s->allc = a;
|
||||
}
|
||||
|
||||
if(len)
|
||||
memcpy(&s->bufr[indx], mem, len);
|
||||
s->leng = indx + len;
|
||||
s->bufr[s->leng] = 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clears the string, keeps the allocation. This can also be called on a
|
||||
* buffer that already was freed.
|
||||
*/
|
||||
void Curl_dyn_reset(struct dynbuf *s)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
if(s->leng)
|
||||
s->bufr[0] = 0;
|
||||
s->leng = 0;
|
||||
}
|
||||
|
||||
#ifdef USE_NGTCP2
|
||||
/*
|
||||
* Specify the size of the tail to keep (number of bytes from the end of the
|
||||
* buffer). The rest will be dropped.
|
||||
*/
|
||||
CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
if(trail > s->leng)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
else if(trail == s->leng)
|
||||
return CURLE_OK;
|
||||
else if(!trail) {
|
||||
Curl_dyn_reset(s);
|
||||
}
|
||||
else {
|
||||
memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail);
|
||||
s->leng = trail;
|
||||
}
|
||||
return CURLE_OK;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Appends a buffer with length.
|
||||
*/
|
||||
CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
return dyn_nappend(s, mem, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a zero terminated string at the end.
|
||||
*/
|
||||
CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
|
||||
{
|
||||
size_t n = strlen(str);
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
return dyn_nappend(s, (unsigned char *)str, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a string printf()-style
|
||||
*/
|
||||
CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
|
||||
{
|
||||
char *str;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
str = vaprintf(fmt, ap); /* this allocs a new string to append */
|
||||
va_end(ap);
|
||||
|
||||
if(str) {
|
||||
CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str));
|
||||
free(str);
|
||||
return result;
|
||||
}
|
||||
/* If we failed, we cleanup the whole buffer and return error */
|
||||
Curl_dyn_free(s);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a pointer to the buffer.
|
||||
*/
|
||||
char *Curl_dyn_ptr(const struct dynbuf *s)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
return s->bufr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an unsigned pointer to the buffer.
|
||||
*/
|
||||
unsigned char *Curl_dyn_uptr(const struct dynbuf *s)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
return (unsigned char *)s->bufr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the length of the buffer.
|
||||
*/
|
||||
size_t Curl_dyn_len(const struct dynbuf *s)
|
||||
{
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
DEBUGASSERT(!s->leng || s->bufr);
|
||||
return s->leng;
|
||||
}
|
||||
63
Utilities/cmcurl/lib/dynbuf.h
Normal file
63
Utilities/cmcurl/lib/dynbuf.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef HEADER_CURL_DYNBUF_H
|
||||
#define HEADER_CURL_DYNBUF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
struct dynbuf {
|
||||
char *bufr; /* point to a zero terminated allocated buffer */
|
||||
size_t leng; /* number of bytes *EXCLUDING* the zero terminator */
|
||||
size_t allc; /* size of the current allocation */
|
||||
size_t toobig; /* size limit for the buffer */
|
||||
#ifdef DEBUGBUILD
|
||||
int init; /* detect API usage mistakes */
|
||||
#endif
|
||||
};
|
||||
|
||||
void Curl_dyn_init(struct dynbuf *s, size_t toobig);
|
||||
void Curl_dyn_free(struct dynbuf *s);
|
||||
CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
|
||||
WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
|
||||
WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
|
||||
WARN_UNUSED_RESULT;
|
||||
void Curl_dyn_reset(struct dynbuf *s);
|
||||
CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
|
||||
char *Curl_dyn_ptr(const struct dynbuf *s);
|
||||
unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
|
||||
size_t Curl_dyn_len(const struct dynbuf *s);
|
||||
|
||||
/* Dynamic buffer max sizes */
|
||||
#define DYN_DOH_RESPONSE 3000
|
||||
#define DYN_DOH_CNAME 256
|
||||
#define DYN_PAUSE_BUFFER (64 * 1024 * 1024)
|
||||
#define DYN_HAXPROXY 2048
|
||||
#define DYN_HTTP_REQUEST (128*1024)
|
||||
#define DYN_H2_HEADERS (128*1024)
|
||||
#define DYN_H2_TRAILER 4096
|
||||
#define DYN_APRINTF 8000000
|
||||
#define DYN_RTSP_REQ_HEADER (64*1024)
|
||||
#define DYN_TRAILERS (64*1024)
|
||||
#define DYN_PROXY_CONNECT_HEADERS 16384
|
||||
#define DYN_QLOG_NAME 1024
|
||||
#define DYN_H1_TRAILER DYN_H2_TRAILER
|
||||
#endif
|
||||
@@ -77,14 +77,13 @@
|
||||
#include "http_digest.h"
|
||||
#include "system_win32.h"
|
||||
#include "http2.h"
|
||||
#include "dynbuf.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
void Curl_version_init(void);
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized;
|
||||
static long init_flags;
|
||||
@@ -201,8 +200,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
|
||||
init_flags = flags;
|
||||
|
||||
Curl_version_init();
|
||||
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
@@ -513,7 +510,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
before = Curl_now();
|
||||
|
||||
/* wait for activity or timeout */
|
||||
pollrc = Curl_poll(fds, numfds, (int)ev->ms);
|
||||
pollrc = Curl_poll(fds, numfds, ev->ms);
|
||||
|
||||
after = Curl_now();
|
||||
|
||||
@@ -684,6 +681,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
mcode = curl_multi_add_handle(multi, data);
|
||||
if(mcode) {
|
||||
curl_multi_cleanup(multi);
|
||||
data->multi_easy = NULL;
|
||||
if(mcode == CURLM_OUT_OF_MEMORY)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_FAILED_INIT;
|
||||
@@ -766,6 +764,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
enum dupstring i;
|
||||
enum dupblob j;
|
||||
|
||||
/* Copy src->set into dst->set first, then deal with the strings
|
||||
afterwards */
|
||||
@@ -782,6 +781,16 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* clear all blob pointers first */
|
||||
memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
|
||||
/* duplicate all blobs */
|
||||
for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
|
||||
result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]);
|
||||
/* Curl_setstropt return CURLE_BAD_FUNCTION_ARGUMENT with blob */
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* duplicate memory areas pointed to */
|
||||
i = STRING_COPYPOSTFIELDS;
|
||||
if(src->set.postfieldsize && src->set.str[i]) {
|
||||
@@ -820,19 +829,13 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->set.buffer_size = data->set.buffer_size;
|
||||
outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
|
||||
if(!outcurl->state.buffer)
|
||||
goto fail;
|
||||
|
||||
outcurl->state.headerbuff = malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff)
|
||||
goto fail;
|
||||
outcurl->state.headersize = HEADERSIZE;
|
||||
|
||||
/* copy all userdefined values */
|
||||
if(dupset(outcurl, data))
|
||||
goto fail;
|
||||
|
||||
Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
|
||||
|
||||
/* the connection cache is setup on demand */
|
||||
outcurl->state.conn_cache = NULL;
|
||||
|
||||
@@ -887,6 +890,28 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
data->state.resolver))
|
||||
goto fail;
|
||||
|
||||
#ifdef USE_ARES
|
||||
{
|
||||
CURLcode rc;
|
||||
|
||||
rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]);
|
||||
if(rc && rc != CURLE_NOT_BUILT_IN)
|
||||
goto fail;
|
||||
|
||||
rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]);
|
||||
if(rc && rc != CURLE_NOT_BUILT_IN)
|
||||
goto fail;
|
||||
|
||||
rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]);
|
||||
if(rc && rc != CURLE_NOT_BUILT_IN)
|
||||
goto fail;
|
||||
|
||||
rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]);
|
||||
if(rc && rc != CURLE_NOT_BUILT_IN)
|
||||
goto fail;
|
||||
}
|
||||
#endif /* USE_ARES */
|
||||
|
||||
Curl_convert_setup(outcurl);
|
||||
|
||||
Curl_initinfo(outcurl);
|
||||
@@ -903,7 +928,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
outcurl->change.cookielist = NULL;
|
||||
Curl_safefree(outcurl->state.buffer);
|
||||
Curl_safefree(outcurl->state.headerbuff);
|
||||
Curl_dyn_free(&outcurl->state.headerb);
|
||||
Curl_safefree(outcurl->change.url);
|
||||
Curl_safefree(outcurl->change.referer);
|
||||
Curl_freeset(outcurl);
|
||||
@@ -919,8 +944,6 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
*/
|
||||
void curl_easy_reset(struct Curl_easy *data)
|
||||
{
|
||||
long old_buffer_size = data->set.buffer_size;
|
||||
|
||||
Curl_free_request_state(data);
|
||||
|
||||
/* zero out UserDefined data: */
|
||||
@@ -944,18 +967,6 @@ void curl_easy_reset(struct Curl_easy *data)
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
Curl_http_auth_cleanup_digest(data);
|
||||
#endif
|
||||
|
||||
/* resize receive buffer */
|
||||
if(old_buffer_size != data->set.buffer_size) {
|
||||
char *newbuff = realloc(data->state.buffer, data->set.buffer_size + 1);
|
||||
if(!newbuff) {
|
||||
DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
|
||||
/* nothing we can do here except use the old size */
|
||||
data->set.buffer_size = old_buffer_size;
|
||||
}
|
||||
else
|
||||
data->state.buffer = newbuff;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -973,16 +984,37 @@ void curl_easy_reset(struct Curl_easy *data)
|
||||
*/
|
||||
CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
struct SingleRequest *k;
|
||||
CURLcode result = CURLE_OK;
|
||||
int oldstate;
|
||||
int newstate;
|
||||
|
||||
/* first switch off both pause bits */
|
||||
int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
|
||||
if(!GOOD_EASY_HANDLE(data) || !data->conn)
|
||||
/* crazy input, don't continue */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* set the new desired pause bits */
|
||||
newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
|
||||
k = &data->req;
|
||||
oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
|
||||
|
||||
/* first switch off both pause bits then set the new pause bits */
|
||||
newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
|
||||
((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
|
||||
((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
|
||||
|
||||
if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) {
|
||||
/* Not changing any pause state, return */
|
||||
DEBUGF(infof(data, "pause: no change, early return\n"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Unpause parts in active mime tree. */
|
||||
if((k->keepon & ~newstate & KEEP_SEND_PAUSE) &&
|
||||
(data->mstate == CURLM_STATE_PERFORM ||
|
||||
data->mstate == CURLM_STATE_TOOFAST) &&
|
||||
data->state.fread_func == (curl_read_callback) Curl_mime_read) {
|
||||
Curl_mime_unpause(data->state.in);
|
||||
}
|
||||
|
||||
/* put it back in the keepon */
|
||||
k->keepon = newstate;
|
||||
|
||||
@@ -1001,7 +1033,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
/* copy the structs to allow for immediate re-pausing */
|
||||
for(i = 0; i < data->state.tempcount; i++) {
|
||||
writebuf[i] = data->state.tempwrite[i];
|
||||
data->state.tempwrite[i].buf = NULL;
|
||||
Curl_dyn_init(&data->state.tempwrite[i].b, DYN_PAUSE_BUFFER);
|
||||
}
|
||||
data->state.tempcount = 0;
|
||||
|
||||
@@ -1015,9 +1047,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
/* even if one function returns error, this loops through and frees
|
||||
all buffers */
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
|
||||
writebuf[i].len);
|
||||
free(writebuf[i].buf);
|
||||
result = Curl_client_write(conn, writebuf[i].type,
|
||||
Curl_dyn_ptr(&writebuf[i].b),
|
||||
Curl_dyn_len(&writebuf[i].b));
|
||||
Curl_dyn_free(&writebuf[i].b);
|
||||
}
|
||||
|
||||
/* recover previous owner of the connection */
|
||||
@@ -1033,8 +1066,11 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
to have this handle checked soon */
|
||||
if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
|
||||
data->state.drain++;
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
|
||||
|
||||
/* force a recv/send check of this connection, as the data might've been
|
||||
read off the socket already */
|
||||
data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
|
||||
if(data->multi)
|
||||
Curl_update_timer(data->multi);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -79,57 +79,42 @@ char *curl_unescape(const char *string, int length)
|
||||
char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
int inlength)
|
||||
{
|
||||
size_t alloc;
|
||||
char *ns;
|
||||
char *testing_ptr = NULL;
|
||||
size_t newlen;
|
||||
size_t strindex = 0;
|
||||
size_t length;
|
||||
CURLcode result;
|
||||
struct dynbuf d;
|
||||
|
||||
if(inlength < 0)
|
||||
return NULL;
|
||||
|
||||
alloc = (inlength?(size_t)inlength:strlen(string)) + 1;
|
||||
newlen = alloc;
|
||||
Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH);
|
||||
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
|
||||
length = alloc-1;
|
||||
length = (inlength?(size_t)inlength:strlen(string));
|
||||
while(length--) {
|
||||
unsigned char in = *string; /* we need to treat the characters unsigned */
|
||||
|
||||
if(Curl_isunreserved(in))
|
||||
/* just copy this */
|
||||
ns[strindex++] = in;
|
||||
if(Curl_isunreserved(in)) {
|
||||
/* append this */
|
||||
if(Curl_dyn_addn(&d, &in, 1))
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* encode it */
|
||||
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
||||
if(newlen > alloc) {
|
||||
alloc *= 2;
|
||||
testing_ptr = Curl_saferealloc(ns, alloc);
|
||||
if(!testing_ptr)
|
||||
return NULL;
|
||||
ns = testing_ptr;
|
||||
}
|
||||
|
||||
char encoded[4];
|
||||
result = Curl_convert_to_network(data, (char *)&in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
Curl_dyn_free(&d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msnprintf(&ns[strindex], 4, "%%%02X", in);
|
||||
|
||||
strindex += 3;
|
||||
msnprintf(encoded, sizeof(encoded), "%%%02X", in);
|
||||
if(Curl_dyn_add(&d, encoded))
|
||||
return NULL;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
ns[strindex] = 0; /* terminate it */
|
||||
return ns;
|
||||
|
||||
return Curl_dyn_ptr(&d);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -149,12 +134,17 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
char **ostring, size_t *olen,
|
||||
bool reject_ctrl)
|
||||
{
|
||||
size_t alloc = (length?length:strlen(string)) + 1;
|
||||
char *ns = malloc(alloc);
|
||||
size_t alloc;
|
||||
char *ns;
|
||||
size_t strindex = 0;
|
||||
unsigned long hex;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(string);
|
||||
|
||||
alloc = (length?length:strlen(string)) + 1;
|
||||
ns = malloc(alloc);
|
||||
|
||||
if(!ns)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path;
|
||||
struct FILEPROTO *file = data->req.protop;
|
||||
int fd = -1;
|
||||
int fd;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
size_t i;
|
||||
char *actual_path;
|
||||
@@ -181,9 +181,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
if(strncmp("\\\\", actual_path, 2))
|
||||
/* refuse to open path that starts with two backslashes */
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len)) {
|
||||
|
||||
@@ -123,11 +123,11 @@ AddHttpPost(char *name, size_t namelength,
|
||||
* parent_form_info is NULL.
|
||||
*
|
||||
***************************************************************************/
|
||||
static FormInfo * AddFormInfo(char *value,
|
||||
char *contenttype,
|
||||
FormInfo *parent_form_info)
|
||||
static struct FormInfo *AddFormInfo(char *value,
|
||||
char *contenttype,
|
||||
struct FormInfo *parent_form_info)
|
||||
{
|
||||
FormInfo *form_info;
|
||||
struct FormInfo *form_info;
|
||||
form_info = calloc(1, sizeof(struct FormInfo));
|
||||
if(form_info) {
|
||||
if(value)
|
||||
@@ -204,7 +204,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
va_list params)
|
||||
{
|
||||
FormInfo *first_form, *current_form, *form = NULL;
|
||||
struct FormInfo *first_form, *current_form, *form = NULL;
|
||||
CURLFORMcode return_value = CURL_FORMADD_OK;
|
||||
const char *prevtype = NULL;
|
||||
struct curl_httppost *post = NULL;
|
||||
@@ -521,7 +521,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if(CURL_FORMADD_OK != return_value) {
|
||||
/* On error, free allocated fields for all nodes of the FormInfo linked
|
||||
list without deallocating nodes. List nodes are deallocated later on */
|
||||
FormInfo *ptr;
|
||||
struct FormInfo *ptr;
|
||||
for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
|
||||
if(ptr->name_alloc) {
|
||||
Curl_safefree(ptr->name);
|
||||
@@ -650,7 +650,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
/* On error, free allocated fields for nodes of the FormInfo linked
|
||||
list which are not already owned by the httppost linked list
|
||||
without deallocating nodes. List nodes are deallocated later on */
|
||||
FormInfo *ptr;
|
||||
struct FormInfo *ptr;
|
||||
for(ptr = form; ptr != NULL; ptr = ptr->more) {
|
||||
if(ptr->name_alloc) {
|
||||
Curl_safefree(ptr->name);
|
||||
@@ -676,7 +676,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
fields given that these have either been deallocated or are owned
|
||||
now by the httppost linked list */
|
||||
while(first_form) {
|
||||
FormInfo *ptr = first_form->more;
|
||||
struct FormInfo *ptr = first_form->more;
|
||||
free(first_form);
|
||||
first_form = ptr;
|
||||
}
|
||||
@@ -728,14 +728,10 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
||||
if(!nread)
|
||||
break;
|
||||
|
||||
switch(nread) {
|
||||
default:
|
||||
if(append(arg, buffer, nread) != nread)
|
||||
result = CURLE_READ_ERROR;
|
||||
break;
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
break;
|
||||
if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) {
|
||||
result = CURLE_READ_ERROR;
|
||||
if(nread == CURL_READFUNC_ABORT)
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -27,7 +27,7 @@
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
|
||||
/* used by FormAdd for temporary storage */
|
||||
typedef struct FormInfo {
|
||||
struct FormInfo {
|
||||
char *name;
|
||||
bool name_alloc;
|
||||
size_t namelength;
|
||||
@@ -45,7 +45,7 @@ typedef struct FormInfo {
|
||||
char *userp; /* pointer for the read callback */
|
||||
struct curl_slist *contentheader;
|
||||
struct FormInfo *more;
|
||||
} FormInfo;
|
||||
};
|
||||
|
||||
CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
curl_mimepart *,
|
||||
|
||||
@@ -113,7 +113,7 @@ static CURLcode ftp_parse_url_path(struct connectdata *conn);
|
||||
static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
static void ftp_pasv_verbose(struct connectdata *conn,
|
||||
Curl_addrinfo *ai,
|
||||
struct Curl_addrinfo *ai,
|
||||
char *newhost, /* ascii version */
|
||||
int port);
|
||||
#endif
|
||||
@@ -136,7 +136,7 @@ static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||
static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
static CURLcode ftp_setup_connection(struct connectdata * conn);
|
||||
static CURLcode ftp_setup_connection(struct connectdata *conn);
|
||||
|
||||
static CURLcode init_wc_data(struct connectdata *conn);
|
||||
static CURLcode wc_statemach(struct connectdata *conn);
|
||||
@@ -221,6 +221,9 @@ static void close_secondarysocket(struct connectdata *conn)
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
}
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
conn->bits.proxy_ssl_connected[SECONDARYSOCKET] = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -291,7 +294,7 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
|
||||
|
||||
conn->sock[SECONDARYSOCKET] = s;
|
||||
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
|
||||
conn->sock_accepted = TRUE;
|
||||
conn->bits.sock_accepted = TRUE;
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
int error = 0;
|
||||
@@ -334,7 +337,7 @@ static timediff_t ftp_timeleft_accept(struct Curl_easy *data)
|
||||
now = Curl_now();
|
||||
|
||||
/* check if the generic timeout possibly is set shorter */
|
||||
other = Curl_timeleft(data, &now, FALSE);
|
||||
other = Curl_timeleft(data, &now, FALSE);
|
||||
if(other && (other < timeout_ms))
|
||||
/* note that this also works fine for when other happens to be negative
|
||||
due to it already having elapsed */
|
||||
@@ -386,7 +389,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
|
||||
/* Data connection could not be established, let's return */
|
||||
infof(data, "There is negative response in cache while serv connect\n");
|
||||
Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||
(void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
|
||||
@@ -408,7 +411,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
}
|
||||
else if(result & CURL_CSELECT_IN) {
|
||||
infof(data, "Ctrl conn has data while waiting for data conn\n");
|
||||
Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||
(void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||
|
||||
if(ftpcode/100 > 3)
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
@@ -632,8 +635,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
|
||||
while(!*ftpcode && !result) {
|
||||
/* check and reset timeout value every lap */
|
||||
time_t timeout = Curl_pp_state_timeout(pp, FALSE);
|
||||
time_t interval_ms;
|
||||
timediff_t timeout = Curl_pp_state_timeout(pp, FALSE);
|
||||
timediff_t interval_ms;
|
||||
|
||||
if(timeout <= 0) {
|
||||
failf(data, "FTP response timeout");
|
||||
@@ -815,6 +818,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
|
||||
if(FTP_STOP == ftpc->state) {
|
||||
int bits = GETSOCK_READSOCK(0);
|
||||
bool any = FALSE;
|
||||
|
||||
/* if stopped and still in this state, then we're also waiting for a
|
||||
connect on the secondary connection */
|
||||
@@ -829,10 +833,11 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
|
||||
socks[s] = conn->tempsock[i];
|
||||
bits |= GETSOCK_WRITESOCK(s++);
|
||||
any = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!any) {
|
||||
socks[1] = conn->sock[SECONDARYSOCKET];
|
||||
bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
|
||||
}
|
||||
@@ -913,7 +918,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
char myhost[MAX_IPADR_LEN + 1] = "";
|
||||
|
||||
struct Curl_sockaddr_storage ss;
|
||||
Curl_addrinfo *res, *ai;
|
||||
struct Curl_addrinfo *res, *ai;
|
||||
curl_socklen_t sslen;
|
||||
char hbuf[NI_MAXHOST];
|
||||
struct sockaddr *sa = (struct sockaddr *)&ss;
|
||||
@@ -1293,7 +1298,7 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result = CURLE_OK;
|
||||
/*
|
||||
Here's the excecutive summary on what to do:
|
||||
Here's the executive summary on what to do:
|
||||
|
||||
PASV is RFC959, expect:
|
||||
227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
|
||||
@@ -1759,7 +1764,11 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) {
|
||||
if(conn->bits.ipv6
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& !(conn->bits.tunnel_proxy || conn->bits.socksproxy)
|
||||
#endif
|
||||
) {
|
||||
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
|
||||
failf(conn->data, "Failed EPSV attempt, exiting\n");
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
@@ -1784,9 +1793,10 @@ static char *control_address(struct connectdata *conn)
|
||||
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. */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
|
||||
return conn->host.name;
|
||||
|
||||
#endif
|
||||
return conn->ip_addr_str;
|
||||
}
|
||||
|
||||
@@ -1903,6 +1913,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.proxy) {
|
||||
/*
|
||||
* This connection uses a proxy and we need to connect to the proxy again
|
||||
@@ -1925,7 +1936,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* normal, direct, ftp connection */
|
||||
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
@@ -2634,9 +2647,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
#endif
|
||||
|
||||
if(data->set.use_ssl &&
|
||||
(!conn->ssl[FIRSTSOCKET].use ||
|
||||
(conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
|
||||
!conn->proxy_ssl[FIRSTSOCKET].use))) {
|
||||
(!conn->ssl[FIRSTSOCKET].use
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|| (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
|
||||
!conn->proxy_ssl[FIRSTSOCKET].use)
|
||||
#endif
|
||||
)) {
|
||||
/* We don't have a SSL/TLS connection yet, but FTPS is
|
||||
requested. Try a FTPS connection now */
|
||||
|
||||
@@ -3231,9 +3247,9 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
}
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* The secondary socket is using SSL so we must close down that part
|
||||
first before we close the socket for real */
|
||||
Curl_ssl_close(conn, SECONDARYSOCKET);
|
||||
/* The secondary socket used SSL so we must close down that part first
|
||||
before we close the socket for real */
|
||||
result = Curl_ssl_shutdown(conn, SECONDARYSOCKET);
|
||||
|
||||
/* Note that we keep "use" set to TRUE since that (next) connection is
|
||||
still requested to use SSL */
|
||||
@@ -3249,7 +3265,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
* data has been transferred. This happens when doing through NATs etc that
|
||||
* abandon old silent connections.
|
||||
*/
|
||||
long old_time = pp->response_time;
|
||||
timediff_t old_time = pp->response_time;
|
||||
|
||||
pp->response_time = 60*1000; /* give it only a minute for now */
|
||||
pp->response = Curl_now(); /* timeout relative now */
|
||||
@@ -3442,7 +3458,7 @@ static CURLcode ftp_nb_type(struct connectdata *conn,
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
static void
|
||||
ftp_pasv_verbose(struct connectdata *conn,
|
||||
Curl_addrinfo *ai,
|
||||
struct Curl_addrinfo *ai,
|
||||
char *newhost, /* ascii version */
|
||||
int port)
|
||||
{
|
||||
@@ -3500,6 +3516,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
result = Curl_proxy_connect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -3510,7 +3527,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
|
||||
Curl_connect_ongoing(conn))
|
||||
return result;
|
||||
|
||||
#endif
|
||||
|
||||
if(ftpc->state) {
|
||||
/* already in a state so skip the initial commands.
|
||||
@@ -4338,7 +4355,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
|
||||
char command;
|
||||
*type = 0; /* it was in the middle of the hostname */
|
||||
command = Curl_raw_toupper(type[6]);
|
||||
conn->bits.type_set = TRUE;
|
||||
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
|
||||
@@ -150,7 +150,6 @@ struct ftp_conn {
|
||||
connection to */
|
||||
char *newhost; /* this is the pair to connect the DATA... */
|
||||
unsigned short newport; /* connection to */
|
||||
|
||||
};
|
||||
|
||||
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -147,6 +147,33 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
long *to_long;
|
||||
} lptr;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
char *timestr = getenv("CURL_TIME");
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
switch(info) {
|
||||
case CURLINFO_LOCAL_PORT:
|
||||
*param_longp = (long)val;
|
||||
return CURLE_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* use another variable for this to allow different values */
|
||||
timestr = getenv("CURL_DEBUG_SIZE");
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
switch(info) {
|
||||
case CURLINFO_HEADER_SIZE:
|
||||
case CURLINFO_REQUEST_SIZE:
|
||||
*param_longp = (long)val;
|
||||
return CURLE_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(info) {
|
||||
case CURLINFO_RESPONSE_CODE:
|
||||
*param_longp = data->info.httpcode;
|
||||
@@ -171,9 +198,11 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
break;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
case CURLINFO_PROXY_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.proxy_ssl.certverifyresult;
|
||||
break;
|
||||
#endif
|
||||
case CURLINFO_REDIRECT_COUNT:
|
||||
*param_longp = data->set.followlocation;
|
||||
break;
|
||||
@@ -212,8 +241,11 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
*param_longp = data->info.conn_local_port;
|
||||
break;
|
||||
case CURLINFO_CONDITION_UNMET:
|
||||
/* return if the condition prevented the document to get transferred */
|
||||
*param_longp = data->info.timecond ? 1L : 0L;
|
||||
if(data->info.httpcode == 304)
|
||||
*param_longp = 1L;
|
||||
else
|
||||
/* return if the condition prevented the document to get transferred */
|
||||
*param_longp = data->info.timecond ? 1L : 0L;
|
||||
break;
|
||||
case CURLINFO_RTSP_CLIENT_CSEQ:
|
||||
*param_longp = data->state.rtsp_next_client_CSeq;
|
||||
@@ -258,6 +290,27 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
||||
curl_off_t *param_offt)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
char *timestr = getenv("CURL_TIME");
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
switch(info) {
|
||||
case CURLINFO_TOTAL_TIME_T:
|
||||
case CURLINFO_NAMELOOKUP_TIME_T:
|
||||
case CURLINFO_CONNECT_TIME_T:
|
||||
case CURLINFO_APPCONNECT_TIME_T:
|
||||
case CURLINFO_PRETRANSFER_TIME_T:
|
||||
case CURLINFO_STARTTRANSFER_TIME_T:
|
||||
case CURLINFO_REDIRECT_TIME_T:
|
||||
case CURLINFO_SPEED_DOWNLOAD_T:
|
||||
case CURLINFO_SPEED_UPLOAD_T:
|
||||
*param_offt = (curl_off_t)val;
|
||||
return CURLE_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
switch(info) {
|
||||
case CURLINFO_FILETIME_T:
|
||||
*param_offt = (curl_off_t)data->info.filetime;
|
||||
@@ -269,7 +322,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
||||
*param_offt = data->progress.downloaded;
|
||||
break;
|
||||
case CURLINFO_SPEED_DOWNLOAD_T:
|
||||
*param_offt = data->progress.dlspeed;
|
||||
*param_offt = data->progress.dlspeed;
|
||||
break;
|
||||
case CURLINFO_SPEED_UPLOAD_T:
|
||||
*param_offt = data->progress.ulspeed;
|
||||
@@ -282,7 +335,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
||||
*param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
|
||||
data->progress.size_ul:-1;
|
||||
break;
|
||||
case CURLINFO_TOTAL_TIME_T:
|
||||
case CURLINFO_TOTAL_TIME_T:
|
||||
*param_offt = data->progress.timespent;
|
||||
break;
|
||||
case CURLINFO_NAMELOOKUP_TIME_T:
|
||||
@@ -316,6 +369,27 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
||||
static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
||||
double *param_doublep)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
char *timestr = getenv("CURL_TIME");
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
switch(info) {
|
||||
case CURLINFO_TOTAL_TIME:
|
||||
case CURLINFO_NAMELOOKUP_TIME:
|
||||
case CURLINFO_CONNECT_TIME:
|
||||
case CURLINFO_APPCONNECT_TIME:
|
||||
case CURLINFO_PRETRANSFER_TIME:
|
||||
case CURLINFO_STARTTRANSFER_TIME:
|
||||
case CURLINFO_REDIRECT_TIME:
|
||||
case CURLINFO_SPEED_DOWNLOAD:
|
||||
case CURLINFO_SPEED_UPLOAD:
|
||||
*param_doublep = (double)val;
|
||||
return CURLE_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
switch(info) {
|
||||
case CURLINFO_TOTAL_TIME:
|
||||
*param_doublep = DOUBLE_SECS(data->progress.timespent);
|
||||
@@ -336,13 +410,13 @@ static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
||||
*param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
|
||||
break;
|
||||
case CURLINFO_SIZE_UPLOAD:
|
||||
*param_doublep = (double)data->progress.uploaded;
|
||||
*param_doublep = (double)data->progress.uploaded;
|
||||
break;
|
||||
case CURLINFO_SIZE_DOWNLOAD:
|
||||
*param_doublep = (double)data->progress.downloaded;
|
||||
break;
|
||||
case CURLINFO_SPEED_DOWNLOAD:
|
||||
*param_doublep = (double)data->progress.dlspeed;
|
||||
*param_doublep = (double)data->progress.dlspeed;
|
||||
break;
|
||||
case CURLINFO_SPEED_UPLOAD:
|
||||
*param_doublep = (double)data->progress.ulspeed;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 +28,7 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
#include "connect.h"
|
||||
#include "progress.h"
|
||||
#include "gopher.h"
|
||||
#include "select.h"
|
||||
@@ -83,8 +84,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
char *query = data->state.up.query;
|
||||
char *sel = NULL;
|
||||
char *sel_org = NULL;
|
||||
timediff_t timeout_ms;
|
||||
ssize_t amount, k;
|
||||
size_t len;
|
||||
int what;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@@ -139,19 +142,29 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
else
|
||||
break;
|
||||
|
||||
timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
|
||||
if(timeout_ms < 0) {
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
if(!timeout_ms)
|
||||
timeout_ms = TIMEDIFF_T_MAX;
|
||||
|
||||
/* 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
|
||||
possible to send now will be sent in the doing function repeatedly
|
||||
until the entire request is sent.
|
||||
|
||||
Wait a while for the socket to be writable. Note that this doesn't
|
||||
acknowledge the timeout.
|
||||
*/
|
||||
if(SOCKET_WRITABLE(sockfd, 100) < 0) {
|
||||
what = SOCKET_WRITABLE(sockfd, timeout_ms);
|
||||
if(what < 0) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
break;
|
||||
}
|
||||
else if(!what) {
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(sel_org);
|
||||
|
||||
@@ -48,13 +48,13 @@ static const unsigned char hmac_opad = 0x5C;
|
||||
|
||||
|
||||
|
||||
HMAC_context *
|
||||
Curl_HMAC_init(const HMAC_params * hashparams,
|
||||
struct HMAC_context *
|
||||
Curl_HMAC_init(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
size_t i;
|
||||
HMAC_context *ctxt;
|
||||
struct HMAC_context *ctxt;
|
||||
unsigned char *hkey;
|
||||
unsigned char b;
|
||||
|
||||
@@ -101,7 +101,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
int Curl_HMAC_update(HMAC_context * ctxt,
|
||||
int Curl_HMAC_update(struct HMAC_context *ctxt,
|
||||
const unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
@@ -111,9 +111,9 @@ int Curl_HMAC_update(HMAC_context * ctxt,
|
||||
}
|
||||
|
||||
|
||||
int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
|
||||
int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
|
||||
{
|
||||
const HMAC_params * hashparams = ctxt->hmac_hash;
|
||||
const struct HMAC_params *hashparams = ctxt->hmac_hash;
|
||||
|
||||
/* Do not get result if called with a null parameter: only release
|
||||
storage. */
|
||||
@@ -147,12 +147,13 @@ int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_hmacit(const HMAC_params *hashparams,
|
||||
CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key, const size_t keylen,
|
||||
const unsigned char *data, const size_t datalen,
|
||||
unsigned char *output)
|
||||
{
|
||||
HMAC_context *ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
|
||||
struct HMAC_context *ctxt =
|
||||
Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
|
||||
|
||||
if(!ctxt)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,10 +117,10 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
* name resolve layers (selected at build-time). They all take this same set
|
||||
* of arguments
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ static void freednsentry(void *freethis);
|
||||
/*
|
||||
* Return # of addresses in a Curl_addrinfo struct
|
||||
*/
|
||||
int Curl_num_addresses(const Curl_addrinfo *addr)
|
||||
int Curl_num_addresses(const struct Curl_addrinfo *addr)
|
||||
{
|
||||
int i = 0;
|
||||
while(addr) {
|
||||
@@ -131,39 +131,36 @@ int Curl_num_addresses(const Curl_addrinfo *addr)
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_printable_address() returns a printable version of the 1st address
|
||||
* Curl_printable_address() stores a printable version of the 1st address
|
||||
* given in the 'ai' argument. The result will be stored in the buf that is
|
||||
* bufsize bytes big.
|
||||
*
|
||||
* If the conversion fails, it returns NULL.
|
||||
* If the conversion fails, the target buffer is empty.
|
||||
*/
|
||||
const char *
|
||||
Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
|
||||
void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
const struct sockaddr_in *sa4;
|
||||
const struct in_addr *ipaddr4;
|
||||
#ifdef ENABLE_IPV6
|
||||
const struct sockaddr_in6 *sa6;
|
||||
const struct in6_addr *ipaddr6;
|
||||
#endif
|
||||
DEBUGASSERT(bufsize);
|
||||
buf[0] = 0;
|
||||
|
||||
switch(ai->ai_family) {
|
||||
case AF_INET:
|
||||
sa4 = (const void *)ai->ai_addr;
|
||||
ipaddr4 = &sa4->sin_addr;
|
||||
return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
|
||||
bufsize);
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
sa6 = (const void *)ai->ai_addr;
|
||||
ipaddr6 = &sa6->sin6_addr;
|
||||
return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
|
||||
bufsize);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
case AF_INET: {
|
||||
const struct sockaddr_in *sa4 = (const void *)ai->ai_addr;
|
||||
const struct in_addr *ipaddr4 = &sa4->sin_addr;
|
||||
(void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize);
|
||||
break;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6: {
|
||||
const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr;
|
||||
const struct in6_addr *ipaddr6 = &sa6->sin6_addr;
|
||||
(void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -337,7 +334,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
|
||||
#ifndef CURL_DISABLE_SHUFFLE_DNS
|
||||
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo **addr);
|
||||
struct Curl_addrinfo **addr);
|
||||
/*
|
||||
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
|
||||
* struct by re-linking its linked list.
|
||||
@@ -351,13 +348,13 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
* @unittest: 1608
|
||||
*/
|
||||
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo **addr)
|
||||
struct Curl_addrinfo **addr)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const int num_addrs = Curl_num_addresses(*addr);
|
||||
|
||||
if(num_addrs > 1) {
|
||||
Curl_addrinfo **nodes;
|
||||
struct Curl_addrinfo **nodes;
|
||||
infof(data, "Shuffling %i addresses", num_addrs);
|
||||
|
||||
nodes = malloc(num_addrs*sizeof(*nodes));
|
||||
@@ -376,7 +373,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
if(rnd) {
|
||||
/* Fisher-Yates shuffle */
|
||||
if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) {
|
||||
Curl_addrinfo *swap_tmp;
|
||||
struct Curl_addrinfo *swap_tmp;
|
||||
for(i = num_addrs - 1; i > 0; i--) {
|
||||
swap_tmp = nodes[rnd[i] % (i + 1)];
|
||||
nodes[rnd[i] % (i + 1)] = nodes[i];
|
||||
@@ -415,7 +412,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo *addr,
|
||||
struct Curl_addrinfo *addr,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
@@ -495,6 +492,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
||||
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
|
||||
*entry = NULL;
|
||||
conn->bits.doh = FALSE; /* default is not */
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
@@ -513,11 +511,13 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
||||
if(!dns) {
|
||||
/* The entry was not in the cache. Resolve it to IP address */
|
||||
|
||||
Curl_addrinfo *addr = NULL;
|
||||
struct Curl_addrinfo *addr = NULL;
|
||||
int respwait = 0;
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
struct in_addr in;
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
const
|
||||
#endif
|
||||
bool ipnum = FALSE;
|
||||
|
||||
/* notify the resolver start callback */
|
||||
if(data->set.resolver_start) {
|
||||
@@ -544,6 +544,22 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
||||
addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
#else /* if USE_RESOLVE_ON_IPS */
|
||||
/* First check if this is an IPv4 address string */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
ipnum = TRUE;
|
||||
#ifdef ENABLE_IPV6
|
||||
else {
|
||||
struct in6_addr in6;
|
||||
/* check if this is an IPv6 address string */
|
||||
if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
|
||||
/* This is an IPv6 address literal */
|
||||
ipnum = TRUE;
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
#endif /* !USE_RESOLVE_ON_IPS */
|
||||
|
||||
if(!addr) {
|
||||
@@ -552,7 +568,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
||||
if(!Curl_ipvalid(conn))
|
||||
return CURLRESOLV_ERROR;
|
||||
|
||||
if(allowDOH && data->set.doh) {
|
||||
if(allowDOH && data->set.doh && !ipnum) {
|
||||
addr = Curl_doh(conn, hostname, port, &respwait);
|
||||
}
|
||||
else {
|
||||
@@ -890,7 +906,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
}
|
||||
else {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *head = NULL, *tail = NULL;
|
||||
struct Curl_addrinfo *head = NULL, *tail = NULL;
|
||||
size_t entry_len;
|
||||
char address[64];
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
@@ -924,7 +940,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
while(*end_ptr) {
|
||||
size_t alen;
|
||||
Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *ai;
|
||||
|
||||
addr_begin = end_ptr + 1;
|
||||
addr_end = strchr(addr_begin, ',');
|
||||
@@ -1047,7 +1063,7 @@ CURLcode Curl_resolv_check(struct connectdata *conn,
|
||||
(void)dns;
|
||||
#endif
|
||||
|
||||
if(conn->data->set.doh)
|
||||
if(conn->bits.doh)
|
||||
return Curl_doh_is_resolved(conn, dns);
|
||||
return Curl_resolver_is_resolved(conn, dns);
|
||||
}
|
||||
@@ -1056,7 +1072,7 @@ int Curl_resolv_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
#ifdef CURLRES_ASYNCH
|
||||
if(conn->data->set.doh)
|
||||
if(conn->bits.doh)
|
||||
/* nothing to wait for during DOH resolve, those handles have their own
|
||||
sockets */
|
||||
return GETSOCK_BLANK;
|
||||
@@ -1085,10 +1101,12 @@ CURLcode Curl_once_resolved(struct connectdata *conn,
|
||||
|
||||
result = Curl_setup_conn(conn, protocol_done);
|
||||
|
||||
if(result)
|
||||
/* We're not allowed to return failure with memory left allocated
|
||||
in the connectdata struct, free those here */
|
||||
Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
|
||||
|
||||
if(result) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
DEBUGASSERT(data);
|
||||
Curl_detach_connnection(data);
|
||||
Curl_conncache_remove_conn(data, conn, TRUE);
|
||||
Curl_disconnect(data, conn, TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ struct connectdata;
|
||||
struct curl_hash *Curl_global_host_cache_init(void);
|
||||
|
||||
struct Curl_dns_entry {
|
||||
Curl_addrinfo *addr;
|
||||
struct Curl_addrinfo *addr;
|
||||
/* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
|
||||
time_t timestamp;
|
||||
/* use-counter, use Curl_resolv_unlock to release reference */
|
||||
@@ -117,10 +117,10 @@ bool Curl_ipvalid(struct connectdata *conn);
|
||||
* name resolve layers (selected at build-time). They all take this same set
|
||||
* of arguments
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
|
||||
/* unlock a previously resolved dns entry */
|
||||
@@ -134,7 +134,7 @@ int Curl_mk_dnscache(struct curl_hash *hash);
|
||||
void Curl_hostcache_prune(struct Curl_easy *data);
|
||||
|
||||
/* Return # of addresses in a Curl_addrinfo struct */
|
||||
int Curl_num_addresses(const Curl_addrinfo *addr);
|
||||
int Curl_num_addresses(const struct Curl_addrinfo *addr);
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
|
||||
int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
||||
@@ -146,7 +146,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
||||
#endif
|
||||
|
||||
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
||||
Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
|
||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
|
||||
|
||||
CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
|
||||
|
||||
@@ -158,15 +158,15 @@ CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
|
||||
*/
|
||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
int status,
|
||||
Curl_addrinfo *ai);
|
||||
struct Curl_addrinfo *ai);
|
||||
|
||||
/*
|
||||
* Curl_printable_address() returns a printable version of the 1st address
|
||||
* given in the 'ip' argument. The result will be stored in the buf that is
|
||||
* bufsize bytes big.
|
||||
*/
|
||||
const char *Curl_printable_address(const Curl_addrinfo *ip,
|
||||
char *buf, size_t bufsize);
|
||||
void Curl_printable_address(const struct Curl_addrinfo *ip,
|
||||
char *buf, size_t bufsize);
|
||||
|
||||
/*
|
||||
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
|
||||
@@ -187,7 +187,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr,
|
||||
Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr,
|
||||
const char *hostname, int port);
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
|
||||
@@ -88,12 +88,12 @@ bool Curl_ipvalid(struct connectdata *conn)
|
||||
* flavours have thread-safe versions of the plain gethostbyname() etc.
|
||||
*
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
Curl_addrinfo *ai = NULL;
|
||||
struct Curl_addrinfo *ai = NULL;
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)conn;
|
||||
@@ -119,13 +119,13 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
* implying that only threadsafe code and function calls may be used.
|
||||
*
|
||||
*/
|
||||
Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
int port)
|
||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
int port)
|
||||
{
|
||||
#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
|
||||
int res;
|
||||
#endif
|
||||
Curl_addrinfo *ai = NULL;
|
||||
struct Curl_addrinfo *ai = NULL;
|
||||
struct hostent *h = NULL;
|
||||
struct hostent *buf = NULL;
|
||||
|
||||
|
||||
@@ -103,20 +103,16 @@ bool Curl_ipvalid(struct connectdata *conn)
|
||||
#if defined(CURLRES_SYNCH)
|
||||
|
||||
#ifdef DEBUG_ADDRINFO
|
||||
static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
static void dump_addrinfo(struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai)
|
||||
{
|
||||
printf("dump_addrinfo:\n");
|
||||
for(; ai; ai = ai->ai_next) {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
printf(" fam %2d, CNAME %s, ",
|
||||
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
|
||||
if(Curl_printable_address(ai, buf, sizeof(buf)))
|
||||
printf("%s\n", buf);
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
printf("failed; %s\n",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
}
|
||||
Curl_printable_address(ai, buf, sizeof(buf));
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -132,13 +128,13 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
Curl_addrinfo *res;
|
||||
struct Curl_addrinfo *res;
|
||||
int error;
|
||||
char sbuf[12];
|
||||
char *sbufptr = NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,38 +44,19 @@ char *Curl_copy_header_value(const char *header);
|
||||
|
||||
char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
const char *thisheader);
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*
|
||||
* The add_buffer series of functions are used to build one large memory chunk
|
||||
* from repeated function invokes. Used so that the entire HTTP request can
|
||||
* be sent in one go.
|
||||
*/
|
||||
struct Curl_send_buffer {
|
||||
char *buffer;
|
||||
size_t size_max;
|
||||
size_t size_used;
|
||||
};
|
||||
typedef struct Curl_send_buffer Curl_send_buffer;
|
||||
|
||||
Curl_send_buffer *Curl_add_buffer_init(void);
|
||||
void Curl_add_buffer_free(Curl_send_buffer **inp);
|
||||
CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
|
||||
WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
|
||||
size_t size) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
|
||||
struct connectdata *conn,
|
||||
curl_off_t *bytes_written,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
struct connectdata *conn,
|
||||
curl_off_t *bytes_written,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
|
||||
CURLcode Curl_add_timecondition(const struct connectdata *conn,
|
||||
Curl_send_buffer *buf);
|
||||
struct dynbuf *buf);
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
Curl_send_buffer *req_buffer);
|
||||
struct dynbuf *req_buffer);
|
||||
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
Curl_send_buffer **buffer,
|
||||
struct dynbuf *buf,
|
||||
struct Curl_easy *handle);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
@@ -154,9 +135,9 @@ struct HTTP {
|
||||
} sending;
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in
|
||||
one chunk, points to an allocated
|
||||
send_buffer struct */
|
||||
struct dynbuf send_buffer; /* used if the request couldn't be sent in one
|
||||
chunk, points to an allocated send_buffer
|
||||
struct */
|
||||
#endif
|
||||
#ifdef USE_NGHTTP2
|
||||
/*********** for HTTP/2 we store stream-local data here *************/
|
||||
@@ -164,10 +145,9 @@ struct HTTP {
|
||||
|
||||
bool bodystarted;
|
||||
/* We store non-final and final response headers here, per-stream */
|
||||
Curl_send_buffer *header_recvbuf;
|
||||
struct dynbuf header_recvbuf;
|
||||
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
|
||||
upper layer */
|
||||
Curl_send_buffer *trailer_recvbuf;
|
||||
int status_code; /* HTTP status code */
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
@@ -201,9 +181,7 @@ struct HTTP {
|
||||
#ifdef USE_NGHTTP3
|
||||
size_t unacked_window;
|
||||
struct h3out *h3out; /* per-stream buffers for upload */
|
||||
char *overflow_buf; /* excess data received during a single Curl_read */
|
||||
size_t overflow_buflen; /* amount of data currently in overflow_buf */
|
||||
size_t overflow_bufsize; /* size of the overflow_buf allocation */
|
||||
struct dynbuf overflow; /* excess data received during a single Curl_read */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "connect.h"
|
||||
#include "strtoofft.h"
|
||||
#include "strdup.h"
|
||||
#include "dynbuf.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -124,8 +125,7 @@ static int http2_getsock(struct connectdata *conn,
|
||||
static void http2_stream_free(struct HTTP *http)
|
||||
{
|
||||
if(http) {
|
||||
Curl_add_buffer_free(&http->header_recvbuf);
|
||||
Curl_add_buffer_free(&http->trailer_recvbuf);
|
||||
Curl_dyn_free(&http->header_recvbuf);
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
@@ -258,16 +258,14 @@ static unsigned int http2_conncheck(struct connectdata *check,
|
||||
void Curl_http2_setup_req(struct Curl_easy *data)
|
||||
{
|
||||
struct HTTP *http = data->req.protop;
|
||||
|
||||
http->nread_header_recvbuf = 0;
|
||||
http->bodystarted = FALSE;
|
||||
http->status_code = -1;
|
||||
http->pausedata = NULL;
|
||||
http->pauselen = 0;
|
||||
http->closed = FALSE;
|
||||
http->close_handled = FALSE;
|
||||
http->mem = data->state.buffer;
|
||||
http->len = data->set.buffer_size;
|
||||
http->mem = NULL;
|
||||
http->len = 0;
|
||||
http->memlen = 0;
|
||||
}
|
||||
|
||||
@@ -333,7 +331,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
int Curl_http2_ver(char *p, size_t len)
|
||||
{
|
||||
nghttp2_info *h2 = nghttp2_version(0);
|
||||
return msnprintf(p, len, " nghttp2/%s", h2->version_str);
|
||||
return msnprintf(p, len, "nghttp2/%s", h2->version_str);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -463,15 +461,9 @@ static struct Curl_easy *duphandle(struct Curl_easy *data)
|
||||
}
|
||||
else {
|
||||
second->req.protop = http;
|
||||
http->header_recvbuf = Curl_add_buffer_init();
|
||||
if(!http->header_recvbuf) {
|
||||
free(http);
|
||||
(void)Curl_close(&second);
|
||||
}
|
||||
else {
|
||||
Curl_http2_setup_req(second);
|
||||
second->state.stream_weight = data->state.stream_weight;
|
||||
}
|
||||
Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
|
||||
Curl_http2_setup_req(second);
|
||||
second->state.stream_weight = data->state.stream_weight;
|
||||
}
|
||||
}
|
||||
return second;
|
||||
@@ -668,15 +660,17 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
stream->status_code = -1;
|
||||
}
|
||||
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
||||
left = Curl_dyn_len(&stream->header_recvbuf) -
|
||||
stream->nread_header_recvbuf;
|
||||
ncopy = CURLMIN(stream->len, left);
|
||||
|
||||
memcpy(&stream->mem[stream->memlen],
|
||||
stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
||||
Curl_dyn_ptr(&stream->header_recvbuf) +
|
||||
stream->nread_header_recvbuf,
|
||||
ncopy);
|
||||
stream->nread_header_recvbuf += ncopy;
|
||||
|
||||
@@ -852,12 +846,6 @@ static int on_begin_headers(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!stream->trailer_recvbuf) {
|
||||
stream->trailer_recvbuf = Curl_add_buffer_init();
|
||||
if(!stream->trailer_recvbuf) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -973,26 +961,19 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
}
|
||||
|
||||
if(stream->bodystarted) {
|
||||
/* This is trailer fields. */
|
||||
/* 4 is for ": " and "\r\n". */
|
||||
uint32_t n = (uint32_t)(namelen + valuelen + 4);
|
||||
|
||||
/* This is a trailer */
|
||||
struct dynbuf trail;
|
||||
H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
value));
|
||||
|
||||
result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3);
|
||||
Curl_dyn_init(&trail, DYN_H2_TRAILER);
|
||||
result = Curl_dyn_addf(&trail,
|
||||
"%.*s: %.*s\r\n", namelen, name,
|
||||
valuelen, value);
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
Curl_dyn_ptr(&trail),
|
||||
Curl_dyn_len(&trail));
|
||||
Curl_dyn_free(&trail);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
@@ -1007,14 +988,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
stream->status_code = decode_status_code(value, valuelen);
|
||||
DEBUGASSERT(stream->status_code != -1);
|
||||
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7);
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "HTTP/2 ");
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
/* the space character after the status code is mandatory */
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3);
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, " \r\n");
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
/* if we receive data for another handle, wake that up */
|
||||
@@ -1029,16 +1010,16 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
/* nghttp2 guarantees that namelen > 0, and :status was already
|
||||
received, and this is not pseudo-header field . */
|
||||
/* convert to a HTTP1-style header */
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, name, namelen);
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, name, namelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2);
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, ": ");
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
/* if we receive data for another handle, wake that up */
|
||||
@@ -1139,17 +1120,14 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
|
||||
/* there might be allocated resources done before this got the 'h2' pointer
|
||||
setup */
|
||||
if(http->header_recvbuf) {
|
||||
Curl_add_buffer_free(&http->header_recvbuf);
|
||||
Curl_add_buffer_free(&http->trailer_recvbuf);
|
||||
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;
|
||||
Curl_dyn_free(&http->header_recvbuf);
|
||||
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(!httpc->h2) /* not HTTP/2 ? */
|
||||
@@ -1238,7 +1216,7 @@ static CURLcode http2_init(struct connectdata *conn)
|
||||
/*
|
||||
* Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
|
||||
*/
|
||||
CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
@@ -1257,7 +1235,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
httpc->local_settings_num);
|
||||
if(!binlen) {
|
||||
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||
Curl_add_buffer_free(&req);
|
||||
Curl_dyn_free(req);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
conn->proto.httpc.binlen = binlen;
|
||||
@@ -1265,15 +1243,15 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
|
||||
&base64, &blen);
|
||||
if(result) {
|
||||
Curl_add_buffer_free(&req);
|
||||
Curl_dyn_free(req);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_add_bufferf(&req,
|
||||
"Connection: Upgrade, HTTP2-Settings\r\n"
|
||||
"Upgrade: %s\r\n"
|
||||
"HTTP2-Settings: %s\r\n",
|
||||
NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
|
||||
result = Curl_dyn_addf(req,
|
||||
"Connection: Upgrade, HTTP2-Settings\r\n"
|
||||
"Upgrade: %s\r\n"
|
||||
"HTTP2-Settings: %s\r\n",
|
||||
NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
|
||||
free(base64);
|
||||
|
||||
k->upgr101 = UPGR101_REQUESTED;
|
||||
@@ -1367,10 +1345,11 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
|
||||
struct HTTP *stream = conn->data->req.protop;
|
||||
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
nghttp2_session *h2 = httpc->h2;
|
||||
|
||||
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! */
|
||||
|
||||
@@ -1380,6 +1359,23 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
|
||||
(void)h2_process_pending_input(conn, httpc, &result);
|
||||
}
|
||||
|
||||
/* If nghttp2 still has pending frames unsent */
|
||||
if(nghttp2_session_want_write(h2)) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int rv;
|
||||
|
||||
H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data));
|
||||
|
||||
/* re-set KEEP_SEND to make sure we are called again */
|
||||
k->keepon |= KEEP_SEND;
|
||||
|
||||
/* and attempt to send the pending frames */
|
||||
rv = h2_session_send(data, h2);
|
||||
if(rv != 0)
|
||||
result = CURLE_SEND_ERROR;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1388,8 +1384,6 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
struct HTTP *stream, CURLcode *err)
|
||||
{
|
||||
char *trailer_pos, *trailer_end;
|
||||
CURLcode result;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
if(httpc->pause_stream_id == stream->stream_id) {
|
||||
@@ -1432,25 +1426,6 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) {
|
||||
trailer_pos = stream->trailer_recvbuf->buffer;
|
||||
trailer_end = trailer_pos + stream->trailer_recvbuf->size_used;
|
||||
|
||||
for(; trailer_pos < trailer_end;) {
|
||||
uint32_t n;
|
||||
memcpy(&n, trailer_pos, sizeof(n));
|
||||
trailer_pos += sizeof(n);
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n);
|
||||
if(result) {
|
||||
*err = result;
|
||||
return -1;
|
||||
}
|
||||
|
||||
trailer_pos += n + 1;
|
||||
}
|
||||
}
|
||||
|
||||
stream->close_handled = TRUE;
|
||||
|
||||
H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
||||
@@ -1541,13 +1516,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
*/
|
||||
|
||||
if(stream->bodystarted &&
|
||||
stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
|
||||
/* If there is body data pending for this stream to return, do that */
|
||||
stream->nread_header_recvbuf < Curl_dyn_len(&stream->header_recvbuf)) {
|
||||
/* If there is header data pending for this stream to return, do that */
|
||||
size_t left =
|
||||
stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
||||
Curl_dyn_len(&stream->header_recvbuf) - stream->nread_header_recvbuf;
|
||||
size_t ncopy = CURLMIN(len, left);
|
||||
memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
||||
ncopy);
|
||||
memcpy(mem, Curl_dyn_ptr(&stream->header_recvbuf) +
|
||||
stream->nread_header_recvbuf, ncopy);
|
||||
stream->nread_header_recvbuf += ncopy;
|
||||
|
||||
H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
|
||||
@@ -1727,8 +1702,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
return retlen;
|
||||
}
|
||||
/* If this stream is closed, return 0 to signal the http routine to close
|
||||
the connection */
|
||||
if(stream->closed)
|
||||
return 0;
|
||||
*err = CURLE_AGAIN;
|
||||
@@ -2058,7 +2031,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
h2_pri_spec(conn->data, &pri_spec);
|
||||
|
||||
switch(conn->data->set.httpreq) {
|
||||
switch(conn->data->state.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_POST_MIME:
|
||||
@@ -2129,13 +2102,11 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct HTTP *stream = conn->data->req.protop;
|
||||
|
||||
DEBUGASSERT(conn->data->state.buffer);
|
||||
|
||||
stream->stream_id = -1;
|
||||
|
||||
if(!stream->header_recvbuf) {
|
||||
stream->header_recvbuf = Curl_add_buffer_init();
|
||||
if(!stream->header_recvbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
|
||||
|
||||
if((conn->handler == &Curl_handler_http2_ssl) ||
|
||||
(conn->handler == &Curl_handler_http2))
|
||||
@@ -2148,7 +2119,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
|
||||
result = http2_init(conn);
|
||||
if(result) {
|
||||
Curl_add_buffer_free(&stream->header_recvbuf);
|
||||
Curl_dyn_free(&stream->header_recvbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2156,6 +2127,8 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
stream->upload_left = 0;
|
||||
stream->upload_mem = NULL;
|
||||
stream->upload_len = 0;
|
||||
stream->mem = conn->data->state.buffer;
|
||||
stream->len = conn->data->set.buffer_size;
|
||||
|
||||
httpc->inbuflen = 0;
|
||||
httpc->nread_inbuf = 0;
|
||||
|
||||
@@ -42,7 +42,7 @@ const char *Curl_http2_strerror(uint32_t err);
|
||||
CURLcode Curl_http2_init(struct connectdata *conn);
|
||||
void Curl_http2_init_state(struct UrlState *state);
|
||||
void Curl_http2_init_userset(struct UserDefined *set);
|
||||
CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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 @@
|
||||
|
||||
#include "urldata.h" /* it includes http_chunks.h */
|
||||
#include "sendf.h" /* for the client write stuff */
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http.h"
|
||||
#include "non-ascii.h" /* for Curl_convert_to_network prototype */
|
||||
@@ -93,6 +93,7 @@ void Curl_httpchunk_init(struct connectdata *conn)
|
||||
chunk->hexindex = 0; /* start at 0 */
|
||||
chunk->dataleft = 0; /* no data left yet! */
|
||||
chunk->state = CHUNK_HEX; /* we get hex first! */
|
||||
Curl_dyn_init(&conn->trailer, DYN_H1_TRAILER);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -177,7 +178,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
/* we're now expecting data to come, unless size was zero! */
|
||||
if(0 == ch->datasize) {
|
||||
ch->state = CHUNK_TRAILER; /* now check for trailers */
|
||||
conn->trlPos = 0;
|
||||
}
|
||||
else
|
||||
ch->state = CHUNK_DATA;
|
||||
@@ -229,32 +229,33 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
|
||||
case CHUNK_TRAILER:
|
||||
if((*datap == 0x0d) || (*datap == 0x0a)) {
|
||||
char *tr = Curl_dyn_ptr(&conn->trailer);
|
||||
/* this is the end of a trailer, but if the trailer was zero bytes
|
||||
there was no trailer and we move on */
|
||||
|
||||
if(conn->trlPos) {
|
||||
/* we allocate trailer with 3 bytes extra room to fit this */
|
||||
conn->trailer[conn->trlPos++] = 0x0d;
|
||||
conn->trailer[conn->trlPos++] = 0x0a;
|
||||
conn->trailer[conn->trlPos] = 0;
|
||||
if(tr) {
|
||||
size_t trlen;
|
||||
result = Curl_dyn_add(&conn->trailer, (char *)"\x0d\x0a");
|
||||
if(result)
|
||||
return CHUNKE_OUT_OF_MEMORY;
|
||||
|
||||
tr = Curl_dyn_ptr(&conn->trailer);
|
||||
trlen = Curl_dyn_len(&conn->trailer);
|
||||
/* Convert to host encoding before calling Curl_client_write */
|
||||
result = Curl_convert_from_network(conn->data, conn->trailer,
|
||||
conn->trlPos);
|
||||
result = Curl_convert_from_network(conn->data, tr, trlen);
|
||||
if(result)
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* Treat it as a bad chunk */
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
|
||||
if(!data->set.http_te_skip) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
conn->trailer, conn->trlPos);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen);
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
return CHUNKE_PASSTHRU_ERROR;
|
||||
}
|
||||
}
|
||||
conn->trlPos = 0;
|
||||
Curl_dyn_reset(&conn->trailer);
|
||||
ch->state = CHUNK_TRAILER_CR;
|
||||
if(*datap == 0x0a)
|
||||
/* already on the LF */
|
||||
@@ -267,25 +268,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* conn->trailer is assumed to be freed in url.c on a
|
||||
connection basis */
|
||||
if(conn->trlPos >= conn->trlMax) {
|
||||
/* we always allocate three extra bytes, just because when the full
|
||||
header has been received we append CRLF\0 */
|
||||
char *ptr;
|
||||
if(conn->trlMax) {
|
||||
conn->trlMax *= 2;
|
||||
ptr = realloc(conn->trailer, conn->trlMax + 3);
|
||||
}
|
||||
else {
|
||||
conn->trlMax = 128;
|
||||
ptr = malloc(conn->trlMax + 3);
|
||||
}
|
||||
if(!ptr)
|
||||
return CHUNKE_OUT_OF_MEMORY;
|
||||
conn->trailer = ptr;
|
||||
}
|
||||
conn->trailer[conn->trlPos++]=*datap;
|
||||
result = Curl_dyn_addn(&conn->trailer, datap, 1);
|
||||
if(result)
|
||||
return CHUNKE_OUT_OF_MEMORY;
|
||||
}
|
||||
datap++;
|
||||
length--;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -94,15 +94,19 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
struct auth *authp;
|
||||
|
||||
if(proxy) {
|
||||
#ifdef CURL_DISABLE_PROXY
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#else
|
||||
digest = &data->state.proxydigest;
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
allocuserpwd = &data->state.aptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
authp = &data->state.authproxy;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
digest = &data->state.digest;
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
allocuserpwd = &data->state.aptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
authp = &data->state.authhost;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 +52,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
curlnegotiate state;
|
||||
|
||||
if(proxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
@@ -59,6 +60,9 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
host = conn->http_proxy.host.name;
|
||||
neg_ctx = &conn->proxyneg;
|
||||
state = conn->proxy_negotiate_state;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
userp = conn->user;
|
||||
@@ -119,7 +123,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
struct auth *authp = proxy ? &conn->data->state.authproxy :
|
||||
&conn->data->state.authhost;
|
||||
curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
|
||||
&conn->http_negotiate_state;
|
||||
&conn->http_negotiate_state;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *base64 = NULL;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
@@ -164,15 +169,15 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
return result;
|
||||
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
base64);
|
||||
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||
data->state.aptr.proxyuserpwd = userp;
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
Curl_safefree(data->state.aptr.userpwd);
|
||||
data->state.aptr.userpwd = userp;
|
||||
}
|
||||
|
||||
free(base64);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 +33,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_auth_cleanup_negotiate(struct connectdata *conn);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
#else /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
#define Curl_http_auth_cleanup_negotiate(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -131,12 +131,15 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
struct ntlmdata *ntlm;
|
||||
curlntlm *state;
|
||||
struct auth *authp;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->data);
|
||||
DEBUGASSERT(data);
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
allocuserpwd = &data->state.aptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
@@ -145,9 +148,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
ntlm = &conn->proxyntlm;
|
||||
state = &conn->proxy_ntlm_state;
|
||||
authp = &conn->data->state.authproxy;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
allocuserpwd = &data->state.aptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
service = conn->data->set.str[STRING_SERVICE_NAME] ?
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 +35,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_auth_cleanup_ntlm(struct connectdata *conn);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
|
||||
#else /* !CURL_DISABLE_HTTP && USE_NTLM */
|
||||
#define Curl_http_auth_cleanup_ntlm(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_NTLM_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,6 +72,7 @@ static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
|
||||
const CURLcode result = https_proxy_connect(conn, sockindex);
|
||||
if(result)
|
||||
@@ -127,7 +128,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
conn->data->req.protop = prot_save;
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
@@ -158,15 +159,15 @@ static CURLcode connect_init(struct connectdata *conn, bool reinit)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
infof(conn->data, "allocate connect buffer!\n");
|
||||
conn->connect_state = s;
|
||||
Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
|
||||
}
|
||||
else {
|
||||
DEBUGASSERT(conn->connect_state);
|
||||
s = conn->connect_state;
|
||||
Curl_dyn_reset(&s->rcvbuf);
|
||||
}
|
||||
s->tunnel_state = TUNNEL_INIT;
|
||||
s->keepon = TRUE;
|
||||
s->line_start = s->connect_buffer;
|
||||
s->ptr = s->line_start;
|
||||
s->cl = 0;
|
||||
s->close_connection = FALSE;
|
||||
return CURLE_OK;
|
||||
@@ -176,6 +177,7 @@ static void connect_done(struct connectdata *conn)
|
||||
{
|
||||
struct http_connect_state *s = conn->connect_state;
|
||||
s->tunnel_state = TUNNEL_COMPLETE;
|
||||
Curl_dyn_free(&s->rcvbuf);
|
||||
infof(conn->data, "CONNECT phase completed!\n");
|
||||
}
|
||||
|
||||
@@ -190,6 +192,8 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
CURLcode result;
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
struct http_connect_state *s = conn->connect_state;
|
||||
char *linep;
|
||||
size_t perline;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@@ -204,7 +208,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(TUNNEL_INIT == s->tunnel_state) {
|
||||
/* BEGIN CONNECT PHASE */
|
||||
char *host_port;
|
||||
Curl_send_buffer *req_buffer;
|
||||
struct dynbuf req;
|
||||
|
||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
|
||||
hostname, remote_port);
|
||||
@@ -215,17 +219,12 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
|
||||
if(!req_buffer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
host_port = aprintf("%s:%d", hostname, remote_port);
|
||||
if(!host_port) {
|
||||
Curl_add_buffer_free(&req_buffer);
|
||||
if(!host_port)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
Curl_dyn_init(&req, DYN_HTTP_REQUEST);
|
||||
|
||||
/* Setup the proxy-authorization header, if any */
|
||||
result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
|
||||
@@ -236,8 +235,8 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
char *host = NULL;
|
||||
const char *proxyconn = "";
|
||||
const char *useragent = "";
|
||||
const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
"1.0" : "1.1";
|
||||
const char *httpv =
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
|
||||
bool ipv6_ip = conn->bits.ipv6_ip;
|
||||
char *hostheader;
|
||||
|
||||
@@ -248,7 +247,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
|
||||
remote_port);
|
||||
if(!hostheader) {
|
||||
Curl_add_buffer_free(&req_buffer);
|
||||
Curl_dyn_free(&req);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -256,7 +255,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
host = aprintf("Host: %s\r\n", hostheader);
|
||||
if(!host) {
|
||||
free(hostheader);
|
||||
Curl_add_buffer_free(&req_buffer);
|
||||
Curl_dyn_free(&req);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
@@ -265,52 +264,49 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = conn->allocptr.uagent;
|
||||
useragent = data->state.aptr.uagent;
|
||||
|
||||
result =
|
||||
Curl_add_bufferf(&req_buffer,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
http,
|
||||
host?host:"",
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
useragent,
|
||||
proxyconn);
|
||||
Curl_dyn_addf(&req,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
httpv,
|
||||
host?host:"",
|
||||
data->state.aptr.proxyuserpwd?
|
||||
data->state.aptr.proxyuserpwd:"",
|
||||
useragent,
|
||||
proxyconn);
|
||||
|
||||
if(host)
|
||||
free(host);
|
||||
free(hostheader);
|
||||
|
||||
if(!result)
|
||||
result = Curl_add_custom_headers(conn, TRUE, req_buffer);
|
||||
result = Curl_add_custom_headers(conn, TRUE, &req);
|
||||
|
||||
if(!result)
|
||||
/* CRLF terminate the request */
|
||||
result = Curl_add_bufferf(&req_buffer, "\r\n");
|
||||
result = Curl_dyn_add(&req, "\r\n");
|
||||
|
||||
if(!result) {
|
||||
/* Send the connect request to the proxy */
|
||||
/* BLOCKING */
|
||||
result =
|
||||
Curl_add_buffer_send(&req_buffer, conn,
|
||||
&data->info.request_size, 0, sockindex);
|
||||
result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
|
||||
sockindex);
|
||||
}
|
||||
req_buffer = NULL;
|
||||
if(result)
|
||||
failf(data, "Failed sending CONNECT to proxy");
|
||||
}
|
||||
|
||||
Curl_add_buffer_free(&req_buffer);
|
||||
Curl_dyn_free(&req);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
s->tunnel_state = TUNNEL_CONNECT;
|
||||
s->perline = 0;
|
||||
} /* END CONNECT PHASE */
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
@@ -330,16 +326,11 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
while(s->keepon) {
|
||||
ssize_t gotbytes;
|
||||
|
||||
/* make sure we have space to read more data */
|
||||
if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) {
|
||||
failf(data, "CONNECT response too large!");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
char byte;
|
||||
|
||||
/* Read one byte at a time to avoid a race condition. Wait at most one
|
||||
second before looping to ensure continuous pgrsUpdates. */
|
||||
result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes);
|
||||
result = Curl_read(conn, tunnelsocket, &byte, 1, &gotbytes);
|
||||
if(result == CURLE_AGAIN)
|
||||
/* socket buffer drained, return */
|
||||
return CURLE_OK;
|
||||
@@ -366,11 +357,9 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(s->keepon > TRUE) {
|
||||
/* This means we are currently ignoring a response-body */
|
||||
|
||||
s->ptr = s->connect_buffer;
|
||||
if(s->cl) {
|
||||
/* A Content-Length based body: simply count down the counter
|
||||
and make sure to break out of the loop when we're done! */
|
||||
@@ -390,7 +379,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
/* now parse the chunked piece of data so that we can
|
||||
properly tell when the stream ends */
|
||||
r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof, &extra);
|
||||
r = Curl_httpchunk_read(conn, &byte, 1, &tookcareof, &extra);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
infof(data, "chunk reading DONE\n");
|
||||
@@ -402,25 +391,27 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
continue;
|
||||
}
|
||||
|
||||
s->perline++; /* amount of bytes in this line so far */
|
||||
|
||||
/* if this is not the end of a header line then continue */
|
||||
if(*s->ptr != 0x0a) {
|
||||
s->ptr++;
|
||||
continue;
|
||||
if(Curl_dyn_addn(&s->rcvbuf, &byte, 1)) {
|
||||
failf(data, "CONNECT response too large!");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
/* if this is not the end of a header line then continue */
|
||||
if(byte != 0x0a)
|
||||
continue;
|
||||
|
||||
linep = Curl_dyn_ptr(&s->rcvbuf);
|
||||
perline = Curl_dyn_len(&s->rcvbuf); /* amount of bytes in this line */
|
||||
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, s->line_start,
|
||||
(size_t)s->perline);
|
||||
result = Curl_convert_from_network(data, linep, perline);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* output debug if that is requested */
|
||||
if(data->set.verbose)
|
||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||
s->line_start, (size_t)s->perline);
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
|
||||
|
||||
if(!data->set.suppress_connect_headers) {
|
||||
/* send the header to the callback */
|
||||
@@ -428,23 +419,22 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
result = Curl_client_write(conn, writetype,
|
||||
s->line_start, s->perline);
|
||||
result = Curl_client_write(conn, writetype, linep, perline);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
data->info.header_size += (long)s->perline;
|
||||
data->req.headerbytecount += (long)s->perline;
|
||||
data->info.header_size += (long)perline;
|
||||
data->req.headerbytecount += (long)perline;
|
||||
|
||||
/* Newlines are CRLF, so the CR is ignored as the line isn't
|
||||
really terminated until the LF comes. Treat a following CR
|
||||
as end-of-headers as well.*/
|
||||
|
||||
if(('\r' == s->line_start[0]) ||
|
||||
('\n' == s->line_start[0])) {
|
||||
if(('\r' == linep[0]) ||
|
||||
('\n' == linep[0])) {
|
||||
/* end of response-headers from the proxy */
|
||||
s->ptr = s->connect_buffer;
|
||||
|
||||
if((407 == k->httpcode) && !data->state.authproblem) {
|
||||
/* If we get a 407 response code with content length
|
||||
when we have no auth problem, we must ignore the
|
||||
@@ -461,21 +451,18 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
infof(data, "Ignore chunked response-body\n");
|
||||
|
||||
/* We set ignorebody true here since the chunked
|
||||
decoder function will acknowledge that. Pay
|
||||
attention so that this is cleared again when this
|
||||
function returns! */
|
||||
/* We set ignorebody true here since the chunked decoder
|
||||
function will acknowledge that. Pay attention so that this is
|
||||
cleared again when this function returns! */
|
||||
k->ignorebody = TRUE;
|
||||
|
||||
if(s->line_start[1] == '\n') {
|
||||
/* this can only be a LF if the letter at index 0
|
||||
was a CR */
|
||||
s->line_start++;
|
||||
}
|
||||
if(linep[1] == '\n')
|
||||
/* this can only be a LF if the letter at index 0 was a CR */
|
||||
linep++;
|
||||
|
||||
/* now parse the chunked piece of data so that we can
|
||||
properly tell when the stream ends */
|
||||
r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes,
|
||||
/* now parse the chunked piece of data so that we can properly
|
||||
tell when the stream ends */
|
||||
r = Curl_httpchunk_read(conn, linep + 1, 1, &gotbytes,
|
||||
&extra);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
@@ -500,14 +487,13 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
continue;
|
||||
}
|
||||
|
||||
s->line_start[s->perline] = 0; /* zero terminate the buffer */
|
||||
if((checkprefix("WWW-Authenticate:", s->line_start) &&
|
||||
if((checkprefix("WWW-Authenticate:", linep) &&
|
||||
(401 == k->httpcode)) ||
|
||||
(checkprefix("Proxy-authenticate:", s->line_start) &&
|
||||
(checkprefix("Proxy-authenticate:", linep) &&
|
||||
(407 == k->httpcode))) {
|
||||
|
||||
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
|
||||
char *auth = Curl_copy_header_value(s->line_start);
|
||||
char *auth = Curl_copy_header_value(linep);
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -518,7 +504,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else if(checkprefix("Content-Length:", s->line_start)) {
|
||||
else if(checkprefix("Content-Length:", linep)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
@@ -527,13 +513,13 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
k->httpcode);
|
||||
}
|
||||
else {
|
||||
(void)curlx_strtoofft(s->line_start +
|
||||
(void)curlx_strtoofft(linep +
|
||||
strlen("Content-Length:"), NULL, 10, &s->cl);
|
||||
}
|
||||
}
|
||||
else if(Curl_compareheader(s->line_start, "Connection:", "close"))
|
||||
else if(Curl_compareheader(linep, "Connection:", "close"))
|
||||
s->close_connection = TRUE;
|
||||
else if(checkprefix("Transfer-Encoding:", s->line_start)) {
|
||||
else if(checkprefix("Transfer-Encoding:", linep)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
@@ -541,7 +527,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
infof(data, "Ignoring Transfer-Encoding in "
|
||||
"CONNECT %03d response\n", k->httpcode);
|
||||
}
|
||||
else if(Curl_compareheader(s->line_start,
|
||||
else if(Curl_compareheader(linep,
|
||||
"Transfer-Encoding:", "chunked")) {
|
||||
infof(data, "CONNECT responded chunked\n");
|
||||
s->chunked_encoding = TRUE;
|
||||
@@ -549,19 +535,16 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
Curl_httpchunk_init(conn);
|
||||
}
|
||||
}
|
||||
else if(Curl_compareheader(s->line_start,
|
||||
"Proxy-Connection:", "close"))
|
||||
else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
|
||||
s->close_connection = TRUE;
|
||||
else if(2 == sscanf(s->line_start, "HTTP/1.%d %d",
|
||||
else if(2 == sscanf(linep, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&k->httpcode)) {
|
||||
/* store the HTTP code from the proxy */
|
||||
data->info.httpproxycode = k->httpcode;
|
||||
}
|
||||
|
||||
s->perline = 0; /* line starts over here */
|
||||
s->ptr = s->connect_buffer;
|
||||
s->line_start = s->ptr;
|
||||
Curl_dyn_reset(&s->rcvbuf);
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
@@ -622,6 +605,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(conn->bits.proxy_connect_closed)
|
||||
/* this is not an error, just part of the connection negotiation */
|
||||
return CURLE_OK;
|
||||
Curl_dyn_free(&s->rcvbuf);
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -632,8 +616,8 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
/* If a proxy-authorization header was used for the proxy, then we should
|
||||
make sure that it isn't accidentally used for the document request
|
||||
after we've connected. So let's free and clear it here. */
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = NULL;
|
||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||
data->state.aptr.proxyuserpwd = NULL;
|
||||
|
||||
data->state.authproxy.done = TRUE;
|
||||
data->state.authproxy.multipass = FALSE;
|
||||
@@ -643,6 +627,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
|
||||
conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
|
||||
document request */
|
||||
Curl_dyn_free(&s->rcvbuf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -47,5 +47,6 @@ bool Curl_connect_ongoing(struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
void Curl_connect_free(struct Curl_easy *data);
|
||||
void Curl_connect_done(struct Curl_easy *data);
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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,13 +72,13 @@ bool curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
{
|
||||
bool success = FALSE;
|
||||
|
||||
wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
|
||||
wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
|
||||
if(in_w) {
|
||||
wchar_t punycode[IDN_MAX_LENGTH];
|
||||
int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
|
||||
free(in_w);
|
||||
if(chars) {
|
||||
*out = Curl_convert_wchar_to_UTF8(punycode);
|
||||
*out = curlx_convert_wchar_to_UTF8(punycode);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ bool curl_win32_ascii_to_idn(const char *in, char **out)
|
||||
{
|
||||
bool success = FALSE;
|
||||
|
||||
wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
|
||||
wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
|
||||
if(in_w) {
|
||||
size_t in_len = wcslen(in_w) + 1;
|
||||
wchar_t unicode[IDN_MAX_LENGTH];
|
||||
@@ -99,7 +99,7 @@ bool curl_win32_ascii_to_idn(const char *in, char **out)
|
||||
unicode, IDN_MAX_LENGTH);
|
||||
free(in_w);
|
||||
if(chars) {
|
||||
*out = Curl_convert_wchar_to_UTF8(unicode);
|
||||
*out = curlx_convert_wchar_to_UTF8(unicode);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -129,11 +129,11 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
|
||||
|
||||
if(ifscope != remote_scope) {
|
||||
/* We are interested only in interface addresses whose
|
||||
scope matches the remote address we want to
|
||||
connect to: global for global, link-local for
|
||||
link-local, etc... */
|
||||
if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
|
||||
/* We are interested only in interface addresses whose scope
|
||||
matches the remote address we want to connect to: global
|
||||
for global, link-local for link-local, etc... */
|
||||
if(res == IF2IP_NOT_FOUND)
|
||||
res = IF2IP_AF_NOT_SUPPORTED;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -187,7 +187,7 @@ static void imap_to_imaps(struct connectdata *conn)
|
||||
conn->handler = &Curl_handler_imaps;
|
||||
|
||||
/* Set the connection's upgraded to TLS flag */
|
||||
conn->tls_upgraded = TRUE;
|
||||
conn->bits.tls_upgraded = TRUE;
|
||||
}
|
||||
#else
|
||||
#define imap_to_imaps(x) Curl_nop_stmt
|
||||
@@ -1710,7 +1710,7 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
|
||||
return result;
|
||||
|
||||
/* Clear the TLS upgraded flag */
|
||||
conn->tls_upgraded = FALSE;
|
||||
conn->bits.tls_upgraded = FALSE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
/* Use our own implementation. */
|
||||
|
||||
typedef struct {
|
||||
struct ldap_urldesc {
|
||||
char *lud_host;
|
||||
int lud_port;
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
@@ -95,10 +95,10 @@ typedef struct {
|
||||
size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the
|
||||
"real" struct so can only be used in code
|
||||
without HAVE_LDAP_URL_PARSE defined */
|
||||
} CURL_LDAPURLDesc;
|
||||
};
|
||||
|
||||
#undef LDAPURLDesc
|
||||
#define LDAPURLDesc CURL_LDAPURLDesc
|
||||
#define LDAPURLDesc struct ldap_urldesc
|
||||
|
||||
static int _ldap_url_parse(const struct connectdata *conn,
|
||||
LDAPURLDesc **ludp);
|
||||
@@ -239,13 +239,13 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server,
|
||||
PTCHAR inpass = NULL;
|
||||
|
||||
if(user && passwd && (conn->data->set.httpauth & CURLAUTH_BASIC)) {
|
||||
inuser = Curl_convert_UTF8_to_tchar((char *) user);
|
||||
inpass = Curl_convert_UTF8_to_tchar((char *) passwd);
|
||||
inuser = curlx_convert_UTF8_to_tchar((char *) user);
|
||||
inpass = curlx_convert_UTF8_to_tchar((char *) passwd);
|
||||
|
||||
rc = ldap_simple_bind_s(server, inuser, inpass);
|
||||
|
||||
Curl_unicodefree(inuser);
|
||||
Curl_unicodefree(inpass);
|
||||
curlx_unicodefree(inuser);
|
||||
curlx_unicodefree(inpass);
|
||||
}
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
else {
|
||||
@@ -306,7 +306,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
ldap_ssl ? "encrypted" : "cleartext");
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
host = Curl_convert_UTF8_to_tchar(conn->host.name);
|
||||
host = curlx_convert_UTF8_to_tchar(conn->host.name);
|
||||
if(!host) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -517,7 +517,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
size_t name_len;
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
TCHAR *dn = ldap_get_dn(server, entryIterator);
|
||||
name = Curl_convert_tchar_to_UTF8(dn);
|
||||
name = curlx_convert_tchar_to_UTF8(dn);
|
||||
if(!name) {
|
||||
ldap_memfree(dn);
|
||||
|
||||
@@ -533,7 +533,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
if(result) {
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(name);
|
||||
curlx_unicodefree(name);
|
||||
#endif
|
||||
ldap_memfree(dn);
|
||||
|
||||
@@ -544,7 +544,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
name_len);
|
||||
if(result) {
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(name);
|
||||
curlx_unicodefree(name);
|
||||
#endif
|
||||
ldap_memfree(dn);
|
||||
|
||||
@@ -554,7 +554,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(result) {
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(name);
|
||||
curlx_unicodefree(name);
|
||||
#endif
|
||||
ldap_memfree(dn);
|
||||
|
||||
@@ -564,7 +564,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
dlsize += name_len + 5;
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(name);
|
||||
curlx_unicodefree(name);
|
||||
#endif
|
||||
ldap_memfree(dn);
|
||||
}
|
||||
@@ -576,7 +576,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
BerValue **vals;
|
||||
size_t attr_len;
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
char *attr = Curl_convert_tchar_to_UTF8(attribute);
|
||||
char *attr = curlx_convert_tchar_to_UTF8(attribute);
|
||||
if(!attr) {
|
||||
if(ber)
|
||||
ber_free(ber, 0);
|
||||
@@ -597,7 +597,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -611,7 +611,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -624,7 +624,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -646,7 +646,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -662,7 +662,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -680,7 +680,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -696,7 +696,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
if(ber)
|
||||
@@ -714,7 +714,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Free the attribute as we are done with it */
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(attr);
|
||||
curlx_unicodefree(attr);
|
||||
#endif
|
||||
ldap_memfree(attribute);
|
||||
|
||||
@@ -746,7 +746,7 @@ quit:
|
||||
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
Curl_unicodefree(host);
|
||||
curlx_unicodefree(host);
|
||||
#endif
|
||||
|
||||
/* no data to transfer */
|
||||
@@ -892,10 +892,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
/* Convert the unescaped string to a tchar */
|
||||
ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
|
||||
ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped);
|
||||
|
||||
/* Free the unescaped string as we are done with it */
|
||||
Curl_unicodefree(unescaped);
|
||||
curlx_unicodefree(unescaped);
|
||||
|
||||
if(!ludp->lud_dn) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
@@ -960,10 +960,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
/* Convert the unescaped string to a tchar */
|
||||
ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
|
||||
ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped);
|
||||
|
||||
/* Free the unescaped string as we are done with it */
|
||||
Curl_unicodefree(unescaped);
|
||||
curlx_unicodefree(unescaped);
|
||||
|
||||
if(!ludp->lud_attrs[i]) {
|
||||
free(attributes);
|
||||
@@ -1027,10 +1027,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
/* Convert the unescaped string to a tchar */
|
||||
ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
|
||||
ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped);
|
||||
|
||||
/* Free the unescaped string as we are done with it */
|
||||
Curl_unicodefree(unescaped);
|
||||
curlx_unicodefree(unescaped);
|
||||
|
||||
if(!ludp->lud_filter) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/opensslconf.h>
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||
/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
|
||||
#define OPENSSL_NO_MD4
|
||||
#endif
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
#ifdef USE_MBEDTLS
|
||||
@@ -135,10 +139,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct {
|
||||
struct md4_ctx {
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTHASH hHash;
|
||||
} MD4_CTX;
|
||||
};
|
||||
typedef struct md4_ctx MD4_CTX;
|
||||
|
||||
static void MD4_Init(MD4_CTX *ctx)
|
||||
{
|
||||
@@ -146,7 +151,7 @@ static void MD4_Init(MD4_CTX *ctx)
|
||||
ctx->hHash = 0;
|
||||
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
|
||||
CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
|
||||
}
|
||||
}
|
||||
@@ -180,10 +185,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct {
|
||||
struct md4_ctx {
|
||||
void *data;
|
||||
unsigned long size;
|
||||
} MD4_CTX;
|
||||
};
|
||||
typedef struct md4_ctx MD4_CTX;
|
||||
|
||||
static void MD4_Init(MD4_CTX *ctx)
|
||||
{
|
||||
@@ -262,12 +268,13 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD4_u32plus;
|
||||
|
||||
typedef struct {
|
||||
struct md4_ctx {
|
||||
MD4_u32plus lo, hi;
|
||||
MD4_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
MD4_u32plus block[16];
|
||||
} MD4_CTX;
|
||||
};
|
||||
typedef struct md4_ctx MD4_CTX;
|
||||
|
||||
static void MD4_Init(MD4_CTX *ctx);
|
||||
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
|
||||
|
||||
@@ -179,15 +179,16 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct {
|
||||
struct md5_ctx {
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTHASH hHash;
|
||||
} MD5_CTX;
|
||||
};
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
|
||||
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
|
||||
}
|
||||
}
|
||||
@@ -261,12 +262,13 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD5_u32plus;
|
||||
|
||||
typedef struct {
|
||||
struct md5_ctx {
|
||||
MD5_u32plus lo, hi;
|
||||
MD5_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
MD5_u32plus block[16];
|
||||
} MD5_CTX;
|
||||
};
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx);
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||
@@ -528,7 +530,7 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||
|
||||
#endif /* CRYPTO LIBS */
|
||||
|
||||
const HMAC_params Curl_HMAC_MD5[] = {
|
||||
const struct HMAC_params Curl_HMAC_MD5[] = {
|
||||
{
|
||||
/* Hash initialization function. */
|
||||
CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
|
||||
@@ -545,7 +547,7 @@ const HMAC_params Curl_HMAC_MD5[] = {
|
||||
}
|
||||
};
|
||||
|
||||
const MD5_params Curl_DIGEST_MD5[] = {
|
||||
const struct MD5_params Curl_DIGEST_MD5[] = {
|
||||
{
|
||||
/* Digest initialization function */
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
|
||||
@@ -573,9 +575,9 @@ void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
|
||||
MD5_Final(outbuffer, &ctx);
|
||||
}
|
||||
|
||||
MD5_context *Curl_MD5_init(const MD5_params *md5params)
|
||||
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
|
||||
{
|
||||
MD5_context *ctxt;
|
||||
struct MD5_context *ctxt;
|
||||
|
||||
/* Create MD5 context */
|
||||
ctxt = malloc(sizeof(*ctxt));
|
||||
@@ -597,7 +599,7 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
CURLcode Curl_MD5_update(MD5_context *context,
|
||||
CURLcode Curl_MD5_update(struct MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
@@ -606,7 +608,7 @@ CURLcode Curl_MD5_update(MD5_context *context,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result)
|
||||
CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result)
|
||||
{
|
||||
(*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -328,7 +328,7 @@ void curl_dbg_free(void *ptr, int line, const char *source)
|
||||
(Curl_cfree)(mem);
|
||||
}
|
||||
|
||||
if(source)
|
||||
if(source && ptr)
|
||||
curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "mime.h"
|
||||
#include "non-ascii.h"
|
||||
#include "warnless.h"
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
|
||||
@@ -52,6 +53,10 @@
|
||||
|
||||
|
||||
#define READ_ERROR ((size_t) -1)
|
||||
#define STOP_FILLING ((size_t) -2)
|
||||
|
||||
static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
void *instream, bool *hasread);
|
||||
|
||||
/* Encoders. */
|
||||
static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
|
||||
@@ -66,7 +71,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part);
|
||||
static curl_off_t encoder_qp_size(curl_mimepart *part);
|
||||
|
||||
static const mime_encoder encoders[] = {
|
||||
static const struct mime_encoder encoders[] = {
|
||||
{"binary", encoder_nop_read, encoder_nop_size},
|
||||
{"8bit", encoder_nop_read, encoder_nop_size},
|
||||
{"7bit", encoder_7bit_read, encoder_nop_size},
|
||||
@@ -264,7 +269,8 @@ static char *Curl_basename(char *path)
|
||||
|
||||
|
||||
/* Set readback state. */
|
||||
static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr)
|
||||
static void mimesetstate(struct mime_state *state,
|
||||
enum mimestate tok, void *ptr)
|
||||
{
|
||||
state->state = tok;
|
||||
state->ptr = ptr;
|
||||
@@ -337,7 +343,7 @@ static char *strippath(const char *fullfile)
|
||||
}
|
||||
|
||||
/* Initialize data encoder state. */
|
||||
static void cleanup_encoder_state(mime_encoder_state *p)
|
||||
static void cleanup_encoder_state(struct mime_encoder_state *p)
|
||||
{
|
||||
p->pos = 0;
|
||||
p->bufbeg = 0;
|
||||
@@ -347,17 +353,22 @@ static void cleanup_encoder_state(mime_encoder_state *p)
|
||||
|
||||
/* Dummy encoder. This is used for 8bit and binary content encodings. */
|
||||
static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part)
|
||||
struct curl_mimepart *part)
|
||||
{
|
||||
mime_encoder_state *st = &part->encstate;
|
||||
struct mime_encoder_state *st = &part->encstate;
|
||||
size_t insize = st->bufend - st->bufbeg;
|
||||
|
||||
(void) ateof;
|
||||
|
||||
if(!size)
|
||||
return STOP_FILLING;
|
||||
|
||||
if(size > insize)
|
||||
size = insize;
|
||||
|
||||
if(size)
|
||||
memcpy(buffer, st->buf, size);
|
||||
memcpy(buffer, st->buf + st->bufbeg, size);
|
||||
|
||||
st->bufbeg += size;
|
||||
return size;
|
||||
}
|
||||
@@ -372,11 +383,14 @@ static curl_off_t encoder_nop_size(curl_mimepart *part)
|
||||
static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part)
|
||||
{
|
||||
mime_encoder_state *st = &part->encstate;
|
||||
struct mime_encoder_state *st = &part->encstate;
|
||||
size_t cursize = st->bufend - st->bufbeg;
|
||||
|
||||
(void) ateof;
|
||||
|
||||
if(!size)
|
||||
return STOP_FILLING;
|
||||
|
||||
if(size > cursize)
|
||||
size = cursize;
|
||||
|
||||
@@ -395,7 +409,7 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
|
||||
static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part)
|
||||
{
|
||||
mime_encoder_state *st = &part->encstate;
|
||||
struct mime_encoder_state *st = &part->encstate;
|
||||
size_t cursize = 0;
|
||||
int i;
|
||||
char *ptr = buffer;
|
||||
@@ -404,8 +418,11 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||
/* Line full ? */
|
||||
if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
|
||||
/* Yes, we need 2 characters for CRLF. */
|
||||
if(size < 2)
|
||||
if(size < 2) {
|
||||
if(!cursize)
|
||||
return STOP_FILLING;
|
||||
break;
|
||||
}
|
||||
*ptr++ = '\r';
|
||||
*ptr++ = '\n';
|
||||
st->pos = 0;
|
||||
@@ -414,7 +431,12 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||
}
|
||||
|
||||
/* Be sure there is enough space and input data for a base64 group. */
|
||||
if(size < 4 || st->bufend - st->bufbeg < 3)
|
||||
if(size < 4) {
|
||||
if(!cursize)
|
||||
return STOP_FILLING;
|
||||
break;
|
||||
}
|
||||
if(st->bufend - st->bufbeg < 3)
|
||||
break;
|
||||
|
||||
/* Encode three bytes as four characters. */
|
||||
@@ -431,25 +453,31 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||
}
|
||||
|
||||
/* If at eof, we have to flush the buffered data. */
|
||||
if(ateof && size >= 4) {
|
||||
/* Buffered data size can only be 0, 1 or 2. */
|
||||
ptr[2] = ptr[3] = '=';
|
||||
i = 0;
|
||||
switch(st->bufend - st->bufbeg) {
|
||||
case 2:
|
||||
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
|
||||
ptr[0] = base64[(i >> 18) & 0x3F];
|
||||
ptr[1] = base64[(i >> 12) & 0x3F];
|
||||
if(++st->bufbeg != st->bufend) {
|
||||
ptr[2] = base64[(i >> 6) & 0x3F];
|
||||
st->bufbeg++;
|
||||
if(ateof) {
|
||||
if(size < 4) {
|
||||
if(!cursize)
|
||||
return STOP_FILLING;
|
||||
}
|
||||
else {
|
||||
/* Buffered data size can only be 0, 1 or 2. */
|
||||
ptr[2] = ptr[3] = '=';
|
||||
i = 0;
|
||||
switch(st->bufend - st->bufbeg) {
|
||||
case 2:
|
||||
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
|
||||
ptr[0] = base64[(i >> 18) & 0x3F];
|
||||
ptr[1] = base64[(i >> 12) & 0x3F];
|
||||
if(++st->bufbeg != st->bufend) {
|
||||
ptr[2] = base64[(i >> 6) & 0x3F];
|
||||
st->bufbeg++;
|
||||
}
|
||||
cursize += 4;
|
||||
st->pos += 4;
|
||||
break;
|
||||
}
|
||||
cursize += 4;
|
||||
st->pos += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +513,7 @@ static curl_off_t encoder_base64_size(curl_mimepart *part)
|
||||
* Check if a CRLF or end of data is in input buffer at current position + n.
|
||||
* Return -1 if more data needed, 1 if CRLF or end of data, else 0.
|
||||
*/
|
||||
static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
|
||||
static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n)
|
||||
{
|
||||
n += st->bufbeg;
|
||||
if(n >= st->bufend && ateof)
|
||||
@@ -502,7 +530,7 @@ static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
|
||||
static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part)
|
||||
{
|
||||
mime_encoder_state *st = &part->encstate;
|
||||
struct mime_encoder_state *st = &part->encstate;
|
||||
char *ptr = buffer;
|
||||
size_t cursize = 0;
|
||||
int softlinebreak;
|
||||
@@ -567,7 +595,6 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||
switch(qp_lookahead_eol(st, ateof, consumed)) {
|
||||
case -1: /* Need more data. */
|
||||
return cursize;
|
||||
break;
|
||||
case 0: /* Not followed by a CRLF. */
|
||||
softlinebreak = 1;
|
||||
break;
|
||||
@@ -581,8 +608,11 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
|
||||
}
|
||||
|
||||
/* If the output buffer would overflow, do not store. */
|
||||
if(len > size)
|
||||
if(len > size) {
|
||||
if(!cursize)
|
||||
return STOP_FILLING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Append to output buffer. */
|
||||
memcpy(ptr, buf, len);
|
||||
@@ -612,16 +642,18 @@ static size_t mime_mem_read(char *buffer, size_t size, size_t nitems,
|
||||
void *instream)
|
||||
{
|
||||
curl_mimepart *part = (curl_mimepart *) instream;
|
||||
size_t sz = (size_t) part->datasize - part->state.offset;
|
||||
size_t sz = curlx_sotouz(part->datasize - part->state.offset);
|
||||
(void) size; /* Always 1.*/
|
||||
|
||||
if(!nitems)
|
||||
return STOP_FILLING;
|
||||
|
||||
if(sz > nitems)
|
||||
sz = nitems;
|
||||
|
||||
if(sz)
|
||||
memcpy(buffer, (char *) &part->data[part->state.offset], sz);
|
||||
memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz);
|
||||
|
||||
part->state.offset += sz;
|
||||
return sz;
|
||||
}
|
||||
|
||||
@@ -641,7 +673,7 @@ static int mime_mem_seek(void *instream, curl_off_t offset, int whence)
|
||||
if(offset < 0 || offset > part->datasize)
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
|
||||
part->state.offset = (size_t) offset;
|
||||
part->state.offset = offset;
|
||||
return CURL_SEEKFUNC_OK;
|
||||
}
|
||||
|
||||
@@ -653,7 +685,7 @@ static void mime_mem_free(void *ptr)
|
||||
|
||||
/* Named file callbacks. */
|
||||
/* Argument is a pointer to the mime part. */
|
||||
static int mime_open_file(curl_mimepart * part)
|
||||
static int mime_open_file(curl_mimepart *part)
|
||||
{
|
||||
/* Open a MIMEKIND_FILE part. */
|
||||
|
||||
@@ -668,6 +700,9 @@ static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
|
||||
{
|
||||
curl_mimepart *part = (curl_mimepart *) instream;
|
||||
|
||||
if(!nitems)
|
||||
return STOP_FILLING;
|
||||
|
||||
if(mime_open_file(part))
|
||||
return READ_ERROR;
|
||||
|
||||
@@ -705,21 +740,22 @@ static void mime_file_free(void *ptr)
|
||||
/* Argument is a pointer to the mime structure. */
|
||||
|
||||
/* Readback a byte string segment. */
|
||||
static size_t readback_bytes(mime_state *state,
|
||||
static size_t readback_bytes(struct mime_state *state,
|
||||
char *buffer, size_t bufsize,
|
||||
const char *bytes, size_t numbytes,
|
||||
const char *trail)
|
||||
{
|
||||
size_t sz;
|
||||
size_t offset = curlx_sotouz(state->offset);
|
||||
|
||||
if(numbytes > state->offset) {
|
||||
sz = numbytes - state->offset;
|
||||
bytes += state->offset;
|
||||
if(numbytes > offset) {
|
||||
sz = numbytes - offset;
|
||||
bytes += offset;
|
||||
}
|
||||
else {
|
||||
size_t tsz = strlen(trail);
|
||||
|
||||
sz = state->offset - numbytes;
|
||||
sz = offset - numbytes;
|
||||
if(sz >= tsz)
|
||||
return 0;
|
||||
bytes = trail + sz;
|
||||
@@ -736,25 +772,79 @@ static size_t readback_bytes(mime_state *state,
|
||||
|
||||
/* Read a non-encoded part content. */
|
||||
static size_t read_part_content(curl_mimepart *part,
|
||||
char *buffer, size_t bufsize)
|
||||
char *buffer, size_t bufsize, bool *hasread)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
if(part->readfunc)
|
||||
sz = part->readfunc(buffer, 1, bufsize, part->arg);
|
||||
switch(part->lastreadstatus) {
|
||||
case 0:
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
return part->lastreadstatus;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we can determine we are at end of part data, spare a read. */
|
||||
if(part->datasize != (curl_off_t) -1 &&
|
||||
part->state.offset >= part->datasize) {
|
||||
/* sz is already zero. */
|
||||
}
|
||||
else {
|
||||
switch(part->kind) {
|
||||
case MIMEKIND_MULTIPART:
|
||||
/*
|
||||
* Cannot be processed as other kinds since read function requires
|
||||
* an additional parameter and is highly recursive.
|
||||
*/
|
||||
sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread);
|
||||
break;
|
||||
case MIMEKIND_FILE:
|
||||
if(part->fp && feof(part->fp))
|
||||
break; /* At EOF. */
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if(part->readfunc) {
|
||||
if(!(part->flags & MIME_FAST_READ)) {
|
||||
if(*hasread)
|
||||
return STOP_FILLING;
|
||||
*hasread = TRUE;
|
||||
}
|
||||
sz = part->readfunc(buffer, 1, bufsize, part->arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(sz) {
|
||||
case STOP_FILLING:
|
||||
break;
|
||||
case 0:
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
part->lastreadstatus = sz;
|
||||
break;
|
||||
default:
|
||||
part->state.offset += sz;
|
||||
part->lastreadstatus = sz;
|
||||
break;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Read and encode part content. */
|
||||
static size_t read_encoded_part_content(curl_mimepart *part,
|
||||
char *buffer, size_t bufsize)
|
||||
static size_t read_encoded_part_content(curl_mimepart *part, char *buffer,
|
||||
size_t bufsize, bool *hasread)
|
||||
{
|
||||
mime_encoder_state *st = &part->encstate;
|
||||
struct mime_encoder_state *st = &part->encstate;
|
||||
size_t cursize = 0;
|
||||
size_t sz;
|
||||
bool ateof = FALSE;
|
||||
|
||||
while(bufsize) {
|
||||
for(;;) {
|
||||
if(st->bufbeg < st->bufend || ateof) {
|
||||
/* Encode buffered data. */
|
||||
sz = part->encoder->encodefunc(buffer, bufsize, ateof, part);
|
||||
@@ -763,9 +853,8 @@ static size_t read_encoded_part_content(curl_mimepart *part,
|
||||
if(ateof)
|
||||
return cursize;
|
||||
break;
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
case STOP_FILLING:
|
||||
return cursize? cursize: sz;
|
||||
default:
|
||||
cursize += sz;
|
||||
@@ -787,7 +876,7 @@ static size_t read_encoded_part_content(curl_mimepart *part,
|
||||
if(st->bufend >= sizeof(st->buf))
|
||||
return cursize? cursize: READ_ERROR; /* Buffer full. */
|
||||
sz = read_part_content(part, st->buf + st->bufend,
|
||||
sizeof(st->buf) - st->bufend);
|
||||
sizeof(st->buf) - st->bufend, hasread);
|
||||
switch(sz) {
|
||||
case 0:
|
||||
ateof = TRUE;
|
||||
@@ -795,6 +884,7 @@ static size_t read_encoded_part_content(curl_mimepart *part,
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
case STOP_FILLING:
|
||||
return cursize? cursize: sz;
|
||||
default:
|
||||
st->bufend += sz;
|
||||
@@ -802,12 +892,12 @@ static size_t read_encoded_part_content(curl_mimepart *part,
|
||||
}
|
||||
}
|
||||
|
||||
return cursize;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Readback a mime part. */
|
||||
static size_t readback_part(curl_mimepart *part,
|
||||
char *buffer, size_t bufsize)
|
||||
char *buffer, size_t bufsize, bool *hasread)
|
||||
{
|
||||
size_t cursize = 0;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
@@ -866,9 +956,9 @@ static size_t readback_part(curl_mimepart *part,
|
||||
break;
|
||||
case MIMESTATE_CONTENT:
|
||||
if(part->encoder)
|
||||
sz = read_encoded_part_content(part, buffer, bufsize);
|
||||
sz = read_encoded_part_content(part, buffer, bufsize, hasread);
|
||||
else
|
||||
sz = read_part_content(part, buffer, bufsize);
|
||||
sz = read_part_content(part, buffer, bufsize, hasread);
|
||||
switch(sz) {
|
||||
case 0:
|
||||
mimesetstate(&part->state, MIMESTATE_END, NULL);
|
||||
@@ -881,6 +971,7 @@ static size_t readback_part(curl_mimepart *part,
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
case STOP_FILLING:
|
||||
return cursize? cursize: sz;
|
||||
}
|
||||
break;
|
||||
@@ -909,9 +1000,9 @@ static size_t readback_part(curl_mimepart *part,
|
||||
return cursize;
|
||||
}
|
||||
|
||||
/* Readback from mime. */
|
||||
/* Readback from mime. Warning: not a read callback function. */
|
||||
static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
void *instream)
|
||||
void *instream, bool *hasread)
|
||||
{
|
||||
curl_mime *mime = (curl_mime *) instream;
|
||||
size_t cursize = 0;
|
||||
@@ -932,7 +1023,7 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
#endif
|
||||
mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
|
||||
/* The first boundary always follows the header termination empty line,
|
||||
so is always preceded by a CRLK. We can then spare 2 characters
|
||||
so is always preceded by a CRLF. We can then spare 2 characters
|
||||
by skipping the leading CRLF in boundary. */
|
||||
mime->state.offset += 2;
|
||||
break;
|
||||
@@ -962,11 +1053,12 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
mimesetstate(&mime->state, MIMESTATE_END, NULL);
|
||||
break;
|
||||
}
|
||||
sz = readback_part(part, buffer, nitems);
|
||||
sz = readback_part(part, buffer, nitems, hasread);
|
||||
switch(sz) {
|
||||
case CURL_READFUNC_ABORT:
|
||||
case CURL_READFUNC_PAUSE:
|
||||
case READ_ERROR:
|
||||
case STOP_FILLING:
|
||||
return cursize? cursize: sz;
|
||||
case 0:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
@@ -1031,6 +1123,7 @@ static int mime_part_rewind(curl_mimepart *part)
|
||||
if(res == CURL_SEEKFUNC_OK)
|
||||
mimesetstate(&part->state, targetstate, NULL);
|
||||
|
||||
part->lastreadstatus = 1; /* Successful read status. */
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1073,6 +1166,8 @@ static void cleanup_part_content(curl_mimepart *part)
|
||||
part->datasize = (curl_off_t) 0; /* No size yet. */
|
||||
cleanup_encoder_state(&part->encstate);
|
||||
part->kind = MIMEKIND_NONE;
|
||||
part->flags &= ~MIME_FAST_READ;
|
||||
part->lastreadstatus = 1; /* Successful read status. */
|
||||
}
|
||||
|
||||
static void mime_subparts_free(void *ptr)
|
||||
@@ -1238,6 +1333,7 @@ void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
|
||||
{
|
||||
memset((char *) part, 0, sizeof(*part));
|
||||
part->easy = easy;
|
||||
part->lastreadstatus = 1; /* Successful read status. */
|
||||
mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
|
||||
}
|
||||
|
||||
@@ -1328,6 +1424,7 @@ CURLcode curl_mime_data(curl_mimepart *part,
|
||||
part->readfunc = mime_mem_read;
|
||||
part->seekfunc = mime_mem_seek;
|
||||
part->freefunc = mime_mem_free;
|
||||
part->flags |= MIME_FAST_READ;
|
||||
part->kind = MIMEKIND_DATA;
|
||||
}
|
||||
|
||||
@@ -1405,7 +1502,7 @@ CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
|
||||
CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
|
||||
{
|
||||
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
const mime_encoder *mep;
|
||||
const struct mime_encoder *mep;
|
||||
|
||||
if(!part)
|
||||
return result;
|
||||
@@ -1502,7 +1599,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part,
|
||||
}
|
||||
|
||||
subparts->parent = part;
|
||||
part->readfunc = mime_subparts_read;
|
||||
/* Subparts are processed internally: no read callback. */
|
||||
part->seekfunc = mime_subparts_seek;
|
||||
part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
|
||||
part->arg = subparts;
|
||||
@@ -1524,9 +1621,23 @@ CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
|
||||
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
|
||||
{
|
||||
curl_mimepart *part = (curl_mimepart *) instream;
|
||||
size_t ret;
|
||||
bool hasread;
|
||||
|
||||
(void) size; /* Always 1. */
|
||||
return readback_part(part, buffer, nitems);
|
||||
|
||||
do {
|
||||
hasread = FALSE;
|
||||
ret = readback_part(part, buffer, nitems, &hasread);
|
||||
/*
|
||||
* If this is not possible to get some data without calling more than
|
||||
* one read callback (probably because a content encoder is not able to
|
||||
* deliver a new bunch for the few data accumulated so far), force another
|
||||
* read until we get enough data or a special exit code.
|
||||
*/
|
||||
} while(ret == STOP_FILLING);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Rewind mime stream. */
|
||||
@@ -1667,6 +1778,23 @@ const char *Curl_mime_contenttype(const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool content_type_match(const char *contenttype, const char *target)
|
||||
{
|
||||
size_t len = strlen(target);
|
||||
|
||||
if(contenttype && strncasecompare(contenttype, target, len))
|
||||
switch(contenttype[len]) {
|
||||
case '\0':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case ' ':
|
||||
case ';':
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
const char *contenttype,
|
||||
const char *disposition,
|
||||
@@ -1718,7 +1846,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
boundary = mime->boundary;
|
||||
}
|
||||
else if(contenttype && !customct &&
|
||||
strcasecompare(contenttype, "text/plain"))
|
||||
content_type_match(contenttype, "text/plain"))
|
||||
if(strategy == MIMESTRATEGY_MAIL || !part->filename)
|
||||
contenttype = NULL;
|
||||
|
||||
@@ -1794,7 +1922,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
curl_mimepart *subpart;
|
||||
|
||||
disposition = NULL;
|
||||
if(strcasecompare(contenttype, "multipart/form-data"))
|
||||
if(content_type_match(contenttype, "multipart/form-data"))
|
||||
disposition = "form-data";
|
||||
for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
|
||||
ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
|
||||
@@ -1805,6 +1933,26 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Recursively reset paused status in the given part. */
|
||||
void Curl_mime_unpause(curl_mimepart *part)
|
||||
{
|
||||
if(part) {
|
||||
if(part->lastreadstatus == CURL_READFUNC_PAUSE)
|
||||
part->lastreadstatus = 1; /* Successful read status. */
|
||||
if(part->kind == MIMEKIND_MULTIPART) {
|
||||
curl_mime *mime = (curl_mime *) part->arg;
|
||||
|
||||
if(mime) {
|
||||
curl_mimepart *subpart;
|
||||
|
||||
for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart)
|
||||
Curl_mime_unpause(subpart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
|
||||
|
||||
/* Mime not compiled in: define stubs for externally-referenced functions. */
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
/* Part flags. */
|
||||
#define MIME_USERHEADERS_OWNER (1 << 0)
|
||||
#define MIME_BODY_ONLY (1 << 1)
|
||||
#define MIME_FAST_READ (1 << 2)
|
||||
|
||||
#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream"
|
||||
#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed"
|
||||
@@ -68,43 +69,43 @@ enum mimestrategy {
|
||||
};
|
||||
|
||||
/* Content transfer encoder. */
|
||||
typedef struct {
|
||||
struct mime_encoder {
|
||||
const char * name; /* Encoding name. */
|
||||
size_t (*encodefunc)(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part); /* Encoded read. */
|
||||
curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */
|
||||
} mime_encoder;
|
||||
};
|
||||
|
||||
/* Content transfer encoder state. */
|
||||
typedef struct {
|
||||
struct mime_encoder_state {
|
||||
size_t pos; /* Position on output line. */
|
||||
size_t bufbeg; /* Next data index in input buffer. */
|
||||
size_t bufend; /* First unused byte index in input buffer. */
|
||||
char buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */
|
||||
} mime_encoder_state;
|
||||
};
|
||||
|
||||
/* Mime readback state. */
|
||||
typedef struct {
|
||||
struct mime_state {
|
||||
enum mimestate state; /* Current state token. */
|
||||
void *ptr; /* State-dependent pointer. */
|
||||
size_t offset; /* State-dependent offset. */
|
||||
} mime_state;
|
||||
curl_off_t offset; /* State-dependent offset. */
|
||||
};
|
||||
|
||||
/* minimum buffer size for the boundary string */
|
||||
#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
|
||||
|
||||
/* A mime multipart. */
|
||||
struct curl_mime_s {
|
||||
struct curl_mime {
|
||||
struct Curl_easy *easy; /* The associated easy handle. */
|
||||
curl_mimepart *parent; /* Parent part. */
|
||||
curl_mimepart *firstpart; /* First part. */
|
||||
curl_mimepart *lastpart; /* Last part. */
|
||||
char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
|
||||
mime_state state; /* Current readback state. */
|
||||
struct mime_state state; /* Current readback state. */
|
||||
};
|
||||
|
||||
/* A mime part. */
|
||||
struct curl_mimepart_s {
|
||||
struct curl_mimepart {
|
||||
struct Curl_easy *easy; /* The associated easy handle. */
|
||||
curl_mime *parent; /* Parent mime structure. */
|
||||
curl_mimepart *nextpart; /* Forward linked list. */
|
||||
@@ -122,9 +123,10 @@ struct curl_mimepart_s {
|
||||
char *name; /* Data name. */
|
||||
curl_off_t datasize; /* Expected data size. */
|
||||
unsigned int flags; /* Flags. */
|
||||
mime_state state; /* Current readback state. */
|
||||
const mime_encoder *encoder; /* Content data encoder. */
|
||||
mime_encoder_state encstate; /* Data encoder state. */
|
||||
struct mime_state state; /* Current readback state. */
|
||||
const struct mime_encoder *encoder; /* Content data encoder. */
|
||||
struct mime_encoder_state encstate; /* Data encoder state. */
|
||||
size_t lastreadstatus; /* Last read callback returned status. */
|
||||
};
|
||||
|
||||
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
|
||||
@@ -133,20 +135,23 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
|
||||
!defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
|
||||
|
||||
/* Prototypes. */
|
||||
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
|
||||
void Curl_mime_cleanpart(curl_mimepart *part);
|
||||
CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src);
|
||||
CURLcode Curl_mime_set_subparts(curl_mimepart *part,
|
||||
curl_mime *subparts, int take_ownership);
|
||||
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy);
|
||||
void Curl_mime_cleanpart(struct curl_mimepart *part);
|
||||
CURLcode Curl_mime_duppart(struct curl_mimepart *dst,
|
||||
const curl_mimepart *src);
|
||||
CURLcode Curl_mime_set_subparts(struct curl_mimepart *part,
|
||||
struct curl_mime *subparts,
|
||||
int take_ownership);
|
||||
CURLcode Curl_mime_prepare_headers(struct curl_mimepart *part,
|
||||
const char *contenttype,
|
||||
const char *disposition,
|
||||
enum mimestrategy strategy);
|
||||
curl_off_t Curl_mime_size(curl_mimepart *part);
|
||||
curl_off_t Curl_mime_size(struct curl_mimepart *part);
|
||||
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
|
||||
void *instream);
|
||||
CURLcode Curl_mime_rewind(curl_mimepart *part);
|
||||
CURLcode Curl_mime_rewind(struct curl_mimepart *part);
|
||||
const char *Curl_mime_contenttype(const char *filename);
|
||||
void Curl_mime_unpause(struct curl_mimepart *part);
|
||||
|
||||
#else
|
||||
/* if disabled */
|
||||
@@ -158,6 +163,7 @@ const char *Curl_mime_contenttype(const char *filename);
|
||||
#define Curl_mime_size(x) (curl_off_t) -1
|
||||
#define Curl_mime_read NULL
|
||||
#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN)
|
||||
#define Curl_mime_unpause(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1999 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1999 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -36,6 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "dynbuf.h"
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
@@ -145,7 +146,7 @@ enum {
|
||||
FLAGS_FLOATG = 1<<19 /* %g or %G */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct va_stack {
|
||||
FormatType type;
|
||||
int flags;
|
||||
long width; /* width OR width parameter number */
|
||||
@@ -159,7 +160,7 @@ typedef struct {
|
||||
} num;
|
||||
double dnum;
|
||||
} data;
|
||||
} va_stack_t;
|
||||
};
|
||||
|
||||
struct nsprintf {
|
||||
char *buffer;
|
||||
@@ -168,11 +169,9 @@ struct nsprintf {
|
||||
};
|
||||
|
||||
struct asprintf {
|
||||
char *buffer; /* allocated buffer */
|
||||
size_t len; /* length of string */
|
||||
size_t alloc; /* length of alloc */
|
||||
int fail; /* (!= 0) if an alloc has failed and thus
|
||||
the output is not the complete data */
|
||||
struct dynbuf b;
|
||||
bool fail; /* if an alloc has failed and thus the output is not the complete
|
||||
data */
|
||||
};
|
||||
|
||||
static long dprintf_DollarString(char *input, char **end)
|
||||
@@ -224,8 +223,8 @@ static bool dprintf_IsQualifierNoDollar(const char *fmt)
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
va_list arglist)
|
||||
static int dprintf_Pass1(const char *format, struct va_stack *vto,
|
||||
char **endpos, va_list arglist)
|
||||
{
|
||||
char *fmt = (char *)format;
|
||||
int param_num = 0;
|
||||
@@ -571,13 +570,11 @@ static int dprintf_formatf(
|
||||
long param; /* current parameter to read */
|
||||
long param_num = 0; /* parameter counter */
|
||||
|
||||
va_stack_t vto[MAX_PARAMETERS];
|
||||
struct va_stack vto[MAX_PARAMETERS];
|
||||
char *endpos[MAX_PARAMETERS];
|
||||
char **end;
|
||||
|
||||
char work[BUFFSIZE];
|
||||
|
||||
va_stack_t *p;
|
||||
struct va_stack *p;
|
||||
|
||||
/* 'workend' points to the final buffer byte position, but with an extra
|
||||
byte as margin to avoid the (false?) warning Coverity gives us
|
||||
@@ -1031,35 +1028,10 @@ static int alloc_addbyter(int output, FILE *data)
|
||||
struct asprintf *infop = (struct asprintf *)data;
|
||||
unsigned char outc = (unsigned char)output;
|
||||
|
||||
if(!infop->buffer) {
|
||||
infop->buffer = malloc(32);
|
||||
if(!infop->buffer) {
|
||||
infop->fail = 1;
|
||||
return -1; /* fail */
|
||||
}
|
||||
infop->alloc = 32;
|
||||
infop->len = 0;
|
||||
if(Curl_dyn_addn(&infop->b, &outc, 1)) {
|
||||
infop->fail = 1;
|
||||
return -1; /* fail */
|
||||
}
|
||||
else if(infop->len + 1 >= infop->alloc) {
|
||||
char *newptr = NULL;
|
||||
size_t newsize = 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 = newsize;
|
||||
}
|
||||
|
||||
infop->buffer[ infop->len ] = outc;
|
||||
|
||||
infop->len++;
|
||||
|
||||
return outc; /* fputc() returns like this on success */
|
||||
}
|
||||
|
||||
@@ -1068,24 +1040,18 @@ char *curl_maprintf(const char *format, ...)
|
||||
va_list ap_save; /* argument pointer */
|
||||
int retcode;
|
||||
struct asprintf info;
|
||||
|
||||
info.buffer = NULL;
|
||||
info.len = 0;
|
||||
info.alloc = 0;
|
||||
Curl_dyn_init(&info.b, DYN_APRINTF);
|
||||
info.fail = 0;
|
||||
|
||||
va_start(ap_save, format);
|
||||
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
|
||||
va_end(ap_save);
|
||||
if((-1 == retcode) || info.fail) {
|
||||
if(info.alloc)
|
||||
free(info.buffer);
|
||||
Curl_dyn_free(&info.b);
|
||||
return NULL;
|
||||
}
|
||||
if(info.alloc) {
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
if(Curl_dyn_len(&info.b))
|
||||
return Curl_dyn_ptr(&info.b);
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
@@ -1093,23 +1059,16 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
|
||||
{
|
||||
int retcode;
|
||||
struct asprintf info;
|
||||
|
||||
info.buffer = NULL;
|
||||
info.len = 0;
|
||||
info.alloc = 0;
|
||||
Curl_dyn_init(&info.b, DYN_APRINTF);
|
||||
info.fail = 0;
|
||||
|
||||
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
|
||||
if((-1 == retcode) || info.fail) {
|
||||
if(info.alloc)
|
||||
free(info.buffer);
|
||||
Curl_dyn_free(&info.b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(info.alloc) {
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
if(Curl_dyn_len(&info.b))
|
||||
return Curl_dyn_ptr(&info.b);
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user