mirror of
https://github.com/Kitware/CMake.git
synced 2026-07-15 12:00:51 +00:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2022-04-27 (1669b17d)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -56,7 +56,7 @@ return 0;
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
/* */
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
|
||||
|
||||
68
Utilities/cmcurl/CMake/FindMSH3.cmake
Normal file
68
Utilities/cmcurl/CMake/FindMSH3.cmake
Normal file
@@ -0,0 +1,68 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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:
|
||||
FindMSH3
|
||||
----------
|
||||
|
||||
Find the msh3 library
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
``MSH3_FOUND``
|
||||
System has msh3
|
||||
``MSH3_INCLUDE_DIRS``
|
||||
The msh3 include directories.
|
||||
``MSH3_LIBRARIES``
|
||||
The libraries needed to use msh3
|
||||
#]=======================================================================]
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_MSH3 libmsh3)
|
||||
endif()
|
||||
|
||||
find_path(MSH3_INCLUDE_DIR msh3.h
|
||||
HINTS
|
||||
${PC_MSH3_INCLUDEDIR}
|
||||
${PC_MSH3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(MSH3_LIBRARY NAMES msh3
|
||||
HINTS
|
||||
${PC_MSH3_LIBDIR}
|
||||
${PC_MSH3_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MSH3
|
||||
REQUIRED_VARS
|
||||
MSH3_LIBRARY
|
||||
MSH3_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(MSH3_FOUND)
|
||||
set(MSH3_LIBRARIES ${MSH3_LIBRARY})
|
||||
set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(MSH3_INCLUDE_DIRS MSH3_LIBRARIES)
|
||||
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -253,8 +253,8 @@ endif()
|
||||
unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
|
||||
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
# only try this on non-macOS
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "iOS")
|
||||
# only try this on non-apple platforms
|
||||
|
||||
# if not cross-compilation...
|
||||
include(CheckCSourceRuns)
|
||||
|
||||
@@ -126,7 +126,7 @@ endif()
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,7 +234,7 @@ option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OF
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
|
||||
if(PICKY_COMPILER)
|
||||
foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wfloat-equal -Wsign-compare -Wundef -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wvla -Wdouble-promotion)
|
||||
foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wfloat-equal -Wsign-compare -Wundef -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wvla -Wdouble-promotion -Wenum-conversion -Warith-conversion)
|
||||
# surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
|
||||
# test result in.
|
||||
string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
|
||||
@@ -471,15 +471,6 @@ endif()
|
||||
check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
|
||||
check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
|
||||
|
||||
# Yellowtab Zeta needs different libraries than BeOS 5.
|
||||
if(BEOS)
|
||||
set(NOT_NEED_LIBNSL 1)
|
||||
check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
|
||||
check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
|
||||
endif()
|
||||
|
||||
check_library_exists_concat("network" recv HAVE_LIBNETWORK)
|
||||
|
||||
if(NOT NOT_NEED_LIBNSL)
|
||||
check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
|
||||
endif()
|
||||
@@ -710,6 +701,16 @@ if(USE_QUICHE)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
option(USE_MSH3 "Use msquic library for HTTP/3 support" OFF)
|
||||
if(USE_MSH3)
|
||||
if(USE_NGTCP2 OR USE_QUICHE)
|
||||
message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
|
||||
endif()
|
||||
set(USE_MSH3 ON)
|
||||
include_directories(${MSH3_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${MSH3_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_LDAP)
|
||||
if(WIN32)
|
||||
option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2021, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
Copyright (c) 1996 - 2022, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
contributors, see the THANKS file.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -73,8 +73,7 @@
|
||||
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
|
||||
defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
|
||||
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
|
||||
(defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
|
||||
defined(__VXWORKS__)
|
||||
(defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000))
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
@@ -82,14 +81,10 @@
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
|
||||
#if !defined(CURL_WIN32)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if defined __BEOS__ || defined __HAIKU__
|
||||
#include <support/SupportDefs.h>
|
||||
#endif
|
||||
|
||||
/* Compatibility for non-Clang compilers */
|
||||
#ifndef __has_declspec_attribute
|
||||
# define __has_declspec_attribute(x) 0
|
||||
@@ -529,10 +524,6 @@ typedef enum {
|
||||
CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
|
||||
CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
|
||||
CURLE_OUT_OF_MEMORY, /* 27 */
|
||||
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
|
||||
instead of a memory allocation error if CURL_DOES_CONVERSIONS
|
||||
is defined
|
||||
*/
|
||||
CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
|
||||
CURLE_OBSOLETE29, /* 29 - NOT USED */
|
||||
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
||||
@@ -569,7 +560,7 @@ typedef enum {
|
||||
CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint
|
||||
wasn't verified fine */
|
||||
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
|
||||
CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
|
||||
CURLE_OBSOLETE62, /* 62 - NOT IN USE since 7.82.0 */
|
||||
CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
|
||||
CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||
CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
|
||||
@@ -585,11 +576,7 @@ typedef enum {
|
||||
CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
|
||||
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||
CURLE_CONV_FAILED, /* 75 - conversion failed */
|
||||
CURLE_CONV_REQD, /* 76 - caller must register conversion
|
||||
callbacks using curl_easy_setopt options
|
||||
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||
CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||
CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */
|
||||
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
|
||||
or wrong format */
|
||||
CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
|
||||
@@ -683,13 +670,13 @@ typedef enum {
|
||||
/* The following were added earlier */
|
||||
|
||||
#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
|
||||
|
||||
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
||||
#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
|
||||
#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
|
||||
|
||||
#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
|
||||
#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
|
||||
#define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62
|
||||
#define CURLE_CONV_REQD CURLE_OBSOLETE76
|
||||
|
||||
/* This was the error code 50 in 7.7.3 and a few earlier versions, this
|
||||
is no longer used by libcurl but is instead #defined here only to not
|
||||
@@ -2062,7 +2049,7 @@ typedef enum {
|
||||
* (in seconds) */
|
||||
CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288),
|
||||
|
||||
/* SASL authorisation identity */
|
||||
/* SASL authorization identity */
|
||||
CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
|
||||
|
||||
/* allow RCPT TO command to fail for some recipients */
|
||||
@@ -2832,7 +2819,7 @@ typedef enum {
|
||||
CURLCLOSEPOLICY_LAST /* last, never use this */
|
||||
} curl_closepolicy;
|
||||
|
||||
#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */
|
||||
#define CURL_GLOBAL_SSL (1<<0) /* no purpose since 7.57.0 */
|
||||
#define CURL_GLOBAL_WIN32 (1<<1)
|
||||
#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
|
||||
#define CURL_GLOBAL_NOTHING 0
|
||||
@@ -3082,6 +3069,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
|
||||
#include "multi.h"
|
||||
#include "urlapi.h"
|
||||
#include "options.h"
|
||||
#include "header.h"
|
||||
|
||||
/* the typechecker doesn't work in C++ (yet) */
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,16 +26,16 @@
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2021 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2022 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.81.0"
|
||||
#define LIBCURL_VERSION "7.83.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 81
|
||||
#define LIBCURL_VERSION_MINOR 83
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
@@ -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 0x075100
|
||||
#define LIBCURL_VERSION_NUM 0x075300
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
64
Utilities/cmcurl/include/curl/header.h
Normal file
64
Utilities/cmcurl/include/curl/header.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef CURLINC_HEADER_H
|
||||
#define CURLINC_HEADER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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 curl_header {
|
||||
char *name; /* this might not use the same case */
|
||||
char *value;
|
||||
size_t amount; /* number of headers using this name */
|
||||
size_t index; /* ... of this instance, 0 or higher */
|
||||
unsigned int origin; /* see bits below */
|
||||
void *anchor; /* handle privately used by libcurl */
|
||||
};
|
||||
|
||||
/* 'origin' bits */
|
||||
#define CURLH_HEADER (1<<0) /* plain server header */
|
||||
#define CURLH_TRAILER (1<<1) /* trailers */
|
||||
#define CURLH_CONNECT (1<<2) /* CONNECT headers */
|
||||
#define CURLH_1XX (1<<3) /* 1xx headers */
|
||||
#define CURLH_PSEUDO (1<<4) /* pseudo headers */
|
||||
|
||||
typedef enum {
|
||||
CURLHE_OK,
|
||||
CURLHE_BADINDEX, /* header exists but not with this index */
|
||||
CURLHE_MISSING, /* no such header exists */
|
||||
CURLHE_NOHEADERS, /* no headers at all exist (yet) */
|
||||
CURLHE_NOREQUEST, /* no request with this number was used */
|
||||
CURLHE_OUT_OF_MEMORY, /* out of memory while processing */
|
||||
CURLHE_BAD_ARGUMENT, /* a function argument was not okay */
|
||||
CURLHE_NOT_BUILT_IN /* if API was disabled in the build */
|
||||
} CURLHcode;
|
||||
|
||||
CURL_EXTERN CURLHcode curl_easy_header(CURL *easy,
|
||||
const char *name,
|
||||
size_t index,
|
||||
unsigned int origin,
|
||||
int request,
|
||||
struct curl_header **hout);
|
||||
|
||||
CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy,
|
||||
unsigned int origin,
|
||||
int request,
|
||||
struct curl_header *prev);
|
||||
|
||||
#endif /* CURLINC_HEADER_H */
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -57,7 +57,7 @@ CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_by_name(const char *name);
|
||||
|
||||
CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_by_id (CURLoption id);
|
||||
curl_easy_option_by_id(CURLoption id);
|
||||
|
||||
CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_next(const struct curl_easyoption *prev);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -98,22 +98,6 @@
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# if defined(__386__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__POCC__)
|
||||
# if (__POCC__ < 280)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
@@ -137,7 +121,7 @@
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__LCC__)
|
||||
# if defined(__e2k__) /* MCST eLbrus C Compiler */
|
||||
# if defined(__MCST__) /* MCST eLbrus Compiler Collection */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -44,10 +44,10 @@ LIB_VTLS_CFILES = \
|
||||
vtls/bearssl.c \
|
||||
vtls/gskit.c \
|
||||
vtls/gtls.c \
|
||||
vtls/hostcheck.c \
|
||||
vtls/keylog.c \
|
||||
vtls/mbedtls.c \
|
||||
vtls/mbedtls_threadlock.c \
|
||||
vtls/mesalink.c \
|
||||
vtls/nss.c \
|
||||
vtls/openssl.c \
|
||||
vtls/rustls.c \
|
||||
@@ -55,30 +55,34 @@ LIB_VTLS_CFILES = \
|
||||
vtls/schannel_verify.c \
|
||||
vtls/sectransp.c \
|
||||
vtls/vtls.c \
|
||||
vtls/wolfssl.c
|
||||
vtls/wolfssl.c \
|
||||
vtls/x509asn1.c
|
||||
|
||||
LIB_VTLS_HFILES = \
|
||||
vtls/bearssl.h \
|
||||
vtls/gskit.h \
|
||||
vtls/gtls.h \
|
||||
vtls/hostcheck.h \
|
||||
vtls/keylog.h \
|
||||
vtls/mbedtls.h \
|
||||
vtls/mbedtls_threadlock.h \
|
||||
vtls/mesalink.h \
|
||||
vtls/nssg.h \
|
||||
vtls/openssl.h \
|
||||
vtls/rustls.h \
|
||||
vtls/schannel.h \
|
||||
vtls/sectransp.h \
|
||||
vtls/vtls.h \
|
||||
vtls/wolfssl.h
|
||||
vtls/wolfssl.h \
|
||||
vtls/x509asn1.h
|
||||
|
||||
LIB_VQUIC_CFILES = \
|
||||
vquic/msh3.c \
|
||||
vquic/ngtcp2.c \
|
||||
vquic/quiche.c \
|
||||
vquic/vquic.c
|
||||
|
||||
LIB_VQUIC_HFILES = \
|
||||
vquic/msh3.h \
|
||||
vquic/ngtcp2.h \
|
||||
vquic/quiche.h \
|
||||
vquic/vquic.h
|
||||
@@ -137,10 +141,11 @@ LIB_CFILES = \
|
||||
getenv.c \
|
||||
getinfo.c \
|
||||
gopher.c \
|
||||
h2h3.c \
|
||||
hash.c \
|
||||
headers.c \
|
||||
hmac.c \
|
||||
hostasyn.c \
|
||||
hostcheck.c \
|
||||
hostip.c \
|
||||
hostip4.c \
|
||||
hostip6.c \
|
||||
@@ -170,7 +175,6 @@ LIB_CFILES = \
|
||||
mqtt.c \
|
||||
multi.c \
|
||||
netrc.c \
|
||||
non-ascii.c \
|
||||
nonblock.c \
|
||||
openldap.c \
|
||||
parsedate.c \
|
||||
@@ -203,6 +207,7 @@ LIB_CFILES = \
|
||||
system_win32.c \
|
||||
telnet.c \
|
||||
tftp.c \
|
||||
timediff.c \
|
||||
timeval.c \
|
||||
transfer.c \
|
||||
url.c \
|
||||
@@ -210,8 +215,7 @@ LIB_CFILES = \
|
||||
version.c \
|
||||
version_win32.c \
|
||||
warnless.c \
|
||||
wildcard.c \
|
||||
x509asn1.c
|
||||
wildcard.c
|
||||
|
||||
LIB_HFILES = \
|
||||
altsvc.h \
|
||||
@@ -268,8 +272,9 @@ LIB_HFILES = \
|
||||
ftplistparser.h \
|
||||
getinfo.h \
|
||||
gopher.h \
|
||||
h2h3.h \
|
||||
hash.h \
|
||||
hostcheck.h \
|
||||
headers.h \
|
||||
hostip.h \
|
||||
hsts.h \
|
||||
http.h \
|
||||
@@ -291,7 +296,6 @@ LIB_HFILES = \
|
||||
multihandle.h \
|
||||
multiif.h \
|
||||
netrc.h \
|
||||
non-ascii.h \
|
||||
nonblock.h \
|
||||
parsedate.h \
|
||||
pingpong.h \
|
||||
@@ -324,6 +328,7 @@ LIB_HFILES = \
|
||||
system_win32.h \
|
||||
telnet.h \
|
||||
tftp.h \
|
||||
timediff.h \
|
||||
timeval.h \
|
||||
transfer.h \
|
||||
url.h \
|
||||
@@ -331,8 +336,7 @@ LIB_HFILES = \
|
||||
urldata.h \
|
||||
version_win32.h \
|
||||
warnless.h \
|
||||
wildcard.h \
|
||||
x509asn1.h
|
||||
wildcard.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -21,7 +21,7 @@
|
||||
***************************************************************************/
|
||||
/*
|
||||
* The Alt-Svc: header is defined in RFC 7838:
|
||||
* https://tools.ietf.org/html/rfc7838
|
||||
* https://datatracker.ietf.org/doc/html/rfc7838
|
||||
*/
|
||||
#include "curl_setup.h"
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#define H3VERSION "h3-29"
|
||||
#elif defined(USE_NGTCP2) && !defined(UNITTESTS)
|
||||
#define H3VERSION "h3-29"
|
||||
#elif defined(USE_MSH3) && !defined(UNITTESTS)
|
||||
#define H3VERSION "h3-29"
|
||||
#else
|
||||
#define H3VERSION "h3"
|
||||
#endif
|
||||
@@ -264,7 +266,7 @@ struct altsvcinfo *Curl_altsvc_init(void)
|
||||
|
||||
/* set default behavior */
|
||||
asi->flags = CURLALTSVC_H1
|
||||
#ifdef USE_NGHTTP2
|
||||
#ifdef USE_HTTP2
|
||||
| CURLALTSVC_H2
|
||||
#endif
|
||||
#ifdef ENABLE_QUIC
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
#include "timediff.h"
|
||||
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
defined(WIN32)
|
||||
@@ -290,7 +291,7 @@ int Curl_resolver_getsock(struct Curl_easy *data,
|
||||
|
||||
timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
|
||||
&timebuf);
|
||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||
milli = (long)curlx_tvtoms(timeout);
|
||||
if(milli == 0)
|
||||
milli += 10;
|
||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "urldata.h" /* for the Curl_easy definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -176,19 +175,15 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
}
|
||||
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode result;
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
int i;
|
||||
int inputparts;
|
||||
char *output;
|
||||
char *base64data;
|
||||
char *convbuf = NULL;
|
||||
|
||||
const char *indata = inputbuff;
|
||||
|
||||
*outptr = NULL;
|
||||
@@ -206,20 +201,6 @@ static CURLcode base64_encode(const char *table64,
|
||||
if(!output)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/*
|
||||
* The base64 data needs to be created using the network encoding
|
||||
* not the host encoding. And we can't change the actual input
|
||||
* so we copy it to a buffer, translate it, and use that instead.
|
||||
*/
|
||||
result = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||
if(result) {
|
||||
free(output);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(convbuf)
|
||||
indata = (char *)convbuf;
|
||||
|
||||
while(insize > 0) {
|
||||
for(i = inputparts = 0; i < 3; i++) {
|
||||
if(insize > 0) {
|
||||
@@ -270,10 +251,8 @@ static CURLcode base64_encode(const char *table64,
|
||||
/* Return the pointer to the new data (allocated memory) */
|
||||
*outptr = base64data;
|
||||
|
||||
free(convbuf);
|
||||
|
||||
/* Return the length of the new data */
|
||||
*outlen = strlen(base64data);
|
||||
*outlen = output - base64data;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -295,11 +274,10 @@ static CURLcode base64_encode(const char *table64,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
|
||||
return base64_encode(base64, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,11 +297,10 @@ CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
|
||||
return base64_encode(base64url, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
#endif /* no users so disabled */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -142,7 +142,7 @@ static int hyper_each_header(void *userdata,
|
||||
return HYPER_ITER_BREAK;
|
||||
}
|
||||
else {
|
||||
if(Curl_dyn_add(&data->state.headerb, "\r\n"))
|
||||
if(Curl_dyn_addn(&data->state.headerb, STRCONST("\r\n")))
|
||||
return HYPER_ITER_BREAK;
|
||||
}
|
||||
len = Curl_dyn_len(&data->state.headerb);
|
||||
@@ -293,10 +293,8 @@ static CURLcode status_line(struct Curl_easy *data,
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
result = Curl_client_write(data, writetype,
|
||||
Curl_dyn_ptr(&data->state.headerb), len);
|
||||
if(result) {
|
||||
data->state.hresult = CURLE_ABORTED_BY_CALLBACK;
|
||||
return HYPER_ITER_BREAK;
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
data->info.header_size += (long)len;
|
||||
data->req.headerbytecount += (long)len;
|
||||
@@ -416,7 +414,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
else if(h->endtask == task) {
|
||||
/* end of transfer */
|
||||
*done = TRUE;
|
||||
infof(data, "hyperstream is done!");
|
||||
infof(data, "hyperstream is done");
|
||||
if(!k->bodywrites) {
|
||||
/* hyper doesn't always call the body write callback */
|
||||
bool stilldone;
|
||||
@@ -806,7 +804,7 @@ static void http1xx_cb(void *arg, struct hyper_response *resp)
|
||||
}
|
||||
|
||||
if(data->state.hresult)
|
||||
infof(data, "ERROR in 1xx, bail out!");
|
||||
infof(data, "ERROR in 1xx, bail out");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -906,6 +904,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
hyper_clientconn_options_http2(options, 1);
|
||||
h2 = TRUE;
|
||||
}
|
||||
hyper_clientconn_options_set_preserve_header_case(options, 1);
|
||||
hyper_clientconn_options_set_preserve_header_order(options, 1);
|
||||
|
||||
hyper_clientconn_options_exec(options, h->exec);
|
||||
|
||||
@@ -1022,7 +1022,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
|
||||
p_accept = Curl_checkheaders(data,
|
||||
STRCONST("Accept"))?NULL:"Accept: */*\r\n";
|
||||
if(p_accept) {
|
||||
result = Curl_hyper_header(data, headers, p_accept);
|
||||
if(result)
|
||||
@@ -1036,8 +1037,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy &&
|
||||
!Curl_checkheaders(data, "Proxy-Connection") &&
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-Connection")) {
|
||||
!Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
|
||||
!Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) {
|
||||
result = Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive");
|
||||
if(result)
|
||||
goto error;
|
||||
@@ -1045,7 +1046,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
#endif
|
||||
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->state.referer && !Curl_checkheaders(data, "Referer")) {
|
||||
if(data->state.referer && !Curl_checkheaders(data, STRCONST("Referer"))) {
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer);
|
||||
if(!data->state.aptr.ref)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@@ -1055,7 +1056,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding") &&
|
||||
if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
data->state.aptr.accept_encoding =
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -132,13 +132,11 @@ void Curl_conncache_destroy(struct conncache *connc)
|
||||
}
|
||||
|
||||
/* creates a key to find a bundle for this connection */
|
||||
static void hashkey(struct connectdata *conn, char *buf,
|
||||
size_t len, /* something like 128 is fine */
|
||||
const char **hostp)
|
||||
static void hashkey(struct connectdata *conn, char *buf, size_t len)
|
||||
{
|
||||
const char *hostname;
|
||||
long port = conn->remote_port;
|
||||
|
||||
DEBUGASSERT(len >= HASHKEY_SIZE);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
hostname = conn->http_proxy.host.name;
|
||||
@@ -151,12 +149,12 @@ static void hashkey(struct connectdata *conn, char *buf,
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
if(hostp)
|
||||
/* report back which name we used */
|
||||
*hostp = hostname;
|
||||
|
||||
/* put the number first so that the hostname gets cut off if too long */
|
||||
msnprintf(buf, len, "%ld%s", port, hostname);
|
||||
/* put the numbers first so that the hostname gets cut off if too long */
|
||||
#ifdef ENABLE_IPV6
|
||||
msnprintf(buf, len, "%u/%ld/%s", conn->scope_id, port, hostname);
|
||||
#else
|
||||
msnprintf(buf, len, "%ld/%s", port, hostname);
|
||||
#endif
|
||||
Curl_strntolower(buf, buf, len);
|
||||
}
|
||||
|
||||
@@ -179,27 +177,24 @@ size_t Curl_conncache_size(struct Curl_easy *data)
|
||||
struct connectbundle *
|
||||
Curl_conncache_find_bundle(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct conncache *connc,
|
||||
const char **hostp)
|
||||
struct conncache *connc)
|
||||
{
|
||||
struct connectbundle *bundle = NULL;
|
||||
CONNCACHE_LOCK(data);
|
||||
if(connc) {
|
||||
char key[HASHKEY_SIZE];
|
||||
hashkey(conn, key, sizeof(key), hostp);
|
||||
hashkey(conn, key, sizeof(key));
|
||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static bool conncache_add_bundle(struct conncache *connc,
|
||||
char *key,
|
||||
struct connectbundle *bundle)
|
||||
static void *conncache_add_bundle(struct conncache *connc,
|
||||
char *key,
|
||||
struct connectbundle *bundle)
|
||||
{
|
||||
void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
|
||||
|
||||
return p?TRUE:FALSE;
|
||||
return Curl_hash_add(&connc->hash, key, strlen(key), bundle);
|
||||
}
|
||||
|
||||
static void conncache_remove_bundle(struct conncache *connc,
|
||||
@@ -235,10 +230,8 @@ CURLcode Curl_conncache_add_conn(struct Curl_easy *data)
|
||||
DEBUGASSERT(conn);
|
||||
|
||||
/* *find_bundle() locks the connection cache */
|
||||
bundle = Curl_conncache_find_bundle(data, conn, data->state.conn_cache,
|
||||
NULL);
|
||||
bundle = Curl_conncache_find_bundle(data, conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
int rc;
|
||||
char key[HASHKEY_SIZE];
|
||||
|
||||
result = bundle_create(&bundle);
|
||||
@@ -246,10 +239,9 @@ CURLcode Curl_conncache_add_conn(struct Curl_easy *data)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hashkey(conn, key, sizeof(key), NULL);
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, bundle);
|
||||
hashkey(conn, key, sizeof(key));
|
||||
|
||||
if(!rc) {
|
||||
if(!conncache_add_bundle(data->state.conn_cache, key, bundle)) {
|
||||
bundle_destroy(bundle);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto unlock;
|
||||
@@ -410,7 +402,7 @@ bool Curl_conncache_return_conn(struct Curl_easy *data,
|
||||
conn_candidate = Curl_conncache_extract_oldest(data);
|
||||
if(conn_candidate) {
|
||||
/* the winner gets the honour of being disconnected */
|
||||
(void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
|
||||
Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +527,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
{
|
||||
struct connectdata *conn;
|
||||
char buffer[READBUFFER_MIN + 1];
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
if(!connc->closure_handle)
|
||||
return;
|
||||
connc->closure_handle->state.buffer = buffer;
|
||||
@@ -542,27 +535,23 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
|
||||
conn = conncache_find_first_connection(connc);
|
||||
while(conn) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
||||
/* This will remove the connection from the cache */
|
||||
connclose(conn, "kill all");
|
||||
Curl_conncache_remove_conn(connc->closure_handle, conn, TRUE);
|
||||
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
|
||||
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);
|
||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
||||
|
||||
Curl_hostcache_clean(connc->closure_handle,
|
||||
connc->closure_handle->dns.hostcache);
|
||||
Curl_close(&connc->closure_handle);
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
Curl_hostcache_clean(connc->closure_handle,
|
||||
connc->closure_handle->dns.hostcache);
|
||||
Curl_close(&connc->closure_handle);
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -87,8 +87,7 @@ void Curl_conncache_destroy(struct conncache *connc);
|
||||
/* return the correct bundle, to a host or a proxy */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct conncache *connc,
|
||||
const char **hostp);
|
||||
struct conncache *connc);
|
||||
/* returns number of connections currently held in the connection cache */
|
||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -74,6 +74,7 @@
|
||||
#include "warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "share.h"
|
||||
#include "version_win32.h"
|
||||
#include "quic.h"
|
||||
#include "socks.h"
|
||||
@@ -137,6 +138,14 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPIDLE on fd %d", sockfd);
|
||||
}
|
||||
#elif defined(TCP_KEEPALIVE)
|
||||
/* Mac OS X style */
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPALIVE on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPINTVL
|
||||
optval = curlx_sltosi(data->set.tcp_keepintvl);
|
||||
@@ -146,15 +155,6 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
infof(data, "Failed to set TCP_KEEPINTVL on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPALIVE
|
||||
/* Mac OS X style */
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPALIVE on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -257,6 +257,9 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
||||
#ifdef IP_BIND_ADDRESS_NO_PORT
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifndef ENABLE_IPV6
|
||||
(void)scope;
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Select device to bind socket to
|
||||
@@ -314,8 +317,11 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(Curl_if2ip(af, scope, conn->scope_id, dev,
|
||||
myhost, sizeof(myhost))) {
|
||||
switch(Curl_if2ip(af,
|
||||
#ifdef ENABLE_IPV6
|
||||
scope, conn->scope_id,
|
||||
#endif
|
||||
dev, myhost, sizeof(myhost))) {
|
||||
case IF2IP_NOT_FOUND:
|
||||
if(is_interface) {
|
||||
/* Do not fall back to treating it as a host name */
|
||||
@@ -617,6 +623,7 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn,
|
||||
data->info.conn_scheme = conn->handler->scheme;
|
||||
data->info.conn_protocol = conn->handler->protocol;
|
||||
data->info.conn_primary_port = conn->port;
|
||||
data->info.conn_remote_port = conn->remote_port;
|
||||
data->info.conn_local_port = local_port;
|
||||
}
|
||||
|
||||
@@ -1481,7 +1488,11 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
find.id_tofind = data->state.lastconnect_id;
|
||||
find.found = NULL;
|
||||
|
||||
Curl_conncache_foreach(data, data->multi_easy?
|
||||
Curl_conncache_foreach(data,
|
||||
data->share && (data->share->specifier
|
||||
& (1<< CURL_LOCK_DATA_CONNECT))?
|
||||
&data->share->conn_cache:
|
||||
data->multi_easy?
|
||||
&data->multi_easy->conn_cache:
|
||||
&data->multi->conn_cache, &find, conn_is_conn);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -1188,12 +1188,15 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
fp = stdin;
|
||||
fromfile = FALSE;
|
||||
}
|
||||
else if(file && !*file) {
|
||||
/* points to a "" string */
|
||||
else if(!file || !*file) {
|
||||
/* points to an empty string or NULL */
|
||||
fp = NULL;
|
||||
}
|
||||
else
|
||||
fp = file?fopen(file, FOPEN_READTEXT):NULL;
|
||||
else {
|
||||
fp = fopen(file, FOPEN_READTEXT);
|
||||
if(!fp)
|
||||
infof(data, "WARNING: failed to open cookie file \"%s\"", file);
|
||||
}
|
||||
|
||||
c->newsession = newsession; /* new session? */
|
||||
|
||||
@@ -1227,7 +1230,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
*/
|
||||
remove_expired(c);
|
||||
|
||||
if(fromfile)
|
||||
if(fromfile && fp)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,13 +22,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -952,6 +952,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */
|
||||
#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1
|
||||
|
||||
/* to enable msh3 */
|
||||
#cmakedefine USE_MSH3 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DOES_CONVERSIONS
|
||||
|
||||
#undef _U
|
||||
#define _U (1<<0) /* upper case */
|
||||
#undef _L
|
||||
@@ -130,4 +128,3 @@ int Curl_iscntrl(int c)
|
||||
return (ascii[c] & (_C));
|
||||
}
|
||||
|
||||
#endif /* !CURL_DOES_CONVERSIONS */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,32 +24,6 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
/*
|
||||
* Uppercase macro versions of ANSI/ISO is*() functions/macros which
|
||||
* avoid negative number inputs with argument byte codes > 127.
|
||||
*
|
||||
* For non-ASCII platforms the C library character classification routines
|
||||
* are used despite being locale-dependent, because this is better than
|
||||
* not to work at all.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
|
||||
#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
|
||||
#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
|
||||
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
|
||||
#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
|
||||
#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
|
||||
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
|
||||
#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
|
||||
#define ISLOWER(x) (islower((int) ((unsigned char)x)))
|
||||
#define ISCNTRL(x) (iscntrl((int) ((unsigned char)x)))
|
||||
#define ISASCII(x) (isascii((int) ((unsigned char)x)))
|
||||
|
||||
#else
|
||||
|
||||
int Curl_isspace(int c);
|
||||
int Curl_isdigit(int c);
|
||||
int Curl_isalnum(int c);
|
||||
@@ -73,8 +47,6 @@ int Curl_iscntrl(int c);
|
||||
#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x)))
|
||||
#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80))
|
||||
|
||||
#endif
|
||||
|
||||
#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
|
||||
(((unsigned char)x) == '\t'))
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2021, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2015 - 2022, Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,7 +22,12 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_OPENSSL) && !defined(USE_WOLFSSL)
|
||||
#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
|
||||
(defined(USE_GNUTLS) || \
|
||||
defined(USE_NSS) || \
|
||||
defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO))
|
||||
|
||||
#include "curl_des.h"
|
||||
|
||||
@@ -60,4 +65,4 @@ void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM && !USE_OPENSSL */
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2020, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2015 - 2022, Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,11 +24,16 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_OPENSSL)
|
||||
#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
|
||||
(defined(USE_GNUTLS) || \
|
||||
defined(USE_NSS) || \
|
||||
defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO))
|
||||
|
||||
/* Applies odd parity to the given byte array */
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
|
||||
|
||||
#endif /* USE_NTLM && !USE_OPENSSL */
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_DES_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -60,7 +60,7 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
||||
#else
|
||||
infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
infof(data, "WARNING: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
"compiled in");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -104,7 +104,7 @@ int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
#ifdef _UNICODE
|
||||
if(filename_w) {
|
||||
result = _wopen(filename_w, oflag, pmode);
|
||||
free(filename_w);
|
||||
curlx_unicodefree(filename_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
@@ -124,8 +124,8 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
result = _wfopen(filename_w, mode_w);
|
||||
else
|
||||
errno = EINVAL;
|
||||
free(filename_w);
|
||||
free(mode_w);
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
return result;
|
||||
#else
|
||||
return (fopen)(filename, mode);
|
||||
@@ -143,7 +143,7 @@ int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
#else
|
||||
result = _wstati64(path_w, buffer);
|
||||
#endif
|
||||
free(path_w);
|
||||
curlx_unicodefree(path_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
@@ -164,7 +164,7 @@ int curlx_win32_access(const char *path, int mode)
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
result = _waccess(path_w, mode);
|
||||
free(path_w);
|
||||
curlx_unicodefree(path_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -108,7 +108,6 @@
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_md5.h"
|
||||
@@ -402,11 +401,9 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
/*
|
||||
* Set up lanmanager hashed password
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
CURLcode result;
|
||||
unsigned char pw[14];
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
@@ -416,14 +413,6 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
Curl_strntoupper((char *)pw, password, len);
|
||||
memset(&pw[len], 0, 14 - len);
|
||||
|
||||
/*
|
||||
* The LanManager hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
|
||||
@@ -455,7 +444,6 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
size_t srclen)
|
||||
{
|
||||
@@ -466,7 +454,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
const char *src, size_t srclen)
|
||||
@@ -478,19 +466,17 @@ static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
#endif /* !USE_WINDOWS_SSPI */
|
||||
|
||||
/*
|
||||
* Set up nt hashed passwords
|
||||
* @unittest: 1600
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */)
|
||||
{
|
||||
size_t len = strlen(password);
|
||||
unsigned char *pw;
|
||||
CURLcode result;
|
||||
if(len > SIZE_T_MAX/2) /* avoid integer overflow */
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
|
||||
@@ -499,22 +485,16 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
|
||||
ascii_to_unicode_le(pw, password, len);
|
||||
|
||||
/*
|
||||
* The NT hashed password needs to be created using the password in the
|
||||
* network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, len * 2);
|
||||
if(!result) {
|
||||
/* Create NT hashed password. */
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
/* Create NT hashed password. */
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
|
||||
free(pw);
|
||||
|
||||
return result;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
|
||||
struct ms_filetime {
|
||||
@@ -730,8 +710,6 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTRESPONSES */
|
||||
#endif /* !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_CURL_NTLM_CORE */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -42,22 +42,6 @@
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/* Define USE_NTRESPONSES in order to make the type-3 message include
|
||||
* the NT response message. */
|
||||
#define USE_NTRESPONSES
|
||||
|
||||
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
|
||||
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 */
|
||||
#if defined(USE_NTRESPONSES)
|
||||
#define USE_NTLM2SESSION
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM_V2 in order to allow the type-3 message to include the
|
||||
LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1 */
|
||||
#if defined(USE_NTRESPONSES)
|
||||
#define USE_NTLM_V2
|
||||
#endif
|
||||
|
||||
/* Helpers to generate function byte arguments in little endian order */
|
||||
#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff))
|
||||
#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \
|
||||
@@ -67,16 +51,13 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
@@ -98,9 +79,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_server,
|
||||
unsigned char *lmresp);
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTRESPONSES */
|
||||
#endif /* !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_CURL_NTLM_CORE */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
|
||||
char *working_path;
|
||||
size_t working_path_len;
|
||||
CURLcode result =
|
||||
Curl_urldecode(data, data->state.up.path, 0, &working_path,
|
||||
Curl_urldecode(data->state.up.path, 0, &working_path,
|
||||
&working_path_len, REJECT_ZERO);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,6 @@
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -283,8 +282,7 @@ static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/* Encode the outgoing SASL message. */
|
||||
static CURLcode build_message(struct SASL *sasl, struct Curl_easy *data,
|
||||
struct bufref *msg)
|
||||
static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@@ -297,7 +295,7 @@ static CURLcode build_message(struct SASL *sasl, struct Curl_easy *data,
|
||||
char *base64;
|
||||
size_t base64len;
|
||||
|
||||
result = Curl_base64_encode(data, (const char *) Curl_bufref_ptr(msg),
|
||||
result = Curl_base64_encode((const char *) Curl_bufref_ptr(msg),
|
||||
Curl_bufref_len(msg), &base64, &base64len);
|
||||
if(!result)
|
||||
Curl_bufref_set(msg, base64, base64len, curl_free);
|
||||
@@ -312,10 +310,10 @@ static CURLcode build_message(struct SASL *sasl, struct Curl_easy *data,
|
||||
*
|
||||
* Check if we have enough auth data and capabilities to authenticate.
|
||||
*/
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
||||
{
|
||||
/* Have credentials been provided? */
|
||||
if(conn->bits.user_passwd)
|
||||
if(data->state.aptr.user)
|
||||
return TRUE;
|
||||
|
||||
/* EXTERNAL can authenticate without a user name and/or password */
|
||||
@@ -367,7 +365,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_external_message(conn->user, &resp);
|
||||
}
|
||||
else if(conn->bits.user_passwd) {
|
||||
else if(data->state.aptr.user) {
|
||||
#if defined(USE_KERBEROS5)
|
||||
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(conn->user)) {
|
||||
@@ -494,7 +492,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||
if(!result && mech) {
|
||||
sasl->curmech = mech;
|
||||
if(Curl_bufref_ptr(&resp))
|
||||
result = build_message(sasl, data, &resp);
|
||||
result = build_message(sasl, &resp);
|
||||
|
||||
if(sasl->params->maxirlen &&
|
||||
strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen)
|
||||
@@ -672,7 +670,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
#endif
|
||||
|
||||
case SASL_OAUTH2:
|
||||
/* Create the authorisation message */
|
||||
/* Create the authorization message */
|
||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
||||
result = Curl_auth_create_oauth_bearer_message(conn->user,
|
||||
hostname,
|
||||
@@ -729,7 +727,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
newstate = SASL_CANCEL;
|
||||
break;
|
||||
case CURLE_OK:
|
||||
result = build_message(sasl, data, &resp);
|
||||
result = build_message(sasl, &resp);
|
||||
if(!result)
|
||||
result = sasl->params->contauth(data, sasl->curmech, &resp);
|
||||
break;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -150,7 +150,7 @@ void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
|
||||
const struct SASLproto *params);
|
||||
|
||||
/* Check if we have enough auth data and capabilities to authenticate */
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data);
|
||||
|
||||
/* Calculate the required login details for SASL authentication */
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -101,14 +101,6 @@
|
||||
# include "config-os400.h"
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include "config-tpf.h"
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include "config-vxworks.h"
|
||||
#endif
|
||||
|
||||
#ifdef __PLAN9__
|
||||
# include "config-plan9.h"
|
||||
#endif
|
||||
@@ -278,22 +270,6 @@
|
||||
# include <extra/strdup.h>
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include <strings.h> /* for bzero, strcasecmp, and strncasecmp */
|
||||
# include <string.h> /* for strcpy and strlen */
|
||||
# include <stdlib.h> /* for rand and srand */
|
||||
# include <sys/socket.h> /* for select and ioctl*/
|
||||
# include <netdb.h> /* for in_addr_t definition */
|
||||
# include <tpf/sysapi.h> /* for tpf_process_signals */
|
||||
/* change which select is used for libcurl */
|
||||
# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include <sockLib.h> /* for generic BSD socket functions */
|
||||
# include <ioLib.h> /* for basic I/O interface functions */
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
@@ -634,14 +610,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
int netware_init(void);
|
||||
#ifndef __NOVELL_LIBC__
|
||||
#include <sys/bsdskt.h>
|
||||
#include <sys/timeval.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
@@ -656,7 +624,7 @@ int netware_init(void);
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
||||
defined(USE_MBEDTLS) || \
|
||||
defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \
|
||||
defined(USE_SECTRANSP) || defined(USE_GSKIT) || \
|
||||
defined(USE_BEARSSL) || defined(USE_RUSTLS)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
@@ -819,6 +787,11 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
|
||||
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
/* A convenience macro to provide both the string literal and the length of
|
||||
the string literal in one go, useful for functions that take "string,len"
|
||||
as their argument */
|
||||
#define STRCONST(x) x,sizeof(x)-1
|
||||
|
||||
/* Some versions of the Android SDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
||||
struct passwd;
|
||||
@@ -836,7 +809,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
#define USE_HTTP2
|
||||
#endif
|
||||
|
||||
#if defined(USE_NGTCP2) || defined(USE_QUICHE)
|
||||
#if defined(USE_NGTCP2) || defined(USE_QUICHE) || defined(USE_MSH3)
|
||||
#define ENABLE_QUIC
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
|
||||
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -32,7 +32,7 @@ extern const struct HMAC_params Curl_HMAC_SHA256[1];
|
||||
/* SHA256_DIGEST_LENGTH is an enum value in wolfSSL. Need to import it from
|
||||
* sha.h*/
|
||||
#include <wolfssl/options.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <wolfssl/openssl/sha.h>
|
||||
#else
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -96,13 +96,13 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
|
||||
};
|
||||
|
||||
static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
static char *unescape_word(const char *inputbuff)
|
||||
{
|
||||
char *newp = NULL;
|
||||
char *dictp;
|
||||
size_t len;
|
||||
|
||||
CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len,
|
||||
CURLcode result = Curl_urldecode(inputbuff, 0, &newp, &len,
|
||||
REJECT_NADA);
|
||||
if(!newp || result)
|
||||
return NULL;
|
||||
@@ -190,10 +190,6 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
if(conn->bits.user_passwd) {
|
||||
/* AUTH is missing */
|
||||
}
|
||||
|
||||
if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
@@ -226,7 +222,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
strategy = (char *)".";
|
||||
}
|
||||
|
||||
eword = unescape_word(data, word);
|
||||
eword = unescape_word(word);
|
||||
if(!eword)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -274,7 +270,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
database = (char *)"!";
|
||||
}
|
||||
|
||||
eword = unescape_word(data, word);
|
||||
eword = unescape_word(word);
|
||||
if(!eword)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -252,7 +252,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers);
|
||||
#ifdef USE_NGHTTP2
|
||||
#ifdef USE_HTTP2
|
||||
ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
#endif
|
||||
#ifndef CURLDEBUG
|
||||
@@ -530,7 +530,7 @@ static DOHcode store_cname(const unsigned char *doh,
|
||||
|
||||
if(length) {
|
||||
if(Curl_dyn_len(c)) {
|
||||
if(Curl_dyn_add(c, "."))
|
||||
if(Curl_dyn_addn(c, STRCONST(".")))
|
||||
return DOH_OUT_OF_MEM;
|
||||
}
|
||||
if((index + length) > dohlen)
|
||||
@@ -911,7 +911,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
|
||||
!dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
|
||||
failf(data, "Could not DoH-resolve: %s", data->state.async.hostname);
|
||||
return data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return CONN_IS_PROXIED(data->conn)?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else if(!dohp->pending) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
/*
|
||||
* "Remove Dot Segments"
|
||||
* https://tools.ietf.org/html/rfc3986#section-5.2.4
|
||||
* https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -68,7 +68,6 @@
|
||||
#include "slist.h"
|
||||
#include "mime.h"
|
||||
#include "amigaos.h"
|
||||
#include "non-ascii.h"
|
||||
#include "warnless.h"
|
||||
#include "multiif.h"
|
||||
#include "sigpipe.h"
|
||||
@@ -168,12 +167,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
if(netware_init()) {
|
||||
DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if(Curl_resolver_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
goto fail;
|
||||
@@ -933,8 +926,6 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
}
|
||||
#endif /* USE_ARES */
|
||||
|
||||
Curl_convert_setup(outcurl);
|
||||
|
||||
Curl_initinfo(outcurl);
|
||||
|
||||
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
||||
@@ -1111,7 +1102,7 @@ static CURLcode easy_connection(struct Curl_easy *data,
|
||||
|
||||
/* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
|
||||
if(!data->set.connect_only) {
|
||||
failf(data, "CONNECT_ONLY is required!");
|
||||
failf(data, "CONNECT_ONLY is required");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "escape.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -39,7 +38,7 @@
|
||||
|
||||
/* Portable character check (remember EBCDIC). Do not use isalnum() because
|
||||
its behavior is altered by the current locale.
|
||||
See https://tools.ietf.org/html/rfc3986#section-2.3
|
||||
See https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
|
||||
*/
|
||||
bool Curl_isunreserved(unsigned char in)
|
||||
{
|
||||
@@ -80,8 +79,8 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
int inlength)
|
||||
{
|
||||
size_t length;
|
||||
CURLcode result;
|
||||
struct dynbuf d;
|
||||
(void)data;
|
||||
|
||||
if(inlength < 0)
|
||||
return NULL;
|
||||
@@ -102,16 +101,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
}
|
||||
else {
|
||||
/* encode it */
|
||||
char encoded[4];
|
||||
result = Curl_convert_to_network(data, (char *)&in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
Curl_dyn_free(&d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msnprintf(encoded, sizeof(encoded), "%%%02X", in);
|
||||
if(Curl_dyn_add(&d, encoded))
|
||||
if(Curl_dyn_addf(&d, "%%%02X", in))
|
||||
return NULL;
|
||||
}
|
||||
string++;
|
||||
@@ -126,8 +116,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
* Returns a pointer to a malloced string in *ostring with length given in
|
||||
* *olen. If length == 0, the length is assumed to be strlen(string).
|
||||
*
|
||||
* 'data' can be set to NULL but then this function can't convert network
|
||||
* data to host for non-ascii.
|
||||
* 'data' can be set to NULL
|
||||
*
|
||||
* ctrl options:
|
||||
* - REJECT_NADA: accept everything
|
||||
@@ -139,8 +128,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
* invokes that used TRUE/FALSE (0 and 1).
|
||||
*/
|
||||
|
||||
CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
const char *string, size_t length,
|
||||
CURLcode Curl_urldecode(const char *string, size_t length,
|
||||
char **ostring, size_t *olen,
|
||||
enum urlreject ctrl)
|
||||
{
|
||||
@@ -148,7 +136,6 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
char *ns;
|
||||
size_t strindex = 0;
|
||||
unsigned long hex;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(string);
|
||||
DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
|
||||
@@ -174,15 +161,6 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
|
||||
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
||||
|
||||
if(data) {
|
||||
result = Curl_convert_from_network(data, (char *)&in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
string += 2;
|
||||
alloc -= 2;
|
||||
}
|
||||
@@ -218,10 +196,11 @@ char *curl_easy_unescape(struct Curl_easy *data, const char *string,
|
||||
int length, int *olen)
|
||||
{
|
||||
char *str = NULL;
|
||||
(void)data;
|
||||
if(length >= 0) {
|
||||
size_t inputlen = length;
|
||||
size_t outputlen;
|
||||
CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
|
||||
CURLcode res = Curl_urldecode(string, inputlen, &str, &outputlen,
|
||||
REJECT_NADA);
|
||||
if(res)
|
||||
return NULL;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -32,8 +32,7 @@ enum urlreject {
|
||||
REJECT_ZERO
|
||||
};
|
||||
|
||||
CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
const char *string, size_t length,
|
||||
CURLcode Curl_urldecode(const char *string, size_t length,
|
||||
char **ostring, size_t *olen,
|
||||
enum urlreject ctrl);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,7 +147,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
#endif
|
||||
size_t real_path_len;
|
||||
|
||||
CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &real_path,
|
||||
CURLcode result = Curl_urldecode(data->state.up.path, 0, &real_path,
|
||||
&real_path_len, REJECT_ZERO);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
#include "urldata.h" /* for struct Curl_easy */
|
||||
#include "mime.h"
|
||||
#include "non-ascii.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "strcase.h"
|
||||
#include "sendf.h"
|
||||
@@ -77,10 +76,15 @@ AddHttpPost(char *name, size_t namelength,
|
||||
struct curl_httppost **last_post)
|
||||
{
|
||||
struct curl_httppost *post;
|
||||
if(!namelength && name)
|
||||
namelength = strlen(name);
|
||||
if((bufferlength > LONG_MAX) || (namelength > LONG_MAX))
|
||||
/* avoid overflow in typecasts below */
|
||||
return NULL;
|
||||
post = calloc(1, sizeof(struct curl_httppost));
|
||||
if(post) {
|
||||
post->name = name;
|
||||
post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
|
||||
post->namelength = (long)namelength;
|
||||
post->contents = value;
|
||||
post->contentlen = contentslength;
|
||||
post->buffer = buffer;
|
||||
@@ -269,14 +273,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
* Set the Name property.
|
||||
*/
|
||||
case CURLFORM_PTRNAME:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
|
||||
* the data in all cases so that we'll have safe memory for the eventual
|
||||
* conversion.
|
||||
*/
|
||||
#else
|
||||
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
#endif
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case CURLFORM_COPYNAME:
|
||||
if(current_form->name)
|
||||
@@ -901,11 +899,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
else
|
||||
uclen = (size_t)clen;
|
||||
result = curl_mime_data(part, post->contents, uclen);
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Convert textual contents now. */
|
||||
if(!result && data && part->datasize)
|
||||
result = Curl_convert_to_network(data, part->data, part->datasize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
#include "speedcheck.h"
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
#include "non-ascii.h"
|
||||
#include "socks.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -592,7 +591,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
|
||||
* This response code can come at any point so having it treated
|
||||
* generically is a good idea.
|
||||
*/
|
||||
infof(data, "We got a 421 - timeout!");
|
||||
infof(data, "We got a 421 - timeout");
|
||||
state(data, FTP_STOP);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
@@ -1030,8 +1029,11 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
if(*addr != '\0') {
|
||||
/* attempt to get the address of the given interface name */
|
||||
switch(Curl_if2ip(conn->ip_addr->ai_family,
|
||||
#ifdef ENABLE_IPV6
|
||||
Curl_ipv6_scope(conn->ip_addr->ai_addr),
|
||||
conn->scope_id, addr, hbuf, sizeof(hbuf))) {
|
||||
conn->scope_id,
|
||||
#endif
|
||||
addr, hbuf, sizeof(hbuf))) {
|
||||
case IF2IP_NOT_FOUND:
|
||||
/* not an interface, use the given string as host name instead */
|
||||
host = addr;
|
||||
@@ -1163,7 +1165,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
|
||||
/* maybe all ports were in use already*/
|
||||
if(port > port_max) {
|
||||
failf(data, "bind() failed, we ran out of ports!");
|
||||
failf(data, "bind() failed, we ran out of ports");
|
||||
Curl_closesocket(data, conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1460,7 +1462,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
|
||||
/* url-decode before evaluation: e.g. paths starting/ending with %2f */
|
||||
const char *slashPos = NULL;
|
||||
char *rawPath = NULL;
|
||||
result = Curl_urldecode(data, ftp->path, 0, &rawPath, NULL, REJECT_CTRL);
|
||||
result = Curl_urldecode(ftp->path, 0, &rawPath, NULL, REJECT_CTRL);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2700,7 +2702,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
|
||||
|
||||
if(Curl_sec_login(data, conn))
|
||||
infof(data, "Logging in with password in cleartext!");
|
||||
infof(data, "Logging in with password in cleartext");
|
||||
else
|
||||
infof(data, "Authentication successful");
|
||||
}
|
||||
@@ -3247,7 +3249,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
|
||||
if(!result)
|
||||
/* get the url-decoded "raw" path */
|
||||
result = Curl_urldecode(data, ftp->path, 0, &rawPath, &pathLen,
|
||||
result = Curl_urldecode(ftp->path, 0, &rawPath, &pathLen,
|
||||
REJECT_CTRL);
|
||||
if(result) {
|
||||
/* We can limp along anyway (and should try to since we may already be in
|
||||
@@ -3379,7 +3381,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
(ftp->transfer == PPTRANSFER_BODY)) {
|
||||
failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
|
||||
" out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
|
||||
data->req.bytecount, data->state.infilesize);
|
||||
data->req.writebytecount, data->state.infilesize);
|
||||
result = CURLE_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
@@ -3402,7 +3404,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
else if(!ftpc->dont_check &&
|
||||
!data->req.bytecount &&
|
||||
(data->req.size>0)) {
|
||||
failf(data, "No data was received!");
|
||||
failf(data, "No data was received");
|
||||
result = CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
@@ -4132,9 +4134,11 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||
ftpc->cwdfail = FALSE;
|
||||
|
||||
/* url-decode ftp path before further evaluation */
|
||||
result = Curl_urldecode(data, ftp->path, 0, &rawPath, &pathLen, REJECT_CTRL);
|
||||
if(result)
|
||||
result = Curl_urldecode(ftp->path, 0, &rawPath, &pathLen, REJECT_CTRL);
|
||||
if(result) {
|
||||
failf(data, "path contains control characters");
|
||||
return result;
|
||||
}
|
||||
|
||||
switch(data->set.ftp_filemethod) {
|
||||
case FTPFILE_NOCWD: /* fastest, but less standard-compliant */
|
||||
@@ -4232,7 +4236,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||
|
||||
if(data->set.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) {
|
||||
/* We need a file name when uploading. Return error! */
|
||||
failf(data, "Uploading to a URL without a file name!");
|
||||
failf(data, "Uploading to a URL without a file name");
|
||||
free(rawPath);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -165,7 +165,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
|
||||
newp += 2;
|
||||
|
||||
/* ... and finally unescape */
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, REJECT_ZERO);
|
||||
result = Curl_urldecode(newp, 0, &sel, &len, REJECT_ZERO);
|
||||
free(gopherpath);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
310
Utilities/cmcurl/lib/h2h3.c
Normal file
310
Utilities/cmcurl/lib/h2h3.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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 "urldata.h"
|
||||
#include "h2h3.h"
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_pseudo_headers() creates the array with pseudo headers to be
|
||||
* used in a HTTP/2 or HTTP/3 request.
|
||||
*/
|
||||
|
||||
#if defined(USE_NGHTTP2) || defined(ENABLE_QUIC)
|
||||
|
||||
/* Index where :authority header field will appear in request header
|
||||
field list. */
|
||||
#define AUTHORITY_DST_IDX 3
|
||||
|
||||
/* USHRT_MAX is 65535 == 0xffff */
|
||||
#define HEADER_OVERFLOW(x) \
|
||||
(x.namelen > 0xffff || x.valuelen > 0xffff - x.namelen)
|
||||
|
||||
/*
|
||||
* Check header memory for the token "trailers".
|
||||
* Parse the tokens as separated by comma and surrounded by whitespace.
|
||||
* Returns TRUE if found or FALSE if not.
|
||||
*/
|
||||
static bool contains_trailers(const char *p, size_t len)
|
||||
{
|
||||
const char *end = p + len;
|
||||
for(;;) {
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || (size_t)(end - p) < sizeof("trailers") - 1)
|
||||
return FALSE;
|
||||
if(strncasecompare("trailers", p, sizeof("trailers") - 1)) {
|
||||
p += sizeof("trailers") - 1;
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || *p == ',')
|
||||
return TRUE;
|
||||
}
|
||||
/* skip to next token */
|
||||
for(; p != end && *p != ','; ++p)
|
||||
;
|
||||
if(p == end)
|
||||
return FALSE;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
/* Send header to server */
|
||||
HEADERINST_FORWARD,
|
||||
/* Don't send header to server */
|
||||
HEADERINST_IGNORE,
|
||||
/* Discard header, and replace it with "te: trailers" */
|
||||
HEADERINST_TE_TRAILERS
|
||||
} header_instruction;
|
||||
|
||||
/* Decides how to treat given header field. */
|
||||
static header_instruction inspect_header(const char *name, size_t namelen,
|
||||
const char *value, size_t valuelen) {
|
||||
switch(namelen) {
|
||||
case 2:
|
||||
if(!strncasecompare("te", name, namelen))
|
||||
return HEADERINST_FORWARD;
|
||||
|
||||
return contains_trailers(value, valuelen) ?
|
||||
HEADERINST_TE_TRAILERS : HEADERINST_IGNORE;
|
||||
case 7:
|
||||
return strncasecompare("upgrade", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 10:
|
||||
return (strncasecompare("connection", name, namelen) ||
|
||||
strncasecompare("keep-alive", name, namelen)) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 16:
|
||||
return strncasecompare("proxy-connection", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 17:
|
||||
return strncasecompare("transfer-encoding", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
default:
|
||||
return HEADERINST_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode Curl_pseudo_headers(struct Curl_easy *data,
|
||||
const char *mem, /* the request */
|
||||
const size_t len /* size of request */,
|
||||
struct h2h3req **hp)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
size_t nheader = 0;
|
||||
size_t i;
|
||||
size_t authority_idx;
|
||||
char *hdbuf = (char *)mem;
|
||||
char *end, *line_end;
|
||||
struct h2h3pseudo *nva = NULL;
|
||||
struct h2h3req *hreq = NULL;
|
||||
char *vptr;
|
||||
|
||||
/* Calculate number of headers contained in [mem, mem + len). Assumes a
|
||||
correctly generated HTTP header field block. */
|
||||
for(i = 1; i < len; ++i) {
|
||||
if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') {
|
||||
++nheader;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if(nheader < 2) {
|
||||
goto fail;
|
||||
}
|
||||
/* We counted additional 2 \r\n in the first and last line. We need 3
|
||||
new headers: :method, :path and :scheme. Therefore we need one
|
||||
more space. */
|
||||
nheader += 1;
|
||||
hreq = malloc(sizeof(struct h2h3req) +
|
||||
sizeof(struct h2h3pseudo) * (nheader - 1));
|
||||
if(!hreq) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nva = &hreq->header[0];
|
||||
|
||||
/* Extract :method, :path from request line
|
||||
We do line endings with CRLF so checking for CR is enough */
|
||||
line_end = memchr(hdbuf, '\r', len);
|
||||
if(!line_end) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Method does not contain spaces */
|
||||
end = memchr(hdbuf, ' ', line_end - hdbuf);
|
||||
if(!end || end == hdbuf)
|
||||
goto fail;
|
||||
nva[0].name = H2H3_PSEUDO_METHOD;
|
||||
nva[0].namelen = sizeof(H2H3_PSEUDO_METHOD) - 1;
|
||||
nva[0].value = hdbuf;
|
||||
nva[0].valuelen = (size_t)(end - hdbuf);
|
||||
|
||||
hdbuf = end + 1;
|
||||
|
||||
/* Path may contain spaces so scan backwards */
|
||||
end = NULL;
|
||||
for(i = (size_t)(line_end - hdbuf); i; --i) {
|
||||
if(hdbuf[i - 1] == ' ') {
|
||||
end = &hdbuf[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!end || end == hdbuf)
|
||||
goto fail;
|
||||
nva[1].name = H2H3_PSEUDO_PATH;
|
||||
nva[1].namelen = sizeof(H2H3_PSEUDO_PATH) - 1;
|
||||
nva[1].value = hdbuf;
|
||||
nva[1].valuelen = (end - hdbuf);
|
||||
|
||||
nva[2].name = H2H3_PSEUDO_SCHEME;
|
||||
nva[2].namelen = sizeof(H2H3_PSEUDO_SCHEME) - 1;
|
||||
vptr = Curl_checkheaders(data, STRCONST(H2H3_PSEUDO_SCHEME));
|
||||
if(vptr) {
|
||||
vptr += sizeof(H2H3_PSEUDO_SCHEME);
|
||||
while(*vptr && ISSPACE(*vptr))
|
||||
vptr++;
|
||||
nva[2].value = vptr;
|
||||
infof(data, "set pseudo header %s to %s", H2H3_PSEUDO_SCHEME, vptr);
|
||||
}
|
||||
else {
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
nva[2].value = "https";
|
||||
else
|
||||
nva[2].value = "http";
|
||||
}
|
||||
nva[2].valuelen = strlen((char *)nva[2].value);
|
||||
|
||||
authority_idx = 0;
|
||||
i = 3;
|
||||
while(i < nheader) {
|
||||
size_t hlen;
|
||||
|
||||
hdbuf = line_end + 2;
|
||||
|
||||
/* check for next CR, but only within the piece of data left in the given
|
||||
buffer */
|
||||
line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem));
|
||||
if(!line_end || (line_end == hdbuf))
|
||||
goto fail;
|
||||
|
||||
/* header continuation lines are not supported */
|
||||
if(*hdbuf == ' ' || *hdbuf == '\t')
|
||||
goto fail;
|
||||
|
||||
for(end = hdbuf; end < line_end && *end != ':'; ++end)
|
||||
;
|
||||
if(end == hdbuf || end == line_end)
|
||||
goto fail;
|
||||
hlen = end - hdbuf;
|
||||
|
||||
if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = H2H3_PSEUDO_AUTHORITY;
|
||||
nva[i].namelen = sizeof(H2H3_PSEUDO_AUTHORITY) - 1;
|
||||
}
|
||||
else {
|
||||
nva[i].namelen = (size_t)(end - hdbuf);
|
||||
/* Lower case the header name for HTTP/3 */
|
||||
Curl_strntolower((char *)hdbuf, hdbuf, nva[i].namelen);
|
||||
nva[i].name = hdbuf;
|
||||
}
|
||||
hdbuf = end + 1;
|
||||
while(*hdbuf == ' ' || *hdbuf == '\t')
|
||||
++hdbuf;
|
||||
end = line_end;
|
||||
|
||||
switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
|
||||
end - hdbuf)) {
|
||||
case HEADERINST_IGNORE:
|
||||
/* skip header fields prohibited by HTTP/2 specification. */
|
||||
--nheader;
|
||||
continue;
|
||||
case HEADERINST_TE_TRAILERS:
|
||||
nva[i].value = "trailers";
|
||||
nva[i].valuelen = sizeof("trailers") - 1;
|
||||
break;
|
||||
default:
|
||||
nva[i].value = hdbuf;
|
||||
nva[i].valuelen = (end - hdbuf);
|
||||
}
|
||||
|
||||
nva[i].value = hdbuf;
|
||||
nva[i].valuelen = (end - hdbuf);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* :authority must come before non-pseudo header fields */
|
||||
if(authority_idx && authority_idx != AUTHORITY_DST_IDX) {
|
||||
struct h2h3pseudo authority = nva[authority_idx];
|
||||
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
|
||||
nva[i] = nva[i - 1];
|
||||
}
|
||||
nva[i] = authority;
|
||||
}
|
||||
|
||||
/* Warn stream may be rejected if cumulative length of headers is too
|
||||
large. */
|
||||
#define MAX_ACC 60000 /* <64KB to account for some overhead */
|
||||
{
|
||||
size_t acc = 0;
|
||||
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
infof(data, "h2h3 [%.*s: %.*s]",
|
||||
(int)nva[i].namelen, nva[i].name,
|
||||
(int)nva[i].valuelen, nva[i].value);
|
||||
}
|
||||
|
||||
if(acc > MAX_ACC) {
|
||||
infof(data, "http_request: Warning: The cumulative length of all "
|
||||
"headers exceeds %d bytes and that could cause the "
|
||||
"stream to be rejected.", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
hreq->entries = nheader;
|
||||
*hp = hreq;
|
||||
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
free(hreq);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
void Curl_pseudo_free(struct h2h3req *hp)
|
||||
{
|
||||
free(hp);
|
||||
}
|
||||
|
||||
#endif /* USE_NGHTTP2 or HTTP/3 enabled */
|
||||
59
Utilities/cmcurl/lib/h2h3.h
Normal file
59
Utilities/cmcurl/lib/h2h3.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef HEADER_CURL_H2H3_H
|
||||
#define HEADER_CURL_H2H3_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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"
|
||||
|
||||
#define H2H3_PSEUDO_METHOD ":method"
|
||||
#define H2H3_PSEUDO_SCHEME ":scheme"
|
||||
#define H2H3_PSEUDO_AUTHORITY ":authority"
|
||||
#define H2H3_PSEUDO_PATH ":path"
|
||||
#define H2H3_PSEUDO_STATUS ":status"
|
||||
|
||||
struct h2h3pseudo {
|
||||
const char *name;
|
||||
size_t namelen;
|
||||
const char *value;
|
||||
size_t valuelen;
|
||||
};
|
||||
|
||||
struct h2h3req {
|
||||
size_t entries;
|
||||
struct h2h3pseudo header[1]; /* the array is allocated to contain entries */
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_pseudo_headers() creates the array with pseudo headers to be
|
||||
* used in a HTTP/2 or HTTP/3 request. Returns an allocated struct.
|
||||
* Free it with Curl_pseudo_free().
|
||||
*/
|
||||
CURLcode Curl_pseudo_headers(struct Curl_easy *data,
|
||||
const char *request,
|
||||
const size_t len,
|
||||
struct h2h3req **hp);
|
||||
|
||||
/*
|
||||
* Curl_pseudo_free() frees a h2h3req struct.
|
||||
*/
|
||||
void Curl_pseudo_free(struct h2h3req *hp);
|
||||
|
||||
#endif /* HEADER_CURL_H2H3_H */
|
||||
324
Utilities/cmcurl/lib/headers.c
Normal file
324
Utilities/cmcurl/lib/headers.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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 "urldata.h"
|
||||
#include "strdup.h"
|
||||
#include "strcase.h"
|
||||
#include "headers.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API)
|
||||
|
||||
/* Generate the curl_header struct for the user. This function MUST assign all
|
||||
struct fields in the output struct. */
|
||||
static void copy_header_external(struct Curl_easy *data,
|
||||
struct Curl_header_store *hs,
|
||||
size_t index,
|
||||
size_t amount,
|
||||
struct Curl_llist_element *e,
|
||||
struct curl_header **hout)
|
||||
{
|
||||
struct curl_header *h = *hout = &data->state.headerout;
|
||||
h->name = hs->name;
|
||||
h->value = hs->value;
|
||||
h->amount = amount;
|
||||
h->index = index;
|
||||
/* this will randomly OR a reserved bit for the sole purpose of making it
|
||||
impossible for applications to do == comparisons, as that would otherwise
|
||||
be very tempting and then lead to the reserved bits not being reserved
|
||||
anymore. */
|
||||
h->origin = hs->type | (1<<27);
|
||||
h->anchor = e;
|
||||
}
|
||||
|
||||
/* public API */
|
||||
CURLHcode curl_easy_header(CURL *easy,
|
||||
const char *name,
|
||||
size_t nameindex,
|
||||
unsigned int type,
|
||||
int request,
|
||||
struct curl_header **hout)
|
||||
{
|
||||
struct Curl_llist_element *e;
|
||||
struct Curl_llist_element *e_pick = NULL;
|
||||
struct Curl_easy *data = easy;
|
||||
size_t match = 0;
|
||||
size_t amount = 0;
|
||||
struct Curl_header_store *hs = NULL;
|
||||
struct Curl_header_store *pick = NULL;
|
||||
if(!name || !hout || !data ||
|
||||
(type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX)) ||
|
||||
!type || (request < -1))
|
||||
return CURLHE_BAD_ARGUMENT;
|
||||
if(!Curl_llist_count(&data->state.httphdrs))
|
||||
return CURLHE_NOHEADERS; /* no headers available */
|
||||
if(request > data->state.requests)
|
||||
return CURLHE_NOREQUEST;
|
||||
if(request == -1)
|
||||
request = data->state.requests;
|
||||
|
||||
/* we need a first round to count amount of this header */
|
||||
for(e = data->state.httphdrs.head; e; e = e->next) {
|
||||
hs = e->ptr;
|
||||
if(strcasecompare(hs->name, name) &&
|
||||
(hs->type & type) &&
|
||||
(hs->request == request)) {
|
||||
amount++;
|
||||
pick = hs;
|
||||
e_pick = e;
|
||||
}
|
||||
}
|
||||
if(!amount)
|
||||
return CURLHE_MISSING;
|
||||
else if(nameindex >= amount)
|
||||
return CURLHE_BADINDEX;
|
||||
|
||||
if(nameindex == amount - 1)
|
||||
/* if the last or only occurrence is what's asked for, then we know it */
|
||||
hs = pick;
|
||||
else {
|
||||
for(e = data->state.httphdrs.head; e; e = e->next) {
|
||||
hs = e->ptr;
|
||||
if(strcasecompare(hs->name, name) &&
|
||||
(hs->type & type) &&
|
||||
(hs->request == request) &&
|
||||
(match++ == nameindex)) {
|
||||
e_pick = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!e) /* this shouldn't happen */
|
||||
return CURLHE_MISSING;
|
||||
}
|
||||
/* this is the name we want */
|
||||
copy_header_external(data, hs, nameindex, amount, e_pick, hout);
|
||||
return CURLHE_OK;
|
||||
}
|
||||
|
||||
/* public API */
|
||||
struct curl_header *curl_easy_nextheader(CURL *easy,
|
||||
unsigned int type,
|
||||
int request,
|
||||
struct curl_header *prev)
|
||||
{
|
||||
struct Curl_easy *data = easy;
|
||||
struct Curl_llist_element *pick;
|
||||
struct Curl_llist_element *e;
|
||||
struct Curl_header_store *hs;
|
||||
struct curl_header *hout;
|
||||
size_t amount = 0;
|
||||
size_t index = 0;
|
||||
|
||||
if(request > data->state.requests)
|
||||
return NULL;
|
||||
if(request == -1)
|
||||
request = data->state.requests;
|
||||
|
||||
if(prev) {
|
||||
pick = prev->anchor;
|
||||
if(!pick)
|
||||
/* something is wrong */
|
||||
return NULL;
|
||||
pick = pick->next;
|
||||
}
|
||||
else
|
||||
pick = data->state.httphdrs.head;
|
||||
|
||||
if(pick) {
|
||||
/* make sure it is the next header of the desired type */
|
||||
do {
|
||||
hs = pick->ptr;
|
||||
if((hs->type & type) && (hs->request == request))
|
||||
break;
|
||||
pick = pick->next;
|
||||
} while(pick);
|
||||
}
|
||||
|
||||
if(!pick)
|
||||
/* no more headers available */
|
||||
return NULL;
|
||||
|
||||
hs = pick->ptr;
|
||||
|
||||
/* count number of occurrences of this name within the mask and figure out
|
||||
the index for the currently selected entry */
|
||||
for(e = data->state.httphdrs.head; e; e = e->next) {
|
||||
struct Curl_header_store *check = e->ptr;
|
||||
if(strcasecompare(hs->name, check->name) &&
|
||||
(check->request == request) &&
|
||||
(check->type & type))
|
||||
amount++;
|
||||
if(e == pick)
|
||||
index = amount - 1;
|
||||
}
|
||||
|
||||
copy_header_external(data, hs, index, amount, pick, &hout);
|
||||
return hout;
|
||||
}
|
||||
|
||||
static CURLcode namevalue(char *header, size_t hlen, unsigned int type,
|
||||
char **name, char **value)
|
||||
{
|
||||
char *end = header + hlen - 1; /* point to the last byte */
|
||||
DEBUGASSERT(hlen);
|
||||
*name = header;
|
||||
|
||||
if(type == CURLH_PSEUDO) {
|
||||
if(*header != ':')
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
header++;
|
||||
}
|
||||
|
||||
/* Find the end of the header name */
|
||||
while(*header && (*header != ':'))
|
||||
++header;
|
||||
|
||||
if(*header)
|
||||
/* Skip over colon, null it */
|
||||
*header++ = 0;
|
||||
else
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* skip all leading space letters */
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
*value = header;
|
||||
|
||||
/* skip all trailing space letters */
|
||||
while((end > header) && ISSPACE(*end))
|
||||
*end-- = 0; /* nul terminate */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_headers_push() gets passed a full HTTP header to store. It gets called
|
||||
* immediately before the header callback. The header is CRLF terminated.
|
||||
*/
|
||||
CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
|
||||
unsigned char type)
|
||||
{
|
||||
char *value = NULL;
|
||||
char *name = NULL;
|
||||
char *end;
|
||||
size_t hlen; /* length of the incoming header */
|
||||
struct Curl_header_store *hs;
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if((header[0] == '\r') || (header[0] == '\n'))
|
||||
/* ignore the body separator */
|
||||
return CURLE_OK;
|
||||
|
||||
end = strchr(header, '\r');
|
||||
if(!end) {
|
||||
end = strchr(header, '\n');
|
||||
if(!end)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
hlen = end - header + 1;
|
||||
|
||||
hs = calloc(1, sizeof(*hs) + hlen);
|
||||
if(!hs)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(hs->buffer, header, hlen);
|
||||
hs->buffer[hlen] = 0; /* nul terminate */
|
||||
|
||||
result = namevalue(hs->buffer, hlen, type, &name, &value);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
hs->name = name;
|
||||
hs->value = value;
|
||||
hs->type = type;
|
||||
hs->request = data->state.requests;
|
||||
|
||||
/* insert this node into the list of headers */
|
||||
Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail,
|
||||
hs, &hs->node);
|
||||
|
||||
return CURLE_OK;
|
||||
fail:
|
||||
free(hs);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_headers_init(). Init the headers subsystem.
|
||||
*/
|
||||
static void headers_init(struct Curl_easy *data)
|
||||
{
|
||||
Curl_llist_init(&data->state.httphdrs, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_headers_cleanup(). Free all stored headers and associated memory.
|
||||
*/
|
||||
CURLcode Curl_headers_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_llist_element *e;
|
||||
struct Curl_llist_element *n;
|
||||
|
||||
for(e = data->state.httphdrs.head; e; e = n) {
|
||||
struct Curl_header_store *hs = e->ptr;
|
||||
n = e->next;
|
||||
free(hs);
|
||||
}
|
||||
headers_init(data);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#else /* HTTP-disabled builds below */
|
||||
|
||||
CURLHcode curl_easy_header(CURL *easy,
|
||||
const char *name,
|
||||
size_t index,
|
||||
unsigned int origin,
|
||||
int request,
|
||||
struct curl_header **hout)
|
||||
{
|
||||
(void)easy;
|
||||
(void)name;
|
||||
(void)index;
|
||||
(void)origin;
|
||||
(void)request;
|
||||
(void)hout;
|
||||
return CURLHE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
struct curl_header *curl_easy_nextheader(CURL *easy,
|
||||
unsigned int type,
|
||||
int request,
|
||||
struct curl_header *prev)
|
||||
{
|
||||
(void)easy;
|
||||
(void)type;
|
||||
(void)request;
|
||||
(void)prev;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
53
Utilities/cmcurl/lib/headers.h
Normal file
53
Utilities/cmcurl/lib/headers.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef HEADER_CURL_HEADER_H
|
||||
#define HEADER_CURL_HEADER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API)
|
||||
|
||||
struct Curl_header_store {
|
||||
struct Curl_llist_element node;
|
||||
char *name; /* points into 'buffer' */
|
||||
char *value; /* points into 'buffer */
|
||||
int request; /* 0 is the first request, then 1.. 2.. */
|
||||
unsigned char type; /* CURLH_* defines */
|
||||
char buffer[1]; /* this is the raw header blob */
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_headers_push() gets passed a full header to store.
|
||||
*/
|
||||
CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
|
||||
unsigned char type);
|
||||
|
||||
/*
|
||||
* Curl_headers_cleanup(). Free all stored headers and associated memory.
|
||||
*/
|
||||
CURLcode Curl_headers_cleanup(struct Curl_easy *data);
|
||||
|
||||
#else
|
||||
#define Curl_headers_push(x,y,z) CURLE_OK
|
||||
#define Curl_headers_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HEADER_H */
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -39,8 +39,8 @@
|
||||
* Generic HMAC algorithm.
|
||||
*
|
||||
* This module computes HMAC digests based on any hash function. Parameters
|
||||
* and computing procedures are set-up dynamically at HMAC computation
|
||||
* context initialisation.
|
||||
* and computing procedures are set-up dynamically at HMAC computation context
|
||||
* initialization.
|
||||
*/
|
||||
|
||||
static const unsigned char hmac_ipad = 0x36;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -945,7 +945,7 @@ clean_up:
|
||||
less than 1! */
|
||||
alarm(1);
|
||||
rc = CURLRESOLV_TIMEDOUT;
|
||||
failf(data, "Previous alarm fired off!");
|
||||
failf(data, "Previous alarm fired off");
|
||||
}
|
||||
else
|
||||
alarm((unsigned int)alarm_set);
|
||||
@@ -1131,7 +1131,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
ai = Curl_str2addr(address, port);
|
||||
if(!ai) {
|
||||
infof(data, "Resolve address '%s' found illegal!", address);
|
||||
infof(data, "Resolve address '%s' found illegal", address);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -1150,7 +1150,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
error = false;
|
||||
err:
|
||||
if(error) {
|
||||
failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!",
|
||||
failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'",
|
||||
hostp->data);
|
||||
Curl_freeaddrinfo(head);
|
||||
return CURLE_SETOPT_OPTION_SYNTAX;
|
||||
@@ -1167,8 +1167,8 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
|
||||
|
||||
if(dns) {
|
||||
infof(data, "RESOLVE %s:%d is - old addresses discarded!",
|
||||
hostname, port);
|
||||
infof(data, "RESOLVE %s:%d is - old addresses discarded",
|
||||
hostname, port);
|
||||
/* delete old entry, there are two reasons for this
|
||||
1. old entry may have different addresses.
|
||||
2. even if entry with correct addresses is already in the cache,
|
||||
@@ -1220,6 +1220,7 @@ CURLcode Curl_resolv_check(struct Curl_easy *data,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
|
||||
(void)data;
|
||||
(void)dns;
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -21,7 +21,7 @@
|
||||
***************************************************************************/
|
||||
/*
|
||||
* The Strict-Transport-Security header is defined in RFC 6797:
|
||||
* https://tools.ietf.org/html/rfc6797
|
||||
* https://datatracker.ietf.org/doc/html/rfc6797
|
||||
*/
|
||||
#include "curl_setup.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -77,7 +77,6 @@
|
||||
#include "content_encoding.h"
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "http2.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
@@ -216,10 +215,10 @@ static CURLcode http_setup_conn(struct Curl_easy *data,
|
||||
*/
|
||||
char *Curl_checkProxyheaders(struct Curl_easy *data,
|
||||
const struct connectdata *conn,
|
||||
const char *thisheader)
|
||||
const char *thisheader,
|
||||
const size_t thislen)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
|
||||
for(head = (conn->bits.proxy && data->set.sep_headers) ?
|
||||
data->set.proxyheaders : data->set.headers;
|
||||
@@ -233,7 +232,7 @@ char *Curl_checkProxyheaders(struct Curl_easy *data,
|
||||
}
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_checkProxyheaders(x,y,z) NULL
|
||||
#define Curl_checkProxyheaders(x,y,z,a) NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -327,7 +326,7 @@ static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
|
||||
if(!out)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
|
||||
result = Curl_base64_encode(out, strlen(out), &authorization, &size);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
@@ -588,7 +587,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
||||
if(data->state.authproblem)
|
||||
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
|
||||
|
||||
if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
|
||||
if((data->state.aptr.user || data->set.str[STRING_BEARER]) &&
|
||||
((data->req.httpcode == 401) ||
|
||||
(conn->bits.authneg && data->req.httpcode < 300))) {
|
||||
pickhost = pickoneauth(&data->state.authhost, authmask);
|
||||
@@ -667,6 +666,7 @@ output_auth_headers(struct Curl_easy *data,
|
||||
{
|
||||
const char *auth = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
(void)conn;
|
||||
|
||||
#ifdef CURL_DISABLE_CRYPTO_AUTH
|
||||
(void)request;
|
||||
@@ -725,10 +725,10 @@ output_auth_headers(struct Curl_easy *data,
|
||||
if(
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(proxy && conn->bits.proxy_user_passwd &&
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-authorization")) ||
|
||||
!Curl_checkProxyheaders(data, conn, STRCONST("Proxy-authorization"))) ||
|
||||
#endif
|
||||
(!proxy && conn->bits.user_passwd &&
|
||||
!Curl_checkheaders(data, "Authorization"))) {
|
||||
(!proxy && data->state.aptr.user &&
|
||||
!Curl_checkheaders(data, STRCONST("Authorization")))) {
|
||||
auth = "Basic";
|
||||
result = http_output_basic(data, proxy);
|
||||
if(result)
|
||||
@@ -742,7 +742,7 @@ output_auth_headers(struct Curl_easy *data,
|
||||
if(authstatus->picked == CURLAUTH_BEARER) {
|
||||
/* Bearer */
|
||||
if((!proxy && data->set.str[STRING_BEARER] &&
|
||||
!Curl_checkheaders(data, "Authorization"))) {
|
||||
!Curl_checkheaders(data, STRCONST("Authorization")))) {
|
||||
auth = "Bearer";
|
||||
result = http_output_bearer(data);
|
||||
if(result)
|
||||
@@ -775,6 +775,21 @@ output_auth_headers(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_allow_auth_to_host() tells if authentication, cookies or other
|
||||
* "sensitive data" can (still) be sent to this host.
|
||||
*/
|
||||
bool Curl_allow_auth_to_host(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
return (!data->state.this_is_a_follow ||
|
||||
data->set.allow_auth_to_other_hosts ||
|
||||
(data->state.first_host &&
|
||||
strcasecompare(data->state.first_host, conn->host.name) &&
|
||||
(data->state.first_remote_port == conn->remote_port) &&
|
||||
(data->state.first_remote_protocol == conn->handler->protocol)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Curl_http_output_auth() setups the authentication headers for the
|
||||
* host/proxy and the correct authentication
|
||||
@@ -811,7 +826,7 @@ Curl_http_output_auth(struct Curl_easy *data,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
||||
#endif
|
||||
conn->bits.user_passwd || data->set.str[STRING_BEARER])
|
||||
data->state.aptr.user || data->set.str[STRING_BEARER])
|
||||
/* continue please */;
|
||||
else {
|
||||
authhost->done = TRUE;
|
||||
@@ -847,17 +862,14 @@ Curl_http_output_auth(struct Curl_easy *data,
|
||||
with it */
|
||||
authproxy->done = TRUE;
|
||||
|
||||
/* To prevent the user+password to get sent to other than the original
|
||||
host due to a location-follow, we do some weirdo checks here */
|
||||
if(!data->state.this_is_a_follow ||
|
||||
/* To prevent the user+password to get sent to other than the original host
|
||||
due to a location-follow */
|
||||
if(Curl_allow_auth_to_host(data)
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
conn->bits.netrc ||
|
||||
|| conn->bits.netrc
|
||||
#endif
|
||||
!data->state.first_host ||
|
||||
data->set.allow_auth_to_other_hosts ||
|
||||
strcasecompare(data->state.first_host, conn->host.name)) {
|
||||
)
|
||||
result = output_auth_headers(data, conn, authhost, request, path, FALSE);
|
||||
}
|
||||
else
|
||||
authhost->done = TRUE;
|
||||
|
||||
@@ -1143,7 +1155,7 @@ static bool http_should_fail(struct Curl_easy *data)
|
||||
** Either we're not authenticating, or we're supposed to
|
||||
** be authenticating something else. This is an error.
|
||||
*/
|
||||
if((httpcode == 401) && !data->conn->bits.user_passwd)
|
||||
if((httpcode == 401) && !data->state.aptr.user)
|
||||
return TRUE;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
|
||||
@@ -1251,14 +1263,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
|
||||
DEBUGASSERT(size > (size_t)included_body_bytes);
|
||||
|
||||
result = Curl_convert_to_network(data, ptr, headersize);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(result) {
|
||||
/* conversion failed, free memory and return to the caller */
|
||||
Curl_dyn_free(in);
|
||||
return result;
|
||||
}
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|| conn->http_proxy.proxytype == CURLPROXY_HTTPS
|
||||
@@ -1425,18 +1429,22 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
bool
|
||||
Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *header, /* header keyword _with_ colon */
|
||||
const char *content) /* content string to find */
|
||||
const size_t hlen, /* len of the keyword in bytes */
|
||||
const char *content, /* content string to find */
|
||||
const size_t clen) /* len of the content in bytes */
|
||||
{
|
||||
/* RFC2616, section 4.2 says: "Each header field consists of a name followed
|
||||
* by a colon (":") and the field value. Field names are case-insensitive.
|
||||
* The field value MAY be preceded by any amount of LWS, though a single SP
|
||||
* is preferred." */
|
||||
|
||||
size_t hlen = strlen(header);
|
||||
size_t clen;
|
||||
size_t len;
|
||||
const char *start;
|
||||
const char *end;
|
||||
DEBUGASSERT(hlen);
|
||||
DEBUGASSERT(clen);
|
||||
DEBUGASSERT(header);
|
||||
DEBUGASSERT(content);
|
||||
|
||||
if(!strncasecompare(headerline, header, hlen))
|
||||
return FALSE; /* doesn't start with header */
|
||||
@@ -1460,7 +1468,6 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
}
|
||||
|
||||
len = end-start; /* length of the content part of the input line */
|
||||
clen = strlen(content); /* length of the word to find */
|
||||
|
||||
/* find the content string in the rest of the line */
|
||||
for(; len >= clen; len--, start++) {
|
||||
@@ -1546,7 +1553,7 @@ static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(data->conn->unix_domain_socket)
|
||||
/* the buffer is large enough to hold this! */
|
||||
result = Curl_dyn_add(&req, "PROXY UNKNOWN\r\n");
|
||||
result = Curl_dyn_addn(&req, STRCONST("PROXY UNKNOWN\r\n"));
|
||||
else {
|
||||
#endif
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
@@ -1713,13 +1720,13 @@ static CURLcode expect100(struct Curl_easy *data,
|
||||
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
|
||||
Expect: 100-continue to the headers which actually speeds up post
|
||||
operations (as there is one packet coming back from the web server) */
|
||||
const char *ptr = Curl_checkheaders(data, "Expect");
|
||||
const char *ptr = Curl_checkheaders(data, STRCONST("Expect"));
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
|
||||
}
|
||||
else {
|
||||
result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
|
||||
result = Curl_dyn_addn(req, STRCONST("Expect: 100-continue\r\n"));
|
||||
if(!result)
|
||||
data->state.expect100header = TRUE;
|
||||
}
|
||||
@@ -1772,7 +1779,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
return result;
|
||||
}
|
||||
else
|
||||
infof(handle, "Malformatted trailing header ! Skipping trailer.");
|
||||
infof(handle, "Malformatted trailing header, skipping trailer");
|
||||
trailers = trailers->next;
|
||||
}
|
||||
result = Curl_dyn_add(b, endofline_network);
|
||||
@@ -1867,7 +1874,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
|
||||
ptr = optr;
|
||||
}
|
||||
}
|
||||
if(ptr) {
|
||||
if(ptr && (ptr != headers->data)) {
|
||||
/* we require a colon for this to be a true header */
|
||||
|
||||
ptr++; /* pass the colon */
|
||||
@@ -1910,10 +1917,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
|
||||
checkprefix("Cookie:", compare)) &&
|
||||
/* be careful of sending this potentially sensitive header to
|
||||
other hosts */
|
||||
(data->state.this_is_a_follow &&
|
||||
data->state.first_host &&
|
||||
!data->set.allow_auth_to_other_hosts &&
|
||||
!strcasecompare(data->state.first_host, conn->host.name)))
|
||||
!Curl_allow_auth_to_host(data))
|
||||
;
|
||||
else {
|
||||
#ifdef USE_HYPER
|
||||
@@ -1949,6 +1953,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
CURLcode result;
|
||||
char datestr[80];
|
||||
const char *condp;
|
||||
size_t len;
|
||||
|
||||
if(data->set.timecondition == CURL_TIMECOND_NONE)
|
||||
/* no condition was asked for */
|
||||
@@ -1967,16 +1972,19 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
|
||||
case CURL_TIMECOND_IFMODSINCE:
|
||||
condp = "If-Modified-Since";
|
||||
len = 17;
|
||||
break;
|
||||
case CURL_TIMECOND_IFUNMODSINCE:
|
||||
condp = "If-Unmodified-Since";
|
||||
len = 19;
|
||||
break;
|
||||
case CURL_TIMECOND_LASTMOD:
|
||||
condp = "Last-Modified";
|
||||
len = 13;
|
||||
break;
|
||||
}
|
||||
|
||||
if(Curl_checkheaders(data, condp)) {
|
||||
if(Curl_checkheaders(data, condp, len)) {
|
||||
/* A custom header was specified; it will be sent instead. */
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -2065,7 +2073,7 @@ CURLcode Curl_http_useragent(struct Curl_easy *data)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(data, "User-Agent")) {
|
||||
if(Curl_checkheaders(data, STRCONST("User-Agent"))) {
|
||||
free(data->state.aptr.uagent);
|
||||
data->state.aptr.uagent = NULL;
|
||||
}
|
||||
@@ -2085,10 +2093,11 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
data->state.first_remote_port = conn->remote_port;
|
||||
data->state.first_remote_protocol = conn->handler->protocol;
|
||||
}
|
||||
Curl_safefree(data->state.aptr.host);
|
||||
|
||||
ptr = Curl_checkheaders(data, "Host");
|
||||
ptr = Curl_checkheaders(data, STRCONST("Host"));
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
strcasecompare(data->state.first_host, conn->host.name))) {
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
@@ -2305,7 +2314,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
if(http->sendit) {
|
||||
const char *cthdr = Curl_checkheaders(data, "Content-Type");
|
||||
const char *cthdr = Curl_checkheaders(data, STRCONST("Content-Type"));
|
||||
|
||||
/* Read and seek body only. */
|
||||
http->sendit->flags |= MIME_BODY_ONLY;
|
||||
@@ -2330,11 +2339,12 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = Curl_checkheaders(data, "Transfer-Encoding");
|
||||
ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding"));
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
data->req.upload_chunky =
|
||||
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
|
||||
Curl_compareheader(ptr,
|
||||
STRCONST("Transfer-Encoding:"), STRCONST("chunked"));
|
||||
}
|
||||
else {
|
||||
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
@@ -2394,7 +2404,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
http->postsize = data->state.infilesize;
|
||||
|
||||
if((http->postsize != -1) && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
(conn->bits.authneg ||
|
||||
!Curl_checkheaders(data, STRCONST("Content-Length")))) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
"\r\n", http->postsize);
|
||||
@@ -2409,7 +2420,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* end of headers */
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2434,7 +2445,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
/* This is form posting using mime data. */
|
||||
if(conn->bits.authneg) {
|
||||
/* nothing to post! */
|
||||
result = Curl_dyn_add(r, "Content-Length: 0\r\n\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("Content-Length: 0\r\n\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2454,7 +2465,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if(http->postsize != -1 && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
(conn->bits.authneg ||
|
||||
!Curl_checkheaders(data, STRCONST("Content-Length")))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_dyn_addf(r,
|
||||
@@ -2481,10 +2493,10 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
sure that the expect100header is always set to the preferred value
|
||||
here. */
|
||||
ptr = Curl_checkheaders(data, "Expect");
|
||||
ptr = Curl_checkheaders(data, STRCONST("Expect"));
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
|
||||
}
|
||||
else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
|
||||
result = expect100(data, conn, r);
|
||||
@@ -2495,7 +2507,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
data->state.expect100header = FALSE;
|
||||
|
||||
/* make the request end in a true CRLF */
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2534,7 +2546,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if((http->postsize != -1) && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
(conn->bits.authneg ||
|
||||
!Curl_checkheaders(data, STRCONST("Content-Length")))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@@ -2543,9 +2556,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_add(r, "Content-Type: application/"
|
||||
"x-www-form-urlencoded\r\n");
|
||||
if(!Curl_checkheaders(data, STRCONST("Content-Type"))) {
|
||||
result = Curl_dyn_addn(r, STRCONST("Content-Type: application/"
|
||||
"x-www-form-urlencoded\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2554,10 +2567,10 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
sure that the expect100header is always set to the preferred value
|
||||
here. */
|
||||
ptr = Curl_checkheaders(data, "Expect");
|
||||
ptr = Curl_checkheaders(data, STRCONST("Expect"));
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
|
||||
}
|
||||
else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
|
||||
result = expect100(data, conn, r);
|
||||
@@ -2584,7 +2597,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
get the data duplicated with malloc() and family. */
|
||||
|
||||
/* end of headers! */
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2606,12 +2619,12 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
result = Curl_dyn_addn(r, data->set.postfields,
|
||||
(size_t)http->postsize);
|
||||
if(!result)
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
included_body += 2;
|
||||
}
|
||||
}
|
||||
if(!result) {
|
||||
result = Curl_dyn_add(r, "\x30\x0d\x0a\x0d\x0a");
|
||||
result = Curl_dyn_addn(r, STRCONST("\x30\x0d\x0a\x0d\x0a"));
|
||||
/* 0 CR LF CR LF */
|
||||
included_body += 5;
|
||||
}
|
||||
@@ -2634,7 +2647,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||
|
||||
/* end of headers! */
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2643,14 +2656,14 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
#endif
|
||||
{
|
||||
/* end of headers! */
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(data->req.upload_chunky && conn->bits.authneg) {
|
||||
/* Chunky upload is selected and we're negotiating auth still, send
|
||||
end-of-data only */
|
||||
result = Curl_dyn_add(r, (char *)"\x30\x0d\x0a\x0d\x0a");
|
||||
result = Curl_dyn_addn(r, (char *)STRCONST("\x30\x0d\x0a\x0d\x0a"));
|
||||
/* 0 CR LF CR LF */
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2678,7 +2691,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
break;
|
||||
|
||||
default:
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2702,7 +2715,8 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *addcookies = NULL;
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie"))
|
||||
if(data->set.str[STRING_COOKIE] &&
|
||||
!Curl_checkheaders(data, STRCONST("Cookie")))
|
||||
addcookies = data->set.str[STRING_COOKIE];
|
||||
|
||||
if(data->cookies || addcookies) {
|
||||
@@ -2728,7 +2742,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
while(co) {
|
||||
if(co->value) {
|
||||
if(0 == count) {
|
||||
result = Curl_dyn_add(r, "Cookie: ");
|
||||
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
@@ -2744,14 +2758,14 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
}
|
||||
if(addcookies && !result) {
|
||||
if(!count)
|
||||
result = Curl_dyn_add(r, "Cookie: ");
|
||||
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
|
||||
if(!result) {
|
||||
result = Curl_dyn_addf(r, "%s%s", count?"; ":"", addcookies);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count && !result)
|
||||
result = Curl_dyn_add(r, "\r\n");
|
||||
result = Curl_dyn_addn(r, STRCONST("\r\n"));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2770,14 +2784,14 @@ CURLcode Curl_http_range(struct Curl_easy *data,
|
||||
* ones if any such are specified.
|
||||
*/
|
||||
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
|
||||
!Curl_checkheaders(data, "Range")) {
|
||||
!Curl_checkheaders(data, STRCONST("Range"))) {
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
free(data->state.aptr.rangeline);
|
||||
data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
|
||||
data->state.range);
|
||||
}
|
||||
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
|
||||
!Curl_checkheaders(data, "Content-Range")) {
|
||||
!Curl_checkheaders(data, STRCONST("Content-Range"))) {
|
||||
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
free(data->state.aptr.rangeline);
|
||||
@@ -2923,7 +2937,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
/* The resume point is at the end of file, consider this fine even if it
|
||||
doesn't allow resume from here. */
|
||||
infof(data, "The entire document is already downloaded");
|
||||
connclose(conn, "already downloaded");
|
||||
streamclose(conn, "already downloaded");
|
||||
/* Abort download */
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
*done = TRUE;
|
||||
@@ -2948,10 +2962,10 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
/* We're simulating a http 304 from server so we return
|
||||
what should have been returned from the server */
|
||||
data->info.httpcode = 304;
|
||||
infof(data, "Simulate a HTTP 304 response!");
|
||||
infof(data, "Simulate a HTTP 304 response");
|
||||
/* we abort the transfer before it is completed == we ruin the
|
||||
re-use ability. Close the connection */
|
||||
connclose(conn, "Simulated 304 handling");
|
||||
streamclose(conn, "Simulated 304 handling");
|
||||
return CURLE_OK;
|
||||
}
|
||||
} /* we have a time condition */
|
||||
@@ -2962,14 +2976,14 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
#ifdef HAVE_LIBZ
|
||||
CURLcode Curl_transferencode(struct Curl_easy *data)
|
||||
{
|
||||
if(!Curl_checkheaders(data, "TE") &&
|
||||
if(!Curl_checkheaders(data, STRCONST("TE")) &&
|
||||
data->set.http_transfer_encoding) {
|
||||
/* When we are to insert a TE: header in the request, we must also insert
|
||||
TE in a Connection: header, so we need to merge the custom provided
|
||||
Connection: header and prevent the original to get sent. Note that if
|
||||
the user has inserted his/her own TE: header we don't do this magic
|
||||
but then assume that the user will handle it all! */
|
||||
char *cptr = Curl_checkheaders(data, "Connection");
|
||||
char *cptr = Curl_checkheaders(data, STRCONST("Connection"));
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(data->state.aptr.te);
|
||||
@@ -3089,13 +3103,13 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->state.referer && !Curl_checkheaders(data, "Referer")) {
|
||||
if(data->state.referer && !Curl_checkheaders(data, STRCONST("Referer"))) {
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer);
|
||||
if(!data->state.aptr.ref)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding") &&
|
||||
if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
data->state.aptr.accept_encoding =
|
||||
@@ -3117,7 +3131,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
|
||||
p_accept = Curl_checkheaders(data,
|
||||
STRCONST("Accept"))?NULL:"Accept: */*\r\n";
|
||||
|
||||
result = Curl_http_resume(data, conn, httpreq);
|
||||
if(result)
|
||||
@@ -3147,7 +3162,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_ALTSVC
|
||||
if(conn->bits.altused && !Curl_checkheaders(data, "Alt-Used")) {
|
||||
if(conn->bits.altused && !Curl_checkheaders(data, STRCONST("Alt-Used"))) {
|
||||
altused = aprintf("Alt-Used: %s:%d\r\n",
|
||||
conn->conn_to_host.name, conn->conn_to_port);
|
||||
if(!altused) {
|
||||
@@ -3194,8 +3209,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkheaders(data, "Proxy-Connection") &&
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))?
|
||||
!Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
|
||||
!Curl_checkProxyheaders(data,
|
||||
conn,
|
||||
STRCONST("Proxy-Connection")))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
#else
|
||||
"",
|
||||
@@ -3308,20 +3325,6 @@ checkhttpprefix(struct Curl_easy *data,
|
||||
struct curl_slist *head = data->set.http200aliases;
|
||||
statusline rc = STATUS_BAD;
|
||||
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert from the network encoding using a scratch area */
|
||||
char *scratch = strdup(s);
|
||||
if(!scratch) {
|
||||
failf(data, "Failed to allocate memory for conversion!");
|
||||
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
|
||||
}
|
||||
if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
free(scratch);
|
||||
return FALSE; /* can't return CURLE_foobar so return FALSE */
|
||||
}
|
||||
s = scratch;
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
while(head) {
|
||||
if(checkprefixmax(head->data, s, len)) {
|
||||
@@ -3334,9 +3337,6 @@ checkhttpprefix(struct Curl_easy *data,
|
||||
if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
|
||||
rc = onmatch;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
free(scratch);
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3347,26 +3347,9 @@ checkrtspprefix(struct Curl_easy *data,
|
||||
{
|
||||
statusline result = STATUS_BAD;
|
||||
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert from the network encoding using a scratch area */
|
||||
char *scratch = strdup(s);
|
||||
if(!scratch) {
|
||||
failf(data, "Failed to allocate memory for conversion!");
|
||||
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
|
||||
}
|
||||
if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
result = FALSE; /* can't return CURLE_foobar so return FALSE */
|
||||
}
|
||||
else if(checkprefixmax("RTSP/", scratch, len))
|
||||
result = onmatch;
|
||||
free(scratch);
|
||||
#else
|
||||
(void)data; /* unused */
|
||||
if(checkprefixmax("RTSP/", s, len))
|
||||
result = onmatch;
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3412,7 +3395,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
}
|
||||
streamclose(conn, "overflow content-length");
|
||||
infof(data, "Overflow Content-Length: value!");
|
||||
infof(data, "Overflow Content-Length: value");
|
||||
}
|
||||
else {
|
||||
/* negative or just rubbish - bad HTTP */
|
||||
@@ -3436,7 +3419,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
else if((conn->httpversion == 10) &&
|
||||
conn->bits.httpproxy &&
|
||||
Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
|
||||
Curl_compareheader(headp,
|
||||
STRCONST("Proxy-Connection:"),
|
||||
STRCONST("keep-alive"))) {
|
||||
/*
|
||||
* When a HTTP/1.0 reply comes when using a proxy, the
|
||||
* 'Proxy-Connection: keep-alive' line tells us the
|
||||
@@ -3444,21 +3429,25 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
* Default action for 1.0 is to close.
|
||||
*/
|
||||
connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
|
||||
infof(data, "HTTP/1.0 proxy connection set to keep alive!");
|
||||
infof(data, "HTTP/1.0 proxy connection set to keep alive");
|
||||
}
|
||||
else if((conn->httpversion == 11) &&
|
||||
conn->bits.httpproxy &&
|
||||
Curl_compareheader(headp, "Proxy-Connection:", "close")) {
|
||||
Curl_compareheader(headp,
|
||||
STRCONST("Proxy-Connection:"),
|
||||
STRCONST("close"))) {
|
||||
/*
|
||||
* We get a HTTP/1.1 response from a proxy and it says it'll
|
||||
* close down after this transfer.
|
||||
*/
|
||||
connclose(conn, "Proxy-Connection: asked to close after done");
|
||||
infof(data, "HTTP/1.1 proxy connection set close!");
|
||||
infof(data, "HTTP/1.1 proxy connection set close");
|
||||
}
|
||||
#endif
|
||||
else if((conn->httpversion == 10) &&
|
||||
Curl_compareheader(headp, "Connection:", "keep-alive")) {
|
||||
Curl_compareheader(headp,
|
||||
STRCONST("Connection:"),
|
||||
STRCONST("keep-alive"))) {
|
||||
/*
|
||||
* A HTTP/1.0 reply with the 'Connection: keep-alive' line
|
||||
* tells us the connection will be kept alive for our
|
||||
@@ -3466,9 +3455,10 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
*
|
||||
* [RFC2068, section 19.7.1] */
|
||||
connkeep(conn, "Connection keep-alive");
|
||||
infof(data, "HTTP/1.0 connection set to keep alive!");
|
||||
infof(data, "HTTP/1.0 connection set to keep alive");
|
||||
}
|
||||
else if(Curl_compareheader(headp, "Connection:", "close")) {
|
||||
else if(Curl_compareheader(headp,
|
||||
STRCONST("Connection:"), STRCONST("close"))) {
|
||||
/*
|
||||
* [RFC 2616, section 8.1.2.1]
|
||||
* "Connection: close" is HTTP/1.1 language and means that
|
||||
@@ -3795,6 +3785,29 @@ CURLcode Curl_http_size(struct Curl_easy *data)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode verify_header(struct Curl_easy *data)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
const char *header = Curl_dyn_ptr(&data->state.headerb);
|
||||
size_t hlen = Curl_dyn_len(&data->state.headerb);
|
||||
char *ptr = memchr(header, 0x00, hlen);
|
||||
if(ptr) {
|
||||
/* this is bad, bail out */
|
||||
failf(data, "Nul byte in header");
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
if(k->headerline < 2)
|
||||
/* the first "header" is the status-line and it has no colon */
|
||||
return CURLE_OK;
|
||||
ptr = memchr(header, ':', hlen);
|
||||
if(!ptr) {
|
||||
/* this is bad, bail out */
|
||||
failf(data, "Header without colon");
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read any HTTP header lines from the server and pass them to the client app.
|
||||
*/
|
||||
@@ -3903,21 +3916,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
size_t headerlen;
|
||||
/* Zero-length header line means end of headers! */
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(0x0d == *headp) {
|
||||
*headp = '\r'; /* replace with CR in host encoding */
|
||||
headp++; /* pass the CR byte */
|
||||
}
|
||||
if(0x0a == *headp) {
|
||||
*headp = '\n'; /* replace with LF in host encoding */
|
||||
headp++; /* pass the LF byte */
|
||||
}
|
||||
#else
|
||||
if('\r' == *headp)
|
||||
headp++; /* pass the \r byte */
|
||||
if('\n' == *headp)
|
||||
headp++; /* pass the \n byte */
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(100 <= k->httpcode && 199 >= k->httpcode) {
|
||||
/* "A user agent MAY ignore unexpected 1xx status responses." */
|
||||
@@ -4028,9 +4030,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
|
||||
/* now, only output this if the header AND body are requested:
|
||||
*/
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
writetype = CLIENTWRITE_HEADER |
|
||||
(data->set.include_header ? CLIENTWRITE_BODY : 0) |
|
||||
((k->httpcode/100 == 1) ? CLIENTWRITE_1XX : 0);
|
||||
|
||||
headerlen = Curl_dyn_len(&data->state.headerb);
|
||||
result = Curl_client_write(data, writetype,
|
||||
@@ -4127,7 +4129,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(conn->bits.rewindaftersend) {
|
||||
/* We rewind after a complete send, so thus we continue
|
||||
sending now */
|
||||
infof(data, "Keep sending data to get tossed away!");
|
||||
infof(data, "Keep sending data to get tossed away");
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
}
|
||||
@@ -4183,36 +4185,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* Checks for special headers coming up.
|
||||
*/
|
||||
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(!k->headerline++) {
|
||||
/* This is the first header, it MUST be the error code line
|
||||
or else we consider this to be the body right away! */
|
||||
int httpversion_major;
|
||||
int rtspversion_major;
|
||||
int nc = 0;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
#define HEADER1 scratch
|
||||
#define SCRATCHSIZE 21
|
||||
CURLcode res;
|
||||
char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
|
||||
/* We can't really convert this yet because we don't know if it's the
|
||||
1st header line or the body. So we do a partial conversion into a
|
||||
scratch area, leaving the data at 'headp' as-is.
|
||||
*/
|
||||
strncpy(&scratch[0], headp, SCRATCHSIZE);
|
||||
scratch[SCRATCHSIZE] = 0; /* null terminate */
|
||||
res = Curl_convert_from_network(data,
|
||||
&scratch[0],
|
||||
SCRATCHSIZE);
|
||||
if(res)
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
return res;
|
||||
#else
|
||||
#define HEADER1 headp /* no conversion needed, just use headp */
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
|
||||
/*
|
||||
* https://tools.ietf.org/html/rfc7230#section-3.1.2
|
||||
* https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2
|
||||
*
|
||||
* The response code is always a three-digit number in HTTP as the spec
|
||||
* says. We allow any three-digit number here, but we cannot make
|
||||
@@ -4254,10 +4238,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
switch(httpversion) {
|
||||
case 10:
|
||||
case 11:
|
||||
#if defined(USE_NGHTTP2) || defined(USE_HYPER)
|
||||
#ifdef USE_HTTP2
|
||||
case 20:
|
||||
#endif
|
||||
#if defined(ENABLE_QUIC)
|
||||
#ifdef ENABLE_QUIC
|
||||
case 30:
|
||||
#endif
|
||||
conn->httpversion = (unsigned char)httpversion;
|
||||
@@ -4326,6 +4310,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
result = Curl_http_statusline(data, conn);
|
||||
if(result)
|
||||
return result;
|
||||
writetype |= CLIENTWRITE_STATUS;
|
||||
}
|
||||
else {
|
||||
k->header = FALSE; /* this is not a header line */
|
||||
@@ -4333,8 +4318,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_convert_from_network(data, headp, strlen(headp));
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
result = verify_header(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -4345,10 +4329,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
/*
|
||||
* End of header-checks. Write them to the client.
|
||||
*/
|
||||
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
if(k->httpcode/100 == 1)
|
||||
writetype |= CLIENTWRITE_1XX;
|
||||
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, headp,
|
||||
Curl_dyn_len(&data->state.headerb));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -38,6 +38,10 @@ typedef enum {
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(ENABLE_QUIC)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
extern const struct Curl_handler Curl_handler_http;
|
||||
|
||||
#ifdef USE_SSL
|
||||
@@ -47,13 +51,16 @@ extern const struct Curl_handler Curl_handler_https;
|
||||
/* Header specific functions */
|
||||
bool Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *header, /* header keyword _with_ colon */
|
||||
const char *content); /* content string to find */
|
||||
const size_t hlen, /* len of the keyword in bytes */
|
||||
const char *content, /* content string to find */
|
||||
const size_t clen); /* len of the content in bytes */
|
||||
|
||||
char *Curl_copy_header_value(const char *header);
|
||||
|
||||
char *Curl_checkProxyheaders(struct Curl_easy *data,
|
||||
const struct connectdata *conn,
|
||||
const char *thisheader);
|
||||
const char *thisheader,
|
||||
const size_t thislen);
|
||||
CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
struct Curl_easy *data,
|
||||
curl_off_t *bytes_written,
|
||||
@@ -160,6 +167,29 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data);
|
||||
struct h3out; /* see ngtcp2 */
|
||||
#endif
|
||||
|
||||
#ifdef USE_MSH3
|
||||
#ifdef _WIN32
|
||||
#define msh3_lock CRITICAL_SECTION
|
||||
#define msh3_lock_initialize(lock) InitializeCriticalSection(lock)
|
||||
#define msh3_lock_uninitialize(lock) DeleteCriticalSection(lock)
|
||||
#define msh3_lock_acquire(lock) EnterCriticalSection(lock)
|
||||
#define msh3_lock_release(lock) LeaveCriticalSection(lock)
|
||||
#else /* !_WIN32 */
|
||||
#include <pthread.h>
|
||||
#define msh3_lock pthread_mutex_t
|
||||
#define msh3_lock_initialize(lock) { \
|
||||
pthread_mutexattr_t attr; \
|
||||
pthread_mutexattr_init(&attr); \
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
|
||||
pthread_mutex_init(lock, &attr); \
|
||||
pthread_mutexattr_destroy(&attr); \
|
||||
}
|
||||
#define msh3_lock_uninitialize(lock) pthread_mutex_destroy(lock)
|
||||
#define msh3_lock_acquire(lock) pthread_mutex_lock(lock)
|
||||
#define msh3_lock_release(lock) pthread_mutex_unlock(lock)
|
||||
#endif /* _WIN32 */
|
||||
#endif /* USE_MSH3 */
|
||||
|
||||
/****************************************************************************
|
||||
* HTTP unique setup
|
||||
***************************************************************************/
|
||||
@@ -225,11 +255,13 @@ struct HTTP {
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_QUIC
|
||||
#ifndef USE_MSH3
|
||||
/*********** for HTTP/3 we store stream-local data here *************/
|
||||
int64_t stream3_id; /* stream we are interested in */
|
||||
bool firstheader; /* FALSE until headers arrive */
|
||||
bool firstbody; /* FALSE until body arrives */
|
||||
bool h3req; /* FALSE until request is issued */
|
||||
#endif
|
||||
bool upload_done;
|
||||
#endif
|
||||
#ifdef USE_NGHTTP3
|
||||
@@ -237,6 +269,21 @@ struct HTTP {
|
||||
struct h3out *h3out; /* per-stream buffers for upload */
|
||||
struct dynbuf overflow; /* excess data received during a single Curl_read */
|
||||
#endif
|
||||
#ifdef USE_MSH3
|
||||
struct MSH3_REQUEST *req;
|
||||
msh3_lock recv_lock;
|
||||
/* Receive Buffer (Headers and Data) */
|
||||
uint8_t* recv_buf;
|
||||
size_t recv_buf_alloc;
|
||||
/* Receive Headers */
|
||||
size_t recv_header_len;
|
||||
bool recv_header_complete;
|
||||
/* Receive Data */
|
||||
size_t recv_data_len;
|
||||
bool recv_data_complete;
|
||||
/* General Receive Error */
|
||||
CURLcode recv_error;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
@@ -317,4 +364,10 @@ Curl_http_output_auth(struct Curl_easy *data,
|
||||
bool proxytunnel); /* TRUE if this is the request setting
|
||||
up the proxy tunnel */
|
||||
|
||||
/*
|
||||
* Curl_allow_auth_to_host() tells if authentication, cookies or other
|
||||
* "sensitive data" can (still) be sent to this host.
|
||||
*/
|
||||
bool Curl_allow_auth_to_host(struct Curl_easy *data);
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -36,7 +36,10 @@
|
||||
#include "connect.h"
|
||||
#include "strtoofft.h"
|
||||
#include "strdup.h"
|
||||
#include "transfer.h"
|
||||
#include "dynbuf.h"
|
||||
#include "h2h3.h"
|
||||
#include "headers.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -64,7 +67,6 @@
|
||||
#define H2BUGF(x) do { } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err);
|
||||
static bool http2_connisdead(struct Curl_easy *data,
|
||||
@@ -200,9 +202,9 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
|
||||
nread = ((Curl_recv *)httpc->recv_underlying)(
|
||||
data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
||||
if(nread != -1) {
|
||||
infof(data,
|
||||
"%d bytes stray data read before trying h2 connection",
|
||||
(int)nread);
|
||||
H2BUGF(infof(data,
|
||||
"%d bytes stray data read before trying h2 connection",
|
||||
(int)nread));
|
||||
httpc->nread_inbuf = 0;
|
||||
httpc->inbuflen = nread;
|
||||
if(h2_process_pending_input(data, httpc, &result) < 0)
|
||||
@@ -513,7 +515,7 @@ static int set_transfer_url(struct Curl_easy *data,
|
||||
if(!u)
|
||||
return 5;
|
||||
|
||||
v = curl_pushheader_byname(hp, ":scheme");
|
||||
v = curl_pushheader_byname(hp, H2H3_PSEUDO_SCHEME);
|
||||
if(v) {
|
||||
uc = curl_url_set(u, CURLUPART_SCHEME, v, 0);
|
||||
if(uc) {
|
||||
@@ -522,7 +524,7 @@ static int set_transfer_url(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
v = curl_pushheader_byname(hp, ":authority");
|
||||
v = curl_pushheader_byname(hp, H2H3_PSEUDO_AUTHORITY);
|
||||
if(v) {
|
||||
uc = curl_url_set(u, CURLUPART_HOST, v, 0);
|
||||
if(uc) {
|
||||
@@ -531,7 +533,7 @@ static int set_transfer_url(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
v = curl_pushheader_byname(hp, ":path");
|
||||
v = curl_pushheader_byname(hp, H2H3_PSEUDO_PATH);
|
||||
if(v) {
|
||||
uc = curl_url_set(u, CURLUPART_PATH, v, 0);
|
||||
if(uc) {
|
||||
@@ -560,7 +562,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
const nghttp2_push_promise *frame)
|
||||
{
|
||||
int rv; /* one of the CURL_PUSH_* defines */
|
||||
H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!",
|
||||
H2BUGF(infof(data, "PUSH_PROMISE received, stream %u",
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
struct HTTP *stream;
|
||||
@@ -580,11 +582,11 @@ static int push_promise(struct Curl_easy *data,
|
||||
heads.data = data;
|
||||
heads.frame = frame;
|
||||
/* ask the application */
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!"));
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ask application"));
|
||||
|
||||
stream = data->req.p.http;
|
||||
if(!stream) {
|
||||
failf(data, "Internal NULL stream!");
|
||||
failf(data, "Internal NULL stream");
|
||||
(void)Curl_close(&newhandle);
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
@@ -651,7 +653,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
Curl_dyn_init(&newstream->trailer_recvbuf, DYN_H2_TRAILERS);
|
||||
}
|
||||
else {
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!"));
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it"));
|
||||
rv = CURL_PUSH_DENY;
|
||||
}
|
||||
fail:
|
||||
@@ -757,7 +759,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
stream->status_code = -1;
|
||||
}
|
||||
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
@@ -800,7 +802,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
H2BUGF(infof(data_s, "Got frame type %x for stream %u!",
|
||||
H2BUGF(infof(data_s, "Got frame type %x for stream %u",
|
||||
frame->hd.type, stream_id));
|
||||
break;
|
||||
}
|
||||
@@ -823,10 +825,14 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
|
||||
/* get the stream from the hash based on Stream ID */
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s)
|
||||
/* Receiving a Stream ID not in the hash should not happen, this is an
|
||||
internal error more than anything else! */
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
if(!data_s) {
|
||||
/* Receiving a Stream ID not in the hash should not happen - unless
|
||||
we have aborted a transfer artificially and there were more data
|
||||
in the pipeline. Silently ignore. */
|
||||
H2BUGF(fprintf(stderr, "Data for stream %u but it doesn't exist\n",
|
||||
stream_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream = data_s->req.p.http;
|
||||
if(!stream)
|
||||
@@ -907,15 +913,15 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
/* remove the entry from the hash as the stream is now gone */
|
||||
rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
|
||||
if(rv) {
|
||||
infof(data_s, "http/2: failed to clear user_data for stream %d!",
|
||||
infof(data_s, "http/2: failed to clear user_data for stream %d",
|
||||
stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
if(stream_id == httpc->pause_stream_id) {
|
||||
H2BUGF(infof(data_s, "Stopped the pause stream!"));
|
||||
H2BUGF(infof(data_s, "Stopped the pause stream"));
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "Removed stream %u hash!", stream_id));
|
||||
H2BUGF(infof(data_s, "Removed stream %u hash", stream_id));
|
||||
stream->stream_id = 0; /* cleared */
|
||||
}
|
||||
return 0;
|
||||
@@ -1000,7 +1006,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
stream = data_s->req.p.http;
|
||||
if(!stream) {
|
||||
failf(data_s, "Internal NULL stream!");
|
||||
failf(data_s, "Internal NULL stream");
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1009,7 +1015,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||
char *h;
|
||||
|
||||
if(!strcmp(":authority", (const char *)name)) {
|
||||
if(!strcmp(H2H3_PSEUDO_AUTHORITY, (const char *)name)) {
|
||||
/* pseudo headers are lower case */
|
||||
int rc = 0;
|
||||
char *check = aprintf("%s:%d", conn->host.name, conn->remote_port);
|
||||
@@ -1072,22 +1078,27 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(namelen == sizeof(":status") - 1 &&
|
||||
memcmp(":status", name, namelen) == 0) {
|
||||
if(namelen == sizeof(H2H3_PSEUDO_STATUS) - 1 &&
|
||||
memcmp(H2H3_PSEUDO_STATUS, name, namelen) == 0) {
|
||||
/* nghttp2 guarantees :status is received first and only once, and
|
||||
value is 3 digits status code, and decode_status_code always
|
||||
succeeds. */
|
||||
char buffer[32];
|
||||
stream->status_code = decode_status_code(value, valuelen);
|
||||
DEBUGASSERT(stream->status_code != -1);
|
||||
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "HTTP/2 ");
|
||||
msnprintf(buffer, sizeof(buffer), H2H3_PSEUDO_STATUS ":%u\r",
|
||||
stream->status_code);
|
||||
result = Curl_headers_push(data_s, buffer, CURLH_PSEUDO);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("HTTP/2 "));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
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_dyn_add(&stream->header_recvbuf, " \r\n");
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST(" \r\n"));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
/* if we receive data for another handle, wake that up */
|
||||
@@ -1105,13 +1116,13 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, name, namelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, ": ");
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST(": "));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
|
||||
result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
/* if we receive data for another handle, wake that up */
|
||||
@@ -1227,17 +1238,18 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
!httpc->h2) /* not HTTP/2 ? */
|
||||
return;
|
||||
|
||||
if(premature) {
|
||||
/* do this before the reset handling, as that might clear ->stream_id */
|
||||
if(http->stream_id == httpc->pause_stream_id) {
|
||||
H2BUGF(infof(data, "DONE the pause stream (%x)", http->stream_id));
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
if(premature || (!http->closed && http->stream_id)) {
|
||||
/* RST_STREAM */
|
||||
set_transfer(httpc, data); /* set the transfer */
|
||||
H2BUGF(infof(data, "RST stream %x", http->stream_id));
|
||||
if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
|
||||
http->stream_id, NGHTTP2_STREAM_CLOSED))
|
||||
(void)nghttp2_session_send(httpc->h2);
|
||||
|
||||
if(http->stream_id == httpc->pause_stream_id) {
|
||||
infof(data, "stopped the pause stream!");
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->state.drain)
|
||||
@@ -1248,7 +1260,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
int rv = nghttp2_session_set_stream_user_data(httpc->h2,
|
||||
http->stream_id, 0);
|
||||
if(rv) {
|
||||
infof(data, "http/2: failed to clear user_data for stream %d!",
|
||||
infof(data, "http/2: failed to clear user_data for stream %d",
|
||||
http->stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
@@ -1273,7 +1285,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
|
||||
rc = nghttp2_session_callbacks_new(&callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2 callbacks!");
|
||||
failf(data, "Couldn't initialize nghttp2 callbacks");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
|
||||
@@ -1302,7 +1314,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
|
||||
nghttp2_session_callbacks_del(callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2!");
|
||||
failf(data, "Couldn't initialize nghttp2");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
}
|
||||
@@ -1337,7 +1349,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
}
|
||||
conn->proto.httpc.binlen = binlen;
|
||||
|
||||
result = Curl_base64url_encode(data, (const char *)binsettings, binlen,
|
||||
result = Curl_base64url_encode((const char *)binsettings, binlen,
|
||||
&base64, &blen);
|
||||
if(result) {
|
||||
Curl_dyn_free(req);
|
||||
@@ -1507,7 +1519,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
|
||||
stream->closed = FALSE;
|
||||
if(stream->error == NGHTTP2_REFUSED_STREAM) {
|
||||
H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!",
|
||||
H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection",
|
||||
stream->stream_id));
|
||||
connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
|
||||
data->state.refused_stream = TRUE;
|
||||
@@ -1666,7 +1678,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
));
|
||||
|
||||
if((data->state.drain) && stream->memlen) {
|
||||
H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)",
|
||||
H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u (%p => %p)",
|
||||
stream->memlen, stream->stream_id,
|
||||
stream->mem, mem));
|
||||
if(mem != stream->mem) {
|
||||
@@ -1816,80 +1828,6 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Index where :authority header field will appear in request header
|
||||
field list. */
|
||||
#define AUTHORITY_DST_IDX 3
|
||||
|
||||
/* USHRT_MAX is 65535 == 0xffff */
|
||||
#define HEADER_OVERFLOW(x) \
|
||||
(x.namelen > 0xffff || x.valuelen > 0xffff - x.namelen)
|
||||
|
||||
/*
|
||||
* Check header memory for the token "trailers".
|
||||
* Parse the tokens as separated by comma and surrounded by whitespace.
|
||||
* Returns TRUE if found or FALSE if not.
|
||||
*/
|
||||
static bool contains_trailers(const char *p, size_t len)
|
||||
{
|
||||
const char *end = p + len;
|
||||
for(;;) {
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || (size_t)(end - p) < sizeof("trailers") - 1)
|
||||
return FALSE;
|
||||
if(strncasecompare("trailers", p, sizeof("trailers") - 1)) {
|
||||
p += sizeof("trailers") - 1;
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || *p == ',')
|
||||
return TRUE;
|
||||
}
|
||||
/* skip to next token */
|
||||
for(; p != end && *p != ','; ++p)
|
||||
;
|
||||
if(p == end)
|
||||
return FALSE;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
/* Send header to server */
|
||||
HEADERINST_FORWARD,
|
||||
/* Don't send header to server */
|
||||
HEADERINST_IGNORE,
|
||||
/* Discard header, and replace it with "te: trailers" */
|
||||
HEADERINST_TE_TRAILERS
|
||||
} header_instruction;
|
||||
|
||||
/* Decides how to treat given header field. */
|
||||
static header_instruction inspect_header(const char *name, size_t namelen,
|
||||
const char *value, size_t valuelen) {
|
||||
switch(namelen) {
|
||||
case 2:
|
||||
if(!strncasecompare("te", name, namelen))
|
||||
return HEADERINST_FORWARD;
|
||||
|
||||
return contains_trailers(value, valuelen) ?
|
||||
HEADERINST_TE_TRAILERS : HEADERINST_IGNORE;
|
||||
case 7:
|
||||
return strncasecompare("upgrade", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 10:
|
||||
return (strncasecompare("connection", name, namelen) ||
|
||||
strncasecompare("keep-alive", name, namelen)) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 16:
|
||||
return strncasecompare("proxy-connection", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 17:
|
||||
return strncasecompare("transfer-encoding", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
default:
|
||||
return HEADERINST_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@@ -1904,14 +1842,12 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
nghttp2_nv *nva = NULL;
|
||||
size_t nheader;
|
||||
size_t i;
|
||||
size_t authority_idx;
|
||||
char *hdbuf = (char *)mem;
|
||||
char *end, *line_end;
|
||||
nghttp2_data_provider data_prd;
|
||||
int32_t stream_id;
|
||||
nghttp2_session *h2 = httpc->h2;
|
||||
nghttp2_priority_spec pri_spec;
|
||||
CURLcode result;
|
||||
struct h2h3req *hreq;
|
||||
|
||||
(void)sockindex;
|
||||
|
||||
@@ -1977,174 +1913,29 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Calculate number of headers contained in [mem, mem + len) */
|
||||
/* Here, we assume the curl http code generate *correct* HTTP header
|
||||
field block */
|
||||
nheader = 0;
|
||||
for(i = 1; i < len; ++i) {
|
||||
if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') {
|
||||
++nheader;
|
||||
++i;
|
||||
}
|
||||
result = Curl_pseudo_headers(data, mem, len, &hreq);
|
||||
if(result) {
|
||||
*err = result;
|
||||
return -1;
|
||||
}
|
||||
if(nheader < 2)
|
||||
goto fail;
|
||||
nheader = hreq->entries;
|
||||
|
||||
/* We counted additional 2 \r\n in the first and last line. We need 3
|
||||
new headers: :method, :path and :scheme. Therefore we need one
|
||||
more space. */
|
||||
nheader += 1;
|
||||
nva = malloc(sizeof(nghttp2_nv) * nheader);
|
||||
if(!nva) {
|
||||
Curl_pseudo_free(hreq);
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Extract :method, :path from request line
|
||||
We do line endings with CRLF so checking for CR is enough */
|
||||
line_end = memchr(hdbuf, '\r', len);
|
||||
if(!line_end)
|
||||
goto fail;
|
||||
|
||||
/* Method does not contain spaces */
|
||||
end = memchr(hdbuf, ' ', line_end - hdbuf);
|
||||
if(!end || end == hdbuf)
|
||||
goto fail;
|
||||
nva[0].name = (unsigned char *)":method";
|
||||
nva[0].namelen = strlen((char *)nva[0].name);
|
||||
nva[0].value = (unsigned char *)hdbuf;
|
||||
nva[0].valuelen = (size_t)(end - hdbuf);
|
||||
nva[0].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[0])) {
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdbuf = end + 1;
|
||||
|
||||
/* Path may contain spaces so scan backwards */
|
||||
end = NULL;
|
||||
for(i = (size_t)(line_end - hdbuf); i; --i) {
|
||||
if(hdbuf[i - 1] == ' ') {
|
||||
end = &hdbuf[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!end || end == hdbuf)
|
||||
goto fail;
|
||||
nva[1].name = (unsigned char *)":path";
|
||||
nva[1].namelen = strlen((char *)nva[1].name);
|
||||
nva[1].value = (unsigned char *)hdbuf;
|
||||
nva[1].valuelen = (size_t)(end - hdbuf);
|
||||
nva[1].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[1])) {
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nva[2].name = (unsigned char *)":scheme";
|
||||
nva[2].namelen = strlen((char *)nva[2].name);
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
nva[2].value = (unsigned char *)"https";
|
||||
else
|
||||
nva[2].value = (unsigned char *)"http";
|
||||
nva[2].valuelen = strlen((char *)nva[2].value);
|
||||
nva[2].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[2])) {
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
authority_idx = 0;
|
||||
i = 3;
|
||||
while(i < nheader) {
|
||||
size_t hlen;
|
||||
|
||||
hdbuf = line_end + 2;
|
||||
|
||||
/* check for next CR, but only within the piece of data left in the given
|
||||
buffer */
|
||||
line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem));
|
||||
if(!line_end || (line_end == hdbuf))
|
||||
goto fail;
|
||||
|
||||
/* header continuation lines are not supported */
|
||||
if(*hdbuf == ' ' || *hdbuf == '\t')
|
||||
goto fail;
|
||||
|
||||
for(end = hdbuf; end < line_end && *end != ':'; ++end)
|
||||
;
|
||||
if(end == hdbuf || end == line_end)
|
||||
goto fail;
|
||||
hlen = end - hdbuf;
|
||||
|
||||
if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = (unsigned char *)":authority";
|
||||
nva[i].namelen = strlen((char *)nva[i].name);
|
||||
}
|
||||
else {
|
||||
nva[i].namelen = (size_t)(end - hdbuf);
|
||||
/* Lower case the header name for HTTP/2 */
|
||||
Curl_strntolower((char *)hdbuf, hdbuf, nva[i].namelen);
|
||||
nva[i].name = (unsigned char *)hdbuf;
|
||||
}
|
||||
hdbuf = end + 1;
|
||||
while(*hdbuf == ' ' || *hdbuf == '\t')
|
||||
++hdbuf;
|
||||
end = line_end;
|
||||
|
||||
switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
|
||||
end - hdbuf)) {
|
||||
case HEADERINST_IGNORE:
|
||||
/* skip header fields prohibited by HTTP/2 specification. */
|
||||
--nheader;
|
||||
continue;
|
||||
case HEADERINST_TE_TRAILERS:
|
||||
nva[i].value = (uint8_t*)"trailers";
|
||||
nva[i].valuelen = sizeof("trailers") - 1;
|
||||
break;
|
||||
default:
|
||||
nva[i].value = (unsigned char *)hdbuf;
|
||||
nva[i].valuelen = (size_t)(end - hdbuf);
|
||||
}
|
||||
|
||||
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[i])) {
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
/* :authority must come before non-pseudo header fields */
|
||||
if(authority_idx && authority_idx != AUTHORITY_DST_IDX) {
|
||||
nghttp2_nv authority = nva[authority_idx];
|
||||
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
|
||||
nva[i] = nva[i - 1];
|
||||
}
|
||||
nva[i] = authority;
|
||||
}
|
||||
|
||||
/* Warn stream may be rejected if cumulative length of headers is too large.
|
||||
It appears nghttp2 will not send a header frame larger than 64KB. */
|
||||
#define MAX_ACC 60000 /* <64KB to account for some overhead */
|
||||
{
|
||||
size_t acc = 0;
|
||||
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
H2BUGF(infof(data, "h2 header: %.*s:%.*s",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
|
||||
if(acc > MAX_ACC) {
|
||||
infof(data, "http2_send: Warning: The cumulative length of all "
|
||||
"headers exceeds %d bytes and that could cause the "
|
||||
"stream to be rejected.", MAX_ACC);
|
||||
else {
|
||||
unsigned int i;
|
||||
for(i = 0; i < nheader; i++) {
|
||||
nva[i].name = (unsigned char *)hreq->header[i].name;
|
||||
nva[i].namelen = hreq->header[i].namelen;
|
||||
nva[i].value = (unsigned char *)hreq->header[i].value;
|
||||
nva[i].valuelen = hreq->header[i].valuelen;
|
||||
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
}
|
||||
Curl_pseudo_free(hreq);
|
||||
}
|
||||
|
||||
h2_pri_spec(data, &pri_spec);
|
||||
@@ -2213,11 +2004,6 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
|
||||
return len;
|
||||
|
||||
fail:
|
||||
free(nva);
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CURLcode Curl_http2_setup(struct Curl_easy *data,
|
||||
@@ -2271,8 +2057,6 @@ CURLcode Curl_http2_setup(struct Curl_easy *data,
|
||||
httpc->pause_stream_id = 0;
|
||||
httpc->drain_total = 0;
|
||||
|
||||
infof(data, "Connection state changed (HTTP/2 confirmed)");
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -2310,7 +2094,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
||||
stream->stream_id,
|
||||
data);
|
||||
if(rv) {
|
||||
infof(data, "http/2: failed to set user_data for stream %d!",
|
||||
infof(data, "http/2: failed to set user_data for stream %d",
|
||||
stream->stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -87,7 +87,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
struct tm tm;
|
||||
char timestamp[17];
|
||||
char date[9];
|
||||
const char *content_type = Curl_checkheaders(data, "Content-Type");
|
||||
const char *content_type = Curl_checkheaders(data, STRCONST("Content-Type"));
|
||||
char *canonical_headers = NULL;
|
||||
char *signed_headers = NULL;
|
||||
Curl_HttpReq httpreq;
|
||||
@@ -110,7 +110,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
DEBUGASSERT(!proxy);
|
||||
(void)proxy;
|
||||
|
||||
if(Curl_checkheaders(data, "Authorization")) {
|
||||
if(Curl_checkheaders(data, STRCONST("Authorization"))) {
|
||||
/* Authorization already present, Bailing out */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "dynbuf.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http.h"
|
||||
#include "non-ascii.h" /* for Curl_convert_to_network prototype */
|
||||
#include "strtoofft.h"
|
||||
#include "warnless.h"
|
||||
|
||||
@@ -74,18 +73,7 @@
|
||||
|
||||
*/
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* Check for an ASCII hex digit.
|
||||
We avoid the use of ISXDIGIT to accommodate non-ASCII hosts. */
|
||||
static bool isxdigit_ascii(char digit)
|
||||
{
|
||||
return (digit >= 0x30 && digit <= 0x39) /* 0-9 */
|
||||
|| (digit >= 0x41 && digit <= 0x46) /* A-F */
|
||||
|| (digit >= 0x61 && digit <= 0x66); /* a-f */
|
||||
}
|
||||
#else
|
||||
#define isxdigit_ascii(x) Curl_isxdigit(x)
|
||||
#endif
|
||||
|
||||
void Curl_httpchunk_init(struct Curl_easy *data)
|
||||
{
|
||||
@@ -157,14 +145,6 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
|
||||
/* length and datap are unmodified */
|
||||
ch->hexbuffer[ch->hexindex] = 0;
|
||||
|
||||
/* convert to host encoding before calling strtoul */
|
||||
result = Curl_convert_from_network(data, ch->hexbuffer, ch->hexindex);
|
||||
if(result) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* Treat it as a bad hex character */
|
||||
return CHUNKE_ILLEGAL_HEX;
|
||||
}
|
||||
|
||||
if(curlx_strtoofft(ch->hexbuffer, &endptr, 16, &ch->datasize))
|
||||
return CHUNKE_ILLEGAL_HEX;
|
||||
ch->state = CHUNK_LF; /* now wait for the CRLF */
|
||||
@@ -234,21 +214,16 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
|
||||
|
||||
if(tr) {
|
||||
size_t trlen;
|
||||
result = Curl_dyn_add(&conn->trailer, (char *)"\x0d\x0a");
|
||||
result = Curl_dyn_addn(&conn->trailer, (char *)STRCONST("\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(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(data, CLIENTWRITE_HEADER, tr, trlen);
|
||||
result = Curl_client_write(data,
|
||||
CLIENTWRITE_HEADER|CLIENTWRITE_TRAILER,
|
||||
tr, trlen);
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
return CHUNKE_PASSTHRU_ERROR;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -161,7 +161,7 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_auth_create_spnego_message(data, neg_ctx, &base64, &len);
|
||||
result = Curl_auth_create_spnego_message(neg_ctx, &base64, &len);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -213,8 +213,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
||||
ntlm, &ntlmmsg);
|
||||
if(!result) {
|
||||
DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
|
||||
result = Curl_base64_encode(data,
|
||||
(const char *) Curl_bufref_ptr(&ntlmmsg),
|
||||
result = Curl_base64_encode((const char *) Curl_bufref_ptr(&ntlmmsg),
|
||||
Curl_bufref_len(&ntlmmsg), &base64, &len);
|
||||
if(!result) {
|
||||
free(*allocuserpwd);
|
||||
@@ -233,8 +232,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
||||
result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp,
|
||||
ntlm, &ntlmmsg);
|
||||
if(!result && Curl_bufref_len(&ntlmmsg)) {
|
||||
result = Curl_base64_encode(data,
|
||||
(const char *) Curl_bufref_ptr(&ntlmmsg),
|
||||
result = Curl_base64_encode((const char *) Curl_bufref_ptr(&ntlmmsg),
|
||||
Curl_bufref_len(&ntlmmsg), &base64, &len);
|
||||
if(!result) {
|
||||
free(*allocuserpwd);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "url.h"
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
#include "curlx.h"
|
||||
#include "vtls/vtls.h"
|
||||
@@ -173,7 +172,7 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit)
|
||||
s = calloc(1, sizeof(struct http_connect_state));
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
infof(data, "allocate connect buffer!");
|
||||
infof(data, "allocate connect buffer");
|
||||
conn->connect_state = s;
|
||||
Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
|
||||
|
||||
@@ -221,7 +220,7 @@ void Curl_connect_done(struct Curl_easy *data)
|
||||
#ifdef USE_HYPER
|
||||
data->state.hconnect = FALSE;
|
||||
#endif
|
||||
infof(data, "CONNECT phase completed!");
|
||||
infof(data, "CONNECT phase completed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +244,7 @@ static CURLcode CONNECT_host(struct Curl_easy *data,
|
||||
if(!hostheader)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "Host")) {
|
||||
if(!Curl_checkProxyheaders(data, conn, STRCONST("Host"))) {
|
||||
host = aprintf("Host: %s\r\n", hostheader);
|
||||
if(!host) {
|
||||
free(hostheader);
|
||||
@@ -324,25 +323,29 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
data->state.aptr.proxyuserpwd?
|
||||
data->state.aptr.proxyuserpwd:"");
|
||||
|
||||
if(!result && !Curl_checkProxyheaders(data, conn, "User-Agent") &&
|
||||
if(!result && !Curl_checkProxyheaders(data,
|
||||
conn, STRCONST("User-Agent")) &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
result = Curl_dyn_addf(req, "User-Agent: %s\r\n",
|
||||
data->set.str[STRING_USERAGENT]);
|
||||
|
||||
if(!result && !Curl_checkProxyheaders(data, conn, "Proxy-Connection"))
|
||||
result = Curl_dyn_add(req, "Proxy-Connection: Keep-Alive\r\n");
|
||||
if(!result && !Curl_checkProxyheaders(data, conn,
|
||||
STRCONST("Proxy-Connection")))
|
||||
result = Curl_dyn_addn(req,
|
||||
STRCONST("Proxy-Connection: Keep-Alive\r\n"));
|
||||
|
||||
if(!result)
|
||||
result = Curl_add_custom_headers(data, TRUE, req);
|
||||
|
||||
if(!result)
|
||||
/* CRLF terminate the request */
|
||||
result = Curl_dyn_add(req, "\r\n");
|
||||
result = Curl_dyn_addn(req, STRCONST("\r\n"));
|
||||
|
||||
if(!result) {
|
||||
/* Send the connect request to the proxy */
|
||||
result = Curl_buffer_send(req, data, &data->info.request_size, 0,
|
||||
sockindex);
|
||||
s->headerlines = 0;
|
||||
}
|
||||
if(result)
|
||||
failf(data, "Failed sending CONNECT to proxy");
|
||||
@@ -470,7 +473,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if(Curl_dyn_addn(&s->rcvbuf, &byte, 1)) {
|
||||
failf(data, "CONNECT response too large!");
|
||||
failf(data, "CONNECT response too large");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
@@ -478,23 +481,18 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
if(byte != 0x0a)
|
||||
continue;
|
||||
|
||||
s->headerlines++;
|
||||
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, linep, perline);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* output debug if that is requested */
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
|
||||
|
||||
if(!data->set.suppress_connect_headers) {
|
||||
/* send the header to the callback */
|
||||
int writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
int writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT |
|
||||
(data->set.include_header ? CLIENTWRITE_BODY : 0) |
|
||||
(s->headerlines == 1 ? CLIENTWRITE_STATUS : 0);
|
||||
|
||||
result = Curl_client_write(data, writetype, linep, perline);
|
||||
if(result)
|
||||
@@ -596,7 +594,8 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
strlen("Content-Length:"), NULL, 10, &s->cl);
|
||||
}
|
||||
}
|
||||
else if(Curl_compareheader(linep, "Connection:", "close"))
|
||||
else if(Curl_compareheader(linep,
|
||||
STRCONST("Connection:"), STRCONST("close")))
|
||||
s->close_connection = TRUE;
|
||||
else if(checkprefix("Transfer-Encoding:", linep)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
@@ -607,14 +606,17 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
"CONNECT %03d response", k->httpcode);
|
||||
}
|
||||
else if(Curl_compareheader(linep,
|
||||
"Transfer-Encoding:", "chunked")) {
|
||||
STRCONST("Transfer-Encoding:"),
|
||||
STRCONST("chunked"))) {
|
||||
infof(data, "CONNECT responded chunked");
|
||||
s->chunked_encoding = TRUE;
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(data);
|
||||
}
|
||||
}
|
||||
else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
|
||||
else if(Curl_compareheader(linep,
|
||||
STRCONST("Proxy-Connection:"),
|
||||
STRCONST("close")))
|
||||
s->close_connection = TRUE;
|
||||
else if(2 == sscanf(linep, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
@@ -765,6 +767,9 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
options = hyper_clientconn_options_new();
|
||||
hyper_clientconn_options_set_preserve_header_case(options, 1);
|
||||
hyper_clientconn_options_set_preserve_header_order(options, 1);
|
||||
|
||||
if(!options) {
|
||||
failf(data, "Couldn't create hyper client options");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@@ -877,7 +882,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
|
||||
if(!Curl_checkProxyheaders(data, conn, STRCONST("User-Agent")) &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
struct dynbuf ua;
|
||||
Curl_dyn_init(&ua, DYN_HTTP_REQUEST);
|
||||
@@ -891,7 +896,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
Curl_dyn_free(&ua);
|
||||
}
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection")) {
|
||||
if(!Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) {
|
||||
result = Curl_hyper_header(data, headers,
|
||||
"Proxy-Connection: Keep-Alive");
|
||||
if(result)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -59,6 +59,7 @@ struct http_connect_state {
|
||||
struct dynbuf rcvbuf;
|
||||
struct dynbuf req;
|
||||
size_t nsend;
|
||||
size_t headerlines;
|
||||
enum keeponval {
|
||||
KEEPON_DONE,
|
||||
KEEPON_CONNECT,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -76,11 +76,15 @@ bool curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
if(in_w) {
|
||||
wchar_t punycode[IDN_MAX_LENGTH];
|
||||
int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
|
||||
free(in_w);
|
||||
curlx_unicodefree(in_w);
|
||||
if(chars) {
|
||||
*out = curlx_convert_wchar_to_UTF8(punycode);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
char *mstr = curlx_convert_wchar_to_UTF8(punycode);
|
||||
if(mstr) {
|
||||
*out = strdup(mstr);
|
||||
curlx_unicodefree(mstr);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,11 +101,15 @@ bool curl_win32_ascii_to_idn(const char *in, char **out)
|
||||
wchar_t unicode[IDN_MAX_LENGTH];
|
||||
int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len),
|
||||
unicode, IDN_MAX_LENGTH);
|
||||
free(in_w);
|
||||
curlx_unicodefree(in_w);
|
||||
if(chars) {
|
||||
*out = curlx_convert_wchar_to_UTF8(unicode);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
char *mstr = curlx_convert_wchar_to_UTF8(unicode);
|
||||
if(mstr) {
|
||||
*out = strdup(mstr);
|
||||
curlx_unicodefree(mstr);
|
||||
if(*out)
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -60,12 +60,10 @@
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/* Return the scope of the given address. */
|
||||
unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
|
||||
{
|
||||
#ifndef ENABLE_IPV6
|
||||
(void) sa;
|
||||
#else
|
||||
if(sa->sa_family == AF_INET6) {
|
||||
const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
|
||||
const unsigned char *b = sa6->sin6_addr.s6_addr;
|
||||
@@ -88,27 +86,25 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return IPV6_SCOPE_GLOBAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETIFADDRS)
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
if2ip_result_t Curl_if2ip(int af,
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned int remote_scope,
|
||||
unsigned int local_scope_id,
|
||||
#endif
|
||||
const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifaddrs *iface, *head;
|
||||
if2ip_result_t res = IF2IP_NOT_FOUND;
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
(void) remote_scope;
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \
|
||||
!defined(ENABLE_IPV6)
|
||||
#if defined(ENABLE_IPV6) && \
|
||||
!defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
(void) local_scope_id;
|
||||
#endif
|
||||
|
||||
@@ -181,8 +177,12 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
|
||||
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
if2ip_result_t Curl_if2ip(int af,
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned int remote_scope,
|
||||
unsigned int local_scope_id,
|
||||
#endif
|
||||
const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifreq req;
|
||||
@@ -192,8 +192,10 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
size_t len;
|
||||
const char *r;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
(void)remote_scope;
|
||||
(void)local_scope_id;
|
||||
#endif
|
||||
|
||||
if(!interf || (af != AF_INET))
|
||||
return IF2IP_NOT_FOUND;
|
||||
@@ -230,13 +232,19 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
|
||||
#else
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
if2ip_result_t Curl_if2ip(int af,
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned int remote_scope,
|
||||
unsigned int local_scope_id,
|
||||
#endif
|
||||
const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
(void) af;
|
||||
#ifdef ENABLE_IPV6
|
||||
(void) remote_scope;
|
||||
(void) local_scope_id;
|
||||
#endif
|
||||
(void) interf;
|
||||
(void) buf;
|
||||
(void) buf_size;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -30,7 +30,11 @@
|
||||
#define IPV6_SCOPE_UNIQUELOCAL 3 /* Unique local */
|
||||
#define IPV6_SCOPE_NODELOCAL 4 /* Loopback. */
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
|
||||
#else
|
||||
#define Curl_ipv6_scope(x) 0
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
IF2IP_NOT_FOUND = 0, /* Interface not found */
|
||||
@@ -38,8 +42,12 @@ typedef enum {
|
||||
IF2IP_FOUND = 2 /* The address has been stored in "buf" */
|
||||
} if2ip_result_t;
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
if2ip_result_t Curl_if2ip(int af,
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned int remote_scope,
|
||||
unsigned int local_scope_id,
|
||||
#endif
|
||||
const char *interf,
|
||||
char *buf, int buf_size);
|
||||
|
||||
#ifdef __INTERIX
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -507,7 +507,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
|
||||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!conn->bits.user_passwd) {
|
||||
if(!data->state.aptr.user) {
|
||||
state(data, IMAP_STOP);
|
||||
|
||||
return result;
|
||||
@@ -608,7 +608,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
|
||||
/* Check if already authenticated OR if there is enough data to authenticate
|
||||
with and end the connect phase if we don't */
|
||||
if(imapc->preauth ||
|
||||
!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
|
||||
!Curl_sasl_can_authenticate(&imapc->sasl, data)) {
|
||||
state(data, IMAP_STOP);
|
||||
return result;
|
||||
}
|
||||
@@ -624,7 +624,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
|
||||
result = imap_perform_login(data, conn);
|
||||
else {
|
||||
/* Other mechanisms not supported */
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
infof(data, "No known authentication mechanisms supported");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -777,7 +777,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data)
|
||||
NULL, MIMESTRATEGY_MAIL);
|
||||
|
||||
if(!result)
|
||||
if(!Curl_checkheaders(data, "Mime-Version"))
|
||||
if(!Curl_checkheaders(data, STRCONST("Mime-Version")))
|
||||
result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
|
||||
"Mime-Version: 1.0");
|
||||
|
||||
@@ -874,7 +874,7 @@ static CURLcode imap_state_servergreet_resp(struct Curl_easy *data,
|
||||
/* PREAUTH */
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
imapc->preauth = TRUE;
|
||||
infof(data, "PREAUTH connection, already authenticated!");
|
||||
infof(data, "PREAUTH connection, already authenticated");
|
||||
}
|
||||
else if(imapcode != IMAP_RESP_OK) {
|
||||
failf(data, "Got unexpected imap-server response");
|
||||
@@ -1986,7 +1986,7 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data)
|
||||
if(end > begin && end[-1] == '/')
|
||||
end--;
|
||||
|
||||
result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
|
||||
result = Curl_urldecode(begin, end - begin, &imap->mailbox, NULL,
|
||||
REJECT_CTRL);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2009,7 +2009,7 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
/* Decode the name parameter */
|
||||
result = Curl_urldecode(data, begin, ptr - begin, &name, NULL,
|
||||
result = Curl_urldecode(begin, ptr - begin, &name, NULL,
|
||||
REJECT_CTRL);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2020,7 +2020,7 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data)
|
||||
ptr++;
|
||||
|
||||
/* Decode the value parameter */
|
||||
result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen,
|
||||
result = Curl_urldecode(begin, ptr - begin, &value, &valuelen,
|
||||
REJECT_CTRL);
|
||||
if(result) {
|
||||
free(name);
|
||||
@@ -2108,7 +2108,7 @@ static CURLcode imap_parse_custom_request(struct Curl_easy *data)
|
||||
|
||||
if(custom) {
|
||||
/* URL decode the custom request */
|
||||
result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, REJECT_CTRL);
|
||||
result = Curl_urldecode(custom, 0, &imap->custom, NULL, REJECT_CTRL);
|
||||
|
||||
/* Extract the parameters if specified */
|
||||
if(!result) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* Copyright (c) 2004 - 2021 Daniel Stenberg
|
||||
* Copyright (c) 2004 - 2022 Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "sendf.h"
|
||||
#include "curl_krb5.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "strcase.h"
|
||||
#include "strdup.h"
|
||||
|
||||
@@ -81,11 +80,6 @@ static CURLcode ftpsend(struct Curl_easy *data, struct connectdata *conn,
|
||||
write_len += 2;
|
||||
bytes_written = 0;
|
||||
|
||||
result = Curl_convert_to_network(data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
for(;;) {
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
@@ -298,7 +292,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
|
||||
if(output_buffer.length) {
|
||||
char *cmd;
|
||||
|
||||
result = Curl_base64_encode(data, (char *)output_buffer.value,
|
||||
result = Curl_base64_encode((char *)output_buffer.value,
|
||||
output_buffer.length, &p, &base64_sz);
|
||||
if(result) {
|
||||
infof(data, "base64-encoding: %s", curl_easy_strerror(result));
|
||||
@@ -612,7 +606,7 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
|
||||
return; /* error */
|
||||
|
||||
if(iscmd) {
|
||||
error = Curl_base64_encode(data, buffer, curlx_sitouz(bytes),
|
||||
error = Curl_base64_encode(buffer, curlx_sitouz(bytes),
|
||||
&cmd_buffer, &cmd_size);
|
||||
if(error) {
|
||||
free(buffer);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -306,8 +306,8 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
rc = _ldap_url_parse(data, conn, &ludp);
|
||||
#endif
|
||||
if(rc) {
|
||||
failf(data, "LDAP local: %s", ldap_err2string(rc));
|
||||
result = CURLE_LDAP_INVALID_URL;
|
||||
failf(data, "Bad LDAP URL: %s", ldap_err2string(rc));
|
||||
result = CURLE_URL_MALFORMAT;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
host = conn->host.name;
|
||||
#endif
|
||||
|
||||
if(conn->bits.user_passwd) {
|
||||
if(data->state.aptr.user) {
|
||||
user = conn->user;
|
||||
passwd = conn->passwd;
|
||||
}
|
||||
@@ -361,7 +361,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
(strcasecompare(data->set.ssl.cert_type, "DER")))
|
||||
cert_type = LDAPSSL_CERT_FILETYPE_DER;
|
||||
if(!ldap_ca) {
|
||||
failf(data, "LDAP local: ERROR %s CA cert not set!",
|
||||
failf(data, "LDAP local: ERROR %s CA cert not set",
|
||||
(cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
@@ -400,12 +400,12 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
if((data->set.ssl.cert_type) &&
|
||||
(!strcasecompare(data->set.ssl.cert_type, "PEM"))) {
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type");
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
if(!ldap_ca) {
|
||||
failf(data, "LDAP local: ERROR PEM CA cert not set!");
|
||||
failf(data, "LDAP local: ERROR PEM CA cert not set");
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
@@ -636,11 +636,8 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
if((attr_len > 7) &&
|
||||
(strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) {
|
||||
/* Binary attribute, encode to base64. */
|
||||
result = Curl_base64_encode(data,
|
||||
vals[i]->bv_val,
|
||||
vals[i]->bv_len,
|
||||
&val_b64,
|
||||
&val_b64_sz);
|
||||
result = Curl_base64_encode(vals[i]->bv_val, vals[i]->bv_len,
|
||||
&val_b64, &val_b64_sz);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
FREE_ON_WINLDAP(attr);
|
||||
@@ -870,7 +867,7 @@ static int _ldap_url_parse2(struct Curl_easy *data,
|
||||
LDAP_TRACE(("DN '%s'\n", dn));
|
||||
|
||||
/* Unescape the DN */
|
||||
result = Curl_urldecode(data, dn, 0, &unescaped, NULL, REJECT_ZERO);
|
||||
result = Curl_urldecode(dn, 0, &unescaped, NULL, REJECT_ZERO);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
@@ -935,7 +932,7 @@ static int _ldap_url_parse2(struct Curl_easy *data,
|
||||
LDAP_TRACE(("attr[%zu] '%s'\n", i, attributes[i]));
|
||||
|
||||
/* Unescape the attribute */
|
||||
result = Curl_urldecode(data, attributes[i], 0, &unescaped, NULL,
|
||||
result = Curl_urldecode(attributes[i], 0, &unescaped, NULL,
|
||||
REJECT_ZERO);
|
||||
if(result) {
|
||||
free(attributes);
|
||||
@@ -1005,7 +1002,7 @@ static int _ldap_url_parse2(struct Curl_easy *data,
|
||||
LDAP_TRACE(("filter '%s'\n", filter));
|
||||
|
||||
/* Unescape the filter */
|
||||
result = Curl_urldecode(data, filter, 0, &unescaped, NULL, REJECT_ZERO);
|
||||
result = Curl_urldecode(filter, 0, &unescaped, NULL, REJECT_ZERO);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -60,22 +60,22 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
typedef struct md5_ctx my_md5_ctx;
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
md5_init(ctx);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
static void my_md5_update(my_md5_ctx *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
md5_update(ctx, inputLen, input);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
|
||||
{
|
||||
md5_digest(ctx, 16, digest);
|
||||
}
|
||||
@@ -83,11 +83,38 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
#elif defined(USE_OPENSSL_MD5) || defined(USE_WOLFSSL_MD5)
|
||||
|
||||
/* When OpenSSL or wolfSSL is available, we use their MD5 functions. */
|
||||
#if defined(USE_OPENSSL_MD5)
|
||||
#include <openssl/md5.h>
|
||||
#elif defined(USE_WOLFSSL_MD5)
|
||||
#include <wolfssl/openssl/md5.h>
|
||||
#endif
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef MD5_CTX my_md5_ctx;
|
||||
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
if(!MD5_Init(ctx))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void my_md5_update(my_md5_ctx *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int len)
|
||||
{
|
||||
(void)MD5_Update(ctx, input, len);
|
||||
}
|
||||
|
||||
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
|
||||
{
|
||||
(void)MD5_Final(digest, ctx);
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
#include <mbedtls/md5.h>
|
||||
@@ -97,21 +124,25 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef mbedtls_md5_context MD5_CTX;
|
||||
typedef mbedtls_md5_context my_md5_ctx;
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_md5_starts(ctx);
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
|
||||
if(mbedtls_md5_starts(ctx))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#elif defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
if(mbedtls_md5_starts_ret(ctx))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
(void) mbedtls_md5_starts_ret(ctx);
|
||||
(void)mbedtls_md5_starts(ctx);
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
static void my_md5_update(my_md5_ctx *ctx,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_md5_update(ctx, data, length);
|
||||
@@ -120,7 +151,7 @@ static void MD5_Update(MD5_CTX *ctx,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_md5_finish(ctx, digest);
|
||||
@@ -143,25 +174,27 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
Declaring the functions as static like this seems to be a bit more
|
||||
reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
# define MD5_CTX CC_MD5_CTX
|
||||
# define my_md5_ctx CC_MD5_CTX
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
CC_MD5_Init(ctx);
|
||||
if(!CC_MD5_Init(ctx))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
static void my_md5_update(my_md5_ctx *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
CC_MD5_Update(ctx, input, inputLen);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
|
||||
{
|
||||
CC_MD5_Final(digest, ctx);
|
||||
}
|
||||
@@ -177,25 +210,30 @@ struct md5_ctx {
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTHASH hHash;
|
||||
};
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
typedef struct md5_ctx my_md5_ctx;
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
|
||||
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
|
||||
if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) {
|
||||
CryptReleaseContext(ctx->hCryptProv, 0);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
static void my_md5_update(my_md5_ctx *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
|
||||
{
|
||||
unsigned long length = 0;
|
||||
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
|
||||
@@ -263,11 +301,12 @@ struct md5_ctx {
|
||||
unsigned char buffer[64];
|
||||
MD5_u32plus block[16];
|
||||
};
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
typedef struct md5_ctx my_md5_ctx;
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx);
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||
static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx);
|
||||
static void my_md5_update(my_md5_ctx *ctx, const void *data,
|
||||
unsigned long size);
|
||||
static void my_md5_final(unsigned char *result, my_md5_ctx *ctx);
|
||||
|
||||
/*
|
||||
* The basic MD5 functions.
|
||||
@@ -318,7 +357,7 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||
* This processes one or more 64-byte data blocks, but does NOT update
|
||||
* the bit counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
static const void *body(my_md5_ctx *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD5_u32plus a, b, c, d;
|
||||
@@ -426,7 +465,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
static CURLcode my_md5_init(my_md5_ctx *ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
@@ -439,7 +478,8 @@ static CURLcode MD5_Init(MD5_CTX *ctx)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
static void my_md5_update(my_md5_ctx *ctx, const void *data,
|
||||
unsigned long size)
|
||||
{
|
||||
MD5_u32plus saved_lo;
|
||||
unsigned long used;
|
||||
@@ -474,7 +514,7 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
memcpy(ctx->buffer, data, size);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||
static void my_md5_final(unsigned char *result, my_md5_ctx *ctx)
|
||||
{
|
||||
unsigned long used, available;
|
||||
|
||||
@@ -530,13 +570,13 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||
const struct HMAC_params Curl_HMAC_MD5[] = {
|
||||
{
|
||||
/* Hash initialization function. */
|
||||
CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
|
||||
CURLX_FUNCTION_CAST(HMAC_hinit_func, my_md5_init),
|
||||
/* Hash update function. */
|
||||
CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update),
|
||||
CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_md5_update),
|
||||
/* Hash computation end function. */
|
||||
CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final),
|
||||
CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_md5_final),
|
||||
/* Size of hash context structure. */
|
||||
sizeof(MD5_CTX),
|
||||
sizeof(my_md5_ctx),
|
||||
/* Maximum key length. */
|
||||
64,
|
||||
/* Result size. */
|
||||
@@ -547,13 +587,13 @@ const struct HMAC_params Curl_HMAC_MD5[] = {
|
||||
const struct MD5_params Curl_DIGEST_MD5[] = {
|
||||
{
|
||||
/* Digest initialization function */
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_init_func, my_md5_init),
|
||||
/* Digest update function */
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update),
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_update_func, my_md5_update),
|
||||
/* Digest computation end function */
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final),
|
||||
CURLX_FUNCTION_CAST(Curl_MD5_final_func, my_md5_final),
|
||||
/* Size of digest context struct */
|
||||
sizeof(MD5_CTX),
|
||||
sizeof(my_md5_ctx),
|
||||
/* Result size */
|
||||
16
|
||||
}
|
||||
@@ -564,15 +604,17 @@ const struct MD5_params Curl_DIGEST_MD5[] = {
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
|
||||
const size_t len)
|
||||
const size_t len)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
CURLcode result;
|
||||
my_md5_ctx ctx;
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, input, curlx_uztoui(len));
|
||||
MD5_Final(outbuffer, &ctx);
|
||||
|
||||
return CURLE_OK;
|
||||
result = my_md5_init(&ctx);
|
||||
if(!result) {
|
||||
my_md5_update(&ctx, input, curlx_uztoui(len));
|
||||
my_md5_final(outbuffer, &ctx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
|
||||
@@ -594,7 +636,11 @@ struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
|
||||
|
||||
ctxt->md5_hash = md5params;
|
||||
|
||||
(*md5params->md5_init_func)(ctxt->md5_hashctx);
|
||||
if((*md5params->md5_init_func)(ctxt->md5_hashctx)) {
|
||||
free(ctxt->md5_hashctx);
|
||||
free(ctxt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,7 +25,6 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "mime.h"
|
||||
#include "non-ascii.h"
|
||||
#include "warnless.h"
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -315,7 +314,7 @@ static char *escape_string(struct Curl_easy *data,
|
||||
|
||||
Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH);
|
||||
|
||||
for(result = Curl_dyn_add(&db, ""); !result && *src; src++) {
|
||||
for(result = Curl_dyn_addn(&db, STRCONST("")); !result && *src; src++) {
|
||||
for(p = table; *p && **p != *src; p++)
|
||||
;
|
||||
|
||||
@@ -340,9 +339,9 @@ static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len)
|
||||
}
|
||||
|
||||
/* Get a header from an slist. */
|
||||
static char *search_header(struct curl_slist *hdrlist, const char *hdr)
|
||||
static char *search_header(struct curl_slist *hdrlist,
|
||||
const char *hdr, size_t len)
|
||||
{
|
||||
size_t len = strlen(hdr);
|
||||
char *value = NULL;
|
||||
|
||||
for(; !value && hdrlist; hdrlist = hdrlist->next)
|
||||
@@ -506,15 +505,6 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* This is now textual data, Convert character codes. */
|
||||
if(part->easy && cursize) {
|
||||
CURLcode result = Curl_convert_to_network(part->easy, buffer, cursize);
|
||||
if(result)
|
||||
return READ_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cursize;
|
||||
}
|
||||
|
||||
@@ -768,7 +758,7 @@ static void mime_file_free(void *ptr)
|
||||
static size_t readback_bytes(struct mime_state *state,
|
||||
char *buffer, size_t bufsize,
|
||||
const char *bytes, size_t numbytes,
|
||||
const char *trail)
|
||||
const char *trail, size_t traillen)
|
||||
{
|
||||
size_t sz;
|
||||
size_t offset = curlx_sotouz(state->offset);
|
||||
@@ -778,13 +768,11 @@ static size_t readback_bytes(struct mime_state *state,
|
||||
bytes += offset;
|
||||
}
|
||||
else {
|
||||
size_t tsz = strlen(trail);
|
||||
|
||||
sz = offset - numbytes;
|
||||
if(sz >= tsz)
|
||||
if(sz >= traillen)
|
||||
return 0;
|
||||
bytes = trail + sz;
|
||||
sz = tsz - sz;
|
||||
sz = traillen - sz;
|
||||
}
|
||||
|
||||
if(sz > bufsize)
|
||||
@@ -925,9 +913,6 @@ static size_t readback_part(curl_mimepart *part,
|
||||
char *buffer, size_t bufsize, bool *hasread)
|
||||
{
|
||||
size_t cursize = 0;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char *convbuf = buffer;
|
||||
#endif
|
||||
|
||||
/* Readback from part. */
|
||||
|
||||
@@ -956,26 +941,18 @@ static size_t readback_part(curl_mimepart *part,
|
||||
mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders);
|
||||
else {
|
||||
sz = readback_bytes(&part->state, buffer, bufsize,
|
||||
hdr->data, strlen(hdr->data), "\r\n");
|
||||
hdr->data, strlen(hdr->data), STRCONST("\r\n"));
|
||||
if(!sz)
|
||||
mimesetstate(&part->state, part->state.state, hdr->next);
|
||||
}
|
||||
break;
|
||||
case MIMESTATE_EOH:
|
||||
sz = readback_bytes(&part->state, buffer, bufsize, "\r\n", 2, "");
|
||||
sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"),
|
||||
STRCONST(""));
|
||||
if(!sz)
|
||||
mimesetstate(&part->state, MIMESTATE_BODY, NULL);
|
||||
break;
|
||||
case MIMESTATE_BODY:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(part->easy && convbuf < buffer) {
|
||||
CURLcode result = Curl_convert_to_network(part->easy, convbuf,
|
||||
buffer - convbuf);
|
||||
if(result)
|
||||
return READ_ERROR;
|
||||
convbuf = buffer;
|
||||
}
|
||||
#endif
|
||||
cleanup_encoder_state(&part->encstate);
|
||||
mimesetstate(&part->state, MIMESTATE_CONTENT, NULL);
|
||||
break;
|
||||
@@ -1012,16 +989,6 @@ static size_t readback_part(curl_mimepart *part,
|
||||
bufsize -= sz;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(part->easy && convbuf < buffer &&
|
||||
part->state.state < MIMESTATE_BODY) {
|
||||
CURLcode result = Curl_convert_to_network(part->easy, convbuf,
|
||||
buffer - convbuf);
|
||||
if(result)
|
||||
return READ_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cursize;
|
||||
}
|
||||
|
||||
@@ -1031,10 +998,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
{
|
||||
curl_mime *mime = (curl_mime *) instream;
|
||||
size_t cursize = 0;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char *convbuf = buffer;
|
||||
#endif
|
||||
|
||||
(void) size; /* Always 1. */
|
||||
|
||||
while(nitems) {
|
||||
@@ -1043,9 +1006,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
switch(mime->state.state) {
|
||||
case MIMESTATE_BEGIN:
|
||||
case MIMESTATE_BODY:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
convbuf = buffer;
|
||||
#endif
|
||||
mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
|
||||
/* The first boundary always follows the header termination empty line,
|
||||
so is always preceded by a CRLF. We can then spare 2 characters
|
||||
@@ -1053,23 +1013,19 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
mime->state.offset += 2;
|
||||
break;
|
||||
case MIMESTATE_BOUNDARY1:
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, "\r\n--", 4, "");
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"),
|
||||
STRCONST(""));
|
||||
if(!sz)
|
||||
mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part);
|
||||
break;
|
||||
case MIMESTATE_BOUNDARY2:
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
strlen(mime->boundary), part? "\r\n": "--\r\n");
|
||||
if(part)
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
MIME_BOUNDARY_LEN, STRCONST("\r\n"));
|
||||
else
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
MIME_BOUNDARY_LEN, STRCONST("--\r\n"));
|
||||
if(!sz) {
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(mime->easy && convbuf < buffer) {
|
||||
CURLcode result = Curl_convert_to_network(mime->easy, convbuf,
|
||||
buffer - convbuf);
|
||||
if(result)
|
||||
return READ_ERROR;
|
||||
convbuf = buffer;
|
||||
}
|
||||
#endif
|
||||
mimesetstate(&mime->state, MIMESTATE_CONTENT, part);
|
||||
}
|
||||
break;
|
||||
@@ -1086,9 +1042,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
case STOP_FILLING:
|
||||
return cursize? cursize: sz;
|
||||
case 0:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
convbuf = buffer;
|
||||
#endif
|
||||
mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart);
|
||||
break;
|
||||
}
|
||||
@@ -1105,16 +1058,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
nitems -= sz;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(mime->easy && convbuf < buffer &&
|
||||
mime->state.state <= MIMESTATE_CONTENT) {
|
||||
CURLcode result = Curl_convert_to_network(mime->easy, convbuf,
|
||||
buffer - convbuf);
|
||||
if(result)
|
||||
return READ_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cursize;
|
||||
}
|
||||
|
||||
@@ -1341,8 +1284,9 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
|
||||
mime->firstpart = NULL;
|
||||
mime->lastpart = NULL;
|
||||
|
||||
memset(mime->boundary, '-', 24);
|
||||
if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24],
|
||||
memset(mime->boundary, '-', MIME_BOUNDARY_DASHES);
|
||||
if(Curl_rand_hex(easy,
|
||||
(unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES],
|
||||
MIME_RAND_BOUNDARY_CHARS + 1)) {
|
||||
/* failed to get random separator, bail out */
|
||||
free(mime);
|
||||
@@ -1619,7 +1563,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part,
|
||||
root = root->parent->parent;
|
||||
if(subparts == root) {
|
||||
if(part->easy)
|
||||
failf(part->easy, "Can't add itself as a subpart!");
|
||||
failf(part->easy, "Can't add itself as a subpart");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
}
|
||||
@@ -1675,10 +1619,9 @@ CURLcode Curl_mime_rewind(curl_mimepart *part)
|
||||
|
||||
/* Compute header list size. */
|
||||
static size_t slist_size(struct curl_slist *s,
|
||||
size_t overhead, const char *skip)
|
||||
size_t overhead, const char *skip, size_t skiplen)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t skiplen = skip? strlen(skip): 0;
|
||||
|
||||
for(; s; s = s->next)
|
||||
if(!skip || !match_header(s, skip, skiplen))
|
||||
@@ -1696,7 +1639,7 @@ static curl_off_t multipart_size(curl_mime *mime)
|
||||
if(!mime)
|
||||
return 0; /* Not present -> empty. */
|
||||
|
||||
boundarysize = 4 + strlen(mime->boundary) + 2;
|
||||
boundarysize = 4 + MIME_BOUNDARY_LEN + 2;
|
||||
size = boundarysize; /* Final boundary - CRLF after headers. */
|
||||
|
||||
for(part = mime->firstpart; part; part = part->nextpart) {
|
||||
@@ -1727,8 +1670,8 @@ curl_off_t Curl_mime_size(curl_mimepart *part)
|
||||
|
||||
if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) {
|
||||
/* Compute total part size. */
|
||||
size += slist_size(part->curlheaders, 2, NULL);
|
||||
size += slist_size(part->userheaders, 2, "Content-Type");
|
||||
size += slist_size(part->curlheaders, 2, NULL, 0);
|
||||
size += slist_size(part->userheaders, 2, STRCONST("Content-Type"));
|
||||
size += 2; /* CRLF after headers. */
|
||||
}
|
||||
return size;
|
||||
@@ -1804,10 +1747,9 @@ const char *Curl_mime_contenttype(const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool content_type_match(const char *contenttype, const char *target)
|
||||
static bool content_type_match(const char *contenttype,
|
||||
const char *target, size_t len)
|
||||
{
|
||||
size_t len = strlen(target);
|
||||
|
||||
if(contenttype && strncasecompare(contenttype, target, len))
|
||||
switch(contenttype[len]) {
|
||||
case '\0':
|
||||
@@ -1843,7 +1785,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
/* Check if content type is specified. */
|
||||
customct = part->mimetype;
|
||||
if(!customct)
|
||||
customct = search_header(part->userheaders, "Content-Type");
|
||||
customct = search_header(part->userheaders, STRCONST("Content-Type"));
|
||||
if(customct)
|
||||
contenttype = customct;
|
||||
|
||||
@@ -1872,12 +1814,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
boundary = mime->boundary;
|
||||
}
|
||||
else if(contenttype && !customct &&
|
||||
content_type_match(contenttype, "text/plain"))
|
||||
content_type_match(contenttype, STRCONST("text/plain")))
|
||||
if(strategy == MIMESTRATEGY_MAIL || !part->filename)
|
||||
contenttype = NULL;
|
||||
|
||||
/* Issue content-disposition header only if not already set by caller. */
|
||||
if(!search_header(part->userheaders, "Content-Disposition")) {
|
||||
if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) {
|
||||
if(!disposition)
|
||||
if(part->filename || part->name ||
|
||||
(contenttype && !strncasecompare(contenttype, "multipart/", 10)))
|
||||
@@ -1924,7 +1866,8 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
}
|
||||
|
||||
/* Content-Transfer-Encoding header. */
|
||||
if(!search_header(part->userheaders, "Content-Transfer-Encoding")) {
|
||||
if(!search_header(part->userheaders,
|
||||
STRCONST("Content-Transfer-Encoding"))) {
|
||||
if(part->encoder)
|
||||
cte = part->encoder->name;
|
||||
else if(contenttype && strategy == MIMESTRATEGY_MAIL &&
|
||||
@@ -1948,7 +1891,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
curl_mimepart *subpart;
|
||||
|
||||
disposition = NULL;
|
||||
if(content_type_match(contenttype, "multipart/form-data"))
|
||||
if(content_type_match(contenttype, STRCONST("multipart/form-data")))
|
||||
disposition = "form-data";
|
||||
for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
|
||||
ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#define MIME_BOUNDARY_DASHES 24 /* leading boundary dashes */
|
||||
#define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */
|
||||
#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */
|
||||
#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */
|
||||
@@ -91,8 +92,8 @@ struct 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)
|
||||
/* Boundary string length. */
|
||||
#define MIME_BOUNDARY_LEN (MIME_BOUNDARY_DASHES + MIME_RAND_BOUNDARY_CHARS)
|
||||
|
||||
/* A mime multipart. */
|
||||
struct curl_mime {
|
||||
@@ -100,7 +101,7 @@ struct curl_mime {
|
||||
curl_mimepart *parent; /* Parent part. */
|
||||
curl_mimepart *firstpart; /* First part. */
|
||||
curl_mimepart *lastpart; /* Last part. */
|
||||
char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
|
||||
char boundary[MIME_BOUNDARY_LEN + 1]; /* The part boundary. */
|
||||
struct mime_state state; /* Current readback state. */
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1999 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1999 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -65,7 +65,6 @@
|
||||
*/
|
||||
|
||||
#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
|
||||
(defined(__WATCOMC__) && defined(__386__)) || \
|
||||
(defined(__POCC__) && defined(_MSC_VER)) || \
|
||||
(defined(_WIN32_WCE)) || \
|
||||
(defined(__MINGW32__)) || \
|
||||
@@ -830,6 +829,8 @@ static int dprintf_formatf(
|
||||
}
|
||||
else if(prec != -1)
|
||||
len = (size_t)prec;
|
||||
else if(*str == '\0')
|
||||
len = 0;
|
||||
else
|
||||
len = strlen(str);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2019, Björn Stenberg, <bjorn@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -60,6 +60,8 @@
|
||||
*/
|
||||
|
||||
static CURLcode mqtt_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode mqtt_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature);
|
||||
static CURLcode mqtt_doing(struct Curl_easy *data, bool *done);
|
||||
static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
@@ -74,7 +76,7 @@ const struct Curl_handler Curl_handler_mqtt = {
|
||||
"MQTT", /* scheme */
|
||||
mqtt_setup_conn, /* setup_connection */
|
||||
mqtt_do, /* do_it */
|
||||
ZERO_NULL, /* done */
|
||||
mqtt_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
@@ -344,7 +346,9 @@ end:
|
||||
static CURLcode mqtt_disconnect(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct MQTT *mq = data->req.p.mqtt;
|
||||
result = mqtt_send(data, (char *)"\xe0\x00", 2);
|
||||
Curl_safefree(mq->sendleftovers);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -384,8 +388,7 @@ static CURLcode mqtt_get_topic(struct Curl_easy *data,
|
||||
{
|
||||
char *path = data->state.up.path;
|
||||
if(strlen(path) > 1)
|
||||
return Curl_urldecode(data, path + 1, 0, topic, topiclen,
|
||||
REJECT_NADA);
|
||||
return Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA);
|
||||
failf(data, "No MQTT topic found. Forgot to URL encode it?");
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
@@ -692,6 +695,16 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct MQTT *mq = data->req.p.mqtt;
|
||||
(void)status;
|
||||
(void)premature;
|
||||
Curl_safefree(mq->sendleftovers);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -719,8 +732,14 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
case MQTT_FIRST:
|
||||
/* Read the initial byte only */
|
||||
result = Curl_read(data, sockfd, (char *)&mq->firstbyte, 1, &nread);
|
||||
if(!nread)
|
||||
if(result)
|
||||
break;
|
||||
else if(!nread) {
|
||||
failf(data, "Connection disconnected");
|
||||
*done = TRUE;
|
||||
result = CURLE_RECV_ERROR;
|
||||
break;
|
||||
}
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
|
||||
/* remember the first byte */
|
||||
mq->npacket = 0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -687,16 +687,10 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
#endif
|
||||
) || conn->bits.close
|
||||
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
|
||||
CURLcode res2;
|
||||
connclose(conn, "disconnecting");
|
||||
Curl_conncache_remove_conn(data, conn, FALSE);
|
||||
CONNCACHE_UNLOCK(data);
|
||||
res2 = Curl_disconnect(data, conn, premature);
|
||||
|
||||
/* If we had an error already, make sure we return that one. But
|
||||
if we got a new error, return that. */
|
||||
if(!result && res2)
|
||||
result = res2;
|
||||
Curl_disconnect(data, conn, premature);
|
||||
}
|
||||
else {
|
||||
char buffer[256];
|
||||
@@ -709,14 +703,15 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
|
||||
conn->host.dispname;
|
||||
/* create string before returning the connection */
|
||||
long connection_id = conn->connection_id;
|
||||
msnprintf(buffer, sizeof(buffer),
|
||||
"Connection #%ld to host %s left intact",
|
||||
conn->connection_id, host);
|
||||
connection_id, host);
|
||||
/* the connection is no longer in use by this transfer */
|
||||
CONNCACHE_UNLOCK(data);
|
||||
if(Curl_conncache_return_conn(data, conn)) {
|
||||
/* remember the most recently used connection */
|
||||
data->state.lastconnect_id = conn->connection_id;
|
||||
data->state.lastconnect_id = connection_id;
|
||||
infof(data, "%s", buffer);
|
||||
}
|
||||
else
|
||||
@@ -724,7 +719,6 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.buffer);
|
||||
Curl_free_request_state(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1759,6 +1753,10 @@ CURLcode Curl_preconnect(struct Curl_easy *data)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void set_in_callback(struct Curl_multi *multi, bool value)
|
||||
{
|
||||
multi->in_callback = value;
|
||||
}
|
||||
|
||||
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct curltime *nowp,
|
||||
@@ -1795,7 +1793,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
rc = CURLM_OK;
|
||||
|
||||
if(multi_ischanged(multi, TRUE)) {
|
||||
DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!"));
|
||||
DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
|
||||
process_pending_handles(multi); /* multiplexed */
|
||||
}
|
||||
|
||||
@@ -2169,8 +2167,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_posttransfer(data);
|
||||
drc = multi_done(data, result, FALSE);
|
||||
|
||||
/* When set to retry the connection, we must to go back to
|
||||
* the CONNECT state */
|
||||
/* When set to retry the connection, we must go back to the CONNECT
|
||||
* state */
|
||||
if(newurl) {
|
||||
if(!drc || (drc == CURLE_SEND_ERROR)) {
|
||||
follow = FOLLOW_RETRY;
|
||||
@@ -2382,7 +2380,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
CURLcode ret = Curl_retry_request(data, &newurl);
|
||||
|
||||
if(!ret) {
|
||||
infof(data, "Downgrades to HTTP/1.1!");
|
||||
infof(data, "Downgrades to HTTP/1.1");
|
||||
streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
|
||||
data->state.httpwant = CURL_HTTP_VERSION_1_1;
|
||||
/* clear the error message bit too as we ignore the one we got */
|
||||
@@ -2872,8 +2870,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
|
||||
continue;
|
||||
|
||||
if(multi->socket_cb) {
|
||||
set_in_callback(multi, TRUE);
|
||||
rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
|
||||
entry->socketp);
|
||||
set_in_callback(multi, FALSE);
|
||||
if(rc == -1) {
|
||||
multi->dead = TRUE;
|
||||
return CURLM_ABORTED_BY_CALLBACK;
|
||||
@@ -2914,8 +2914,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
|
||||
entry->readers--;
|
||||
if(!entry->users) {
|
||||
if(multi->socket_cb) {
|
||||
set_in_callback(multi, TRUE);
|
||||
rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
|
||||
multi->socket_userp, entry->socketp);
|
||||
set_in_callback(multi, FALSE);
|
||||
if(rc == -1) {
|
||||
multi->dead = TRUE;
|
||||
return CURLM_ABORTED_BY_CALLBACK;
|
||||
@@ -2969,9 +2971,12 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
|
||||
|
||||
if(entry) {
|
||||
int rc = 0;
|
||||
if(multi->socket_cb)
|
||||
if(multi->socket_cb) {
|
||||
set_in_callback(multi, TRUE);
|
||||
rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
|
||||
multi->socket_userp, entry->socketp);
|
||||
set_in_callback(multi, FALSE);
|
||||
}
|
||||
|
||||
/* now remove it from the socket hash */
|
||||
sh_delentry(entry, &multi->sockhash, s);
|
||||
@@ -3343,7 +3348,9 @@ CURLMcode Curl_update_timer(struct Curl_multi *multi)
|
||||
multi->timer_lastcall = none;
|
||||
/* there's no timeout now but there was one previously, tell the app to
|
||||
disable it */
|
||||
set_in_callback(multi, TRUE);
|
||||
rc = multi->timer_cb(multi, -1, multi->timer_userp);
|
||||
set_in_callback(multi, FALSE);
|
||||
if(rc == -1) {
|
||||
multi->dead = TRUE;
|
||||
return CURLM_ABORTED_BY_CALLBACK;
|
||||
@@ -3362,7 +3369,9 @@ CURLMcode Curl_update_timer(struct Curl_multi *multi)
|
||||
|
||||
multi->timer_lastcall = multi->timetree->key;
|
||||
|
||||
set_in_callback(multi, TRUE);
|
||||
rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
||||
set_in_callback(multi, FALSE);
|
||||
if(rc == -1) {
|
||||
multi->dead = TRUE;
|
||||
return CURLM_ABORTED_BY_CALLBACK;
|
||||
@@ -3561,9 +3570,6 @@ CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
|
||||
{
|
||||
struct Curl_sh_entry *there = NULL;
|
||||
|
||||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
there = sh_getentry(&multi->sockhash, s);
|
||||
|
||||
if(!there)
|
||||
|
||||
@@ -1,336 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, 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.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "non-ascii.h"
|
||||
#include "formdata.h"
|
||||
#include "sendf.h"
|
||||
#include "urldata.h"
|
||||
#include "multiif.h"
|
||||
#include "strerror.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
/* set default codesets for iconv */
|
||||
#ifndef CURL_ICONV_CODESET_OF_NETWORK
|
||||
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||
#endif
|
||||
#ifndef CURL_ICONV_CODESET_FOR_UTF8
|
||||
#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||
#endif
|
||||
#define ICONV_ERROR (size_t)-1
|
||||
#endif /* HAVE_ICONV */
|
||||
|
||||
/*
|
||||
* Curl_convert_clone() returns a malloced copy of the source string (if
|
||||
* returning CURLE_OK), with the data converted to network format.
|
||||
*/
|
||||
CURLcode Curl_convert_clone(struct Curl_easy *data,
|
||||
const char *indata,
|
||||
size_t insize,
|
||||
char **outbuf)
|
||||
{
|
||||
char *convbuf;
|
||||
CURLcode result;
|
||||
|
||||
convbuf = malloc(insize);
|
||||
if(!convbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(convbuf, indata, insize);
|
||||
result = Curl_convert_to_network(data, convbuf, insize);
|
||||
if(result) {
|
||||
free(convbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
*outbuf = convbuf; /* return the converted buffer */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_to_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It converts the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data && data->set.convtonetwork) {
|
||||
/* use translation callback */
|
||||
CURLcode result;
|
||||
Curl_set_in_callback(data, true);
|
||||
result = data->set.convtonetwork(buffer, length);
|
||||
Curl_set_in_callback(data, false);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
iconv_t tmpcd = (iconv_t) -1;
|
||||
iconv_t *cd = &tmpcd;
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
char ebuffer[STRERROR_LEN];
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data)
|
||||
cd = &data->outbound_cd;
|
||||
if(*cd == (iconv_t)-1) {
|
||||
*cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
if(*cd == (iconv_t)-1) {
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(*cd, &input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if(!data)
|
||||
iconv_close(tmpcd);
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"The Curl_convert_to_network iconv call failed with errno %i: %s",
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It converts the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data && data->set.convfromnetwork) {
|
||||
/* use translation callback */
|
||||
CURLcode result;
|
||||
Curl_set_in_callback(data, true);
|
||||
result = data->set.convfromnetwork(buffer, length);
|
||||
Curl_set_in_callback(data, false);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
iconv_t tmpcd = (iconv_t) -1;
|
||||
iconv_t *cd = &tmpcd;
|
||||
char *input_ptr, *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
char ebuffer[STRERROR_LEN];
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data)
|
||||
cd = &data->inbound_cd;
|
||||
if(*cd == (iconv_t)-1) {
|
||||
*cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
if(*cd == (iconv_t)-1) {
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(*cd, &input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if(!data)
|
||||
iconv_close(tmpcd);
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_convert_from_utf8() is an internal function for performing UTF-8
|
||||
* conversions on non-ASCII platforms.
|
||||
*/
|
||||
CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
{
|
||||
if(data && data->set.convfromutf8) {
|
||||
/* use translation callback */
|
||||
CURLcode result;
|
||||
Curl_set_in_callback(data, true);
|
||||
result = data->set.convfromutf8(buffer, length);
|
||||
Curl_set_in_callback(data, false);
|
||||
if(result) {
|
||||
failf(data,
|
||||
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
|
||||
(int)result, curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_ICONV
|
||||
/* do the translation ourselves */
|
||||
iconv_t tmpcd = (iconv_t) -1;
|
||||
iconv_t *cd = &tmpcd;
|
||||
char *input_ptr;
|
||||
char *output_ptr;
|
||||
size_t in_bytes, out_bytes, rc;
|
||||
char ebuffer[STRERROR_LEN];
|
||||
|
||||
/* open an iconv conversion descriptor if necessary */
|
||||
if(data)
|
||||
cd = &data->utf8_cd;
|
||||
if(*cd == (iconv_t)-1) {
|
||||
*cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
if(*cd == (iconv_t)-1) {
|
||||
failf(data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8,
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
/* call iconv */
|
||||
input_ptr = output_ptr = buffer;
|
||||
in_bytes = out_bytes = length;
|
||||
rc = iconv(*cd, &input_ptr, &in_bytes,
|
||||
&output_ptr, &out_bytes);
|
||||
if(!data)
|
||||
iconv_close(tmpcd);
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
if(output_ptr < input_ptr) {
|
||||
/* null terminate the now shorter output string */
|
||||
*output_ptr = 0x00;
|
||||
}
|
||||
#else
|
||||
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
|
||||
return CURLE_CONV_REQD;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init conversion stuff for a Curl_easy
|
||||
*/
|
||||
void Curl_convert_init(struct Curl_easy *data)
|
||||
{
|
||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||
/* conversion descriptors for iconv calls */
|
||||
data->outbound_cd = (iconv_t)-1;
|
||||
data->inbound_cd = (iconv_t)-1;
|
||||
data->utf8_cd = (iconv_t)-1;
|
||||
#else
|
||||
(void)data;
|
||||
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup conversion stuff for a Curl_easy
|
||||
*/
|
||||
void Curl_convert_setup(struct Curl_easy *data)
|
||||
{
|
||||
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close conversion stuff for a Curl_easy
|
||||
*/
|
||||
|
||||
void Curl_convert_close(struct Curl_easy *data)
|
||||
{
|
||||
#ifdef HAVE_ICONV
|
||||
/* close iconv conversion descriptors */
|
||||
if(data->inbound_cd != (iconv_t)-1) {
|
||||
iconv_close(data->inbound_cd);
|
||||
}
|
||||
if(data->outbound_cd != (iconv_t)-1) {
|
||||
iconv_close(data->outbound_cd);
|
||||
}
|
||||
if(data->utf8_cd != (iconv_t)-1) {
|
||||
iconv_close(data->utf8_cd);
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
#endif /* HAVE_ICONV */
|
||||
}
|
||||
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
@@ -1,61 +0,0 @@
|
||||
#ifndef HEADER_CURL_NON_ASCII_H
|
||||
#define HEADER_CURL_NON_ASCII_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
/*
|
||||
* Curl_convert_clone() returns a malloced copy of the source string (if
|
||||
* returning CURLE_OK), with the data converted to network format.
|
||||
*
|
||||
* If no conversion was needed *outbuf may be NULL.
|
||||
*/
|
||||
CURLcode Curl_convert_clone(struct Curl_easy *data,
|
||||
const char *indata,
|
||||
size_t insize,
|
||||
char **outbuf);
|
||||
|
||||
void Curl_convert_init(struct Curl_easy *data);
|
||||
void Curl_convert_setup(struct Curl_easy *data);
|
||||
void Curl_convert_close(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
char *buffer, size_t length);
|
||||
#else
|
||||
#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_init(x) Curl_nop_stmt
|
||||
#define Curl_convert_setup(x) Curl_nop_stmt
|
||||
#define Curl_convert_close(x) Curl_nop_stmt
|
||||
#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK)
|
||||
#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_NON_ASCII_H */
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
|
||||
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
|
||||
|
||||
/* BeOS */
|
||||
/* Orbis OS */
|
||||
long b = nonblock ? 1L : 0L;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef NETWARE /* Novell NetWare */
|
||||
|
||||
#ifdef __NOVELL_LIBC__
|
||||
/* For native LibC-based NLM we need to register as a real lib. */
|
||||
#include <library.h>
|
||||
#include <netware.h>
|
||||
#include <screen.h>
|
||||
#include <nks/thread.h>
|
||||
#include <nks/synch.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
struct libthreaddata {
|
||||
int _errno;
|
||||
void *twentybytes;
|
||||
};
|
||||
|
||||
struct libdata {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
void *tenbytes;
|
||||
NXKey_t perthreadkey; /* if -1, no key obtained... */
|
||||
NXMutex_t *lock;
|
||||
};
|
||||
|
||||
int gLibId = -1;
|
||||
void *gLibHandle = (void *) NULL;
|
||||
rtag_t gAllocTag = (rtag_t) NULL;
|
||||
NXMutex_t *gLibLock = (NXMutex_t *) NULL;
|
||||
|
||||
/* internal library function prototypes... */
|
||||
int DisposeLibraryData(void *);
|
||||
void DisposeThreadData(void *);
|
||||
int GetOrSetUpData(int id, struct libdata **data,
|
||||
struct libthreaddata **threaddata);
|
||||
|
||||
|
||||
int _NonAppStart(void *NLMHandle,
|
||||
void *errorScreen,
|
||||
const char *cmdLine,
|
||||
const char *loadDirPath,
|
||||
size_t uninitializedDataLength,
|
||||
void *NLMFileHandle,
|
||||
int (*readRoutineP)(int conn,
|
||||
void *fileHandle, size_t offset,
|
||||
size_t nbytes,
|
||||
size_t *bytesRead,
|
||||
void *buffer),
|
||||
size_t customDataOffset,
|
||||
size_t customDataSize,
|
||||
int messageCount,
|
||||
const char **messages)
|
||||
{
|
||||
NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma unused(cmdLine)
|
||||
#pragma unused(loadDirPath)
|
||||
#pragma unused(uninitializedDataLength)
|
||||
#pragma unused(NLMFileHandle)
|
||||
#pragma unused(readRoutineP)
|
||||
#pragma unused(customDataOffset)
|
||||
#pragma unused(customDataSize)
|
||||
#pragma unused(messageCount)
|
||||
#pragma unused(messages)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here we process our command line, post errors (to the error screen),
|
||||
* perform initializations and anything else we need to do before being able
|
||||
* to accept calls into us. If we succeed, we return non-zero and the NetWare
|
||||
* Loader will leave us up, otherwise we fail to load and get dumped.
|
||||
*/
|
||||
gAllocTag = AllocateResourceTag(NLMHandle,
|
||||
"<library-name> memory allocations",
|
||||
AllocSignature);
|
||||
|
||||
if(!gAllocTag) {
|
||||
OutputToScreen(errorScreen, "Unable to allocate resource tag for "
|
||||
"library memory allocations.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gLibId = register_library(DisposeLibraryData);
|
||||
|
||||
if(gLibId < -1) {
|
||||
OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gLibHandle = NLMHandle;
|
||||
|
||||
gLibLock = NXMutexAlloc(0, 0, &liblock);
|
||||
|
||||
if(!gLibLock) {
|
||||
OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we clean up any resources we allocated. Resource tags is a big part
|
||||
* of what we created, but NetWare doesn't ask us to free those.
|
||||
*/
|
||||
void _NonAppStop(void)
|
||||
{
|
||||
(void) unregister_library(gLibId);
|
||||
NXMutexFree(gLibLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function cannot be the first in the file for if the file is linked
|
||||
* first, then the check-unload function's offset will be nlmname.nlm+0
|
||||
* which is how to tell that there isn't one. When the check function is
|
||||
* first in the linked objects, it is ambiguous. For this reason, we will
|
||||
* put it inside this file after the stop function.
|
||||
*
|
||||
* Here we check to see if it's alright to ourselves to be unloaded. If not,
|
||||
* we return a non-zero value. Right now, there isn't any reason not to allow
|
||||
* it.
|
||||
*/
|
||||
int _NonAppCheckUnload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetOrSetUpData(int id, struct libdata **appData,
|
||||
struct libthreaddata **threadData)
|
||||
{
|
||||
int err;
|
||||
struct libdata *app_data;
|
||||
struct libthreaddata *thread_data;
|
||||
NXKey_t key;
|
||||
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
|
||||
|
||||
err = 0;
|
||||
thread_data = (struct libthreaddata_t *) NULL;
|
||||
|
||||
/*
|
||||
* Attempt to get our data for the application calling us. This is where we
|
||||
* store whatever application-specific information we need to carry in
|
||||
* support of calling applications.
|
||||
*/
|
||||
app_data = (struct libdata *) get_app_data(id);
|
||||
|
||||
if(!app_data) {
|
||||
/*
|
||||
* This application hasn't called us before; set up application AND
|
||||
* per-thread data. Of course, just in case a thread from this same
|
||||
* application is calling us simultaneously, we better lock our application
|
||||
* data-creation mutex. We also need to recheck for data after we acquire
|
||||
* the lock because WE might be that other thread that was too late to
|
||||
* create the data and the first thread in will have created it.
|
||||
*/
|
||||
NXLock(gLibLock);
|
||||
|
||||
app_data = (struct libdata *) get_app_data(id);
|
||||
if(!app_data) {
|
||||
app_data = calloc(1, sizeof(struct libdata));
|
||||
|
||||
if(app_data) {
|
||||
app_data->tenbytes = malloc(10);
|
||||
app_data->lock = NXMutexAlloc(0, 0, &liblock);
|
||||
|
||||
if(!app_data->tenbytes || !app_data->lock) {
|
||||
if(app_data->lock)
|
||||
NXMutexFree(app_data->lock);
|
||||
free(app_data->tenbytes);
|
||||
free(app_data);
|
||||
app_data = (libdata_t *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
if(app_data) {
|
||||
/*
|
||||
* Here we burn in the application data that we were trying to get
|
||||
* by calling get_app_data(). Next time we call the first function,
|
||||
* we'll get this data we're just now setting. We also go on here to
|
||||
* establish the per-thread data for the calling thread, something
|
||||
* we'll have to do on each application thread the first time
|
||||
* it calls us.
|
||||
*/
|
||||
err = set_app_data(gLibId, app_data);
|
||||
|
||||
if(err) {
|
||||
if(app_data->lock)
|
||||
NXMutexFree(app_data->lock);
|
||||
free(app_data->tenbytes);
|
||||
free(app_data);
|
||||
app_data = (libdata_t *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
else {
|
||||
/* create key for thread-specific data... */
|
||||
err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
|
||||
|
||||
if(err) /* (no more keys left?) */
|
||||
key = -1;
|
||||
|
||||
app_data->perthreadkey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NXUnlock(gLibLock);
|
||||
}
|
||||
|
||||
if(app_data) {
|
||||
key = app_data->perthreadkey;
|
||||
|
||||
if(key != -1 /* couldn't create a key? no thread data */
|
||||
&& !(err = NXKeyGetValue(key, (void **) &thread_data))
|
||||
&& !thread_data) {
|
||||
/*
|
||||
* Allocate the per-thread data for the calling thread. Regardless of
|
||||
* whether there was already application data or not, this may be the
|
||||
* first call by a new thread. The fact that we allocation 20 bytes on
|
||||
* a pointer is not very important, this just helps to demonstrate that
|
||||
* we can have arbitrarily complex per-thread data.
|
||||
*/
|
||||
thread_data = malloc(sizeof(struct libthreaddata));
|
||||
|
||||
if(thread_data) {
|
||||
thread_data->_errno = 0;
|
||||
thread_data->twentybytes = malloc(20);
|
||||
|
||||
if(!thread_data->twentybytes) {
|
||||
free(thread_data);
|
||||
thread_data = (struct libthreaddata *) NULL;
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
err = NXKeySetValue(key, thread_data);
|
||||
if(err) {
|
||||
free(thread_data->twentybytes);
|
||||
free(thread_data);
|
||||
thread_data = (struct libthreaddata *) NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(appData)
|
||||
*appData = app_data;
|
||||
|
||||
if(threadData)
|
||||
*threadData = thread_data;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int DisposeLibraryData(void *data)
|
||||
{
|
||||
if(data) {
|
||||
void *tenbytes = ((libdata_t *) data)->tenbytes;
|
||||
|
||||
free(tenbytes);
|
||||
free(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisposeThreadData(void *data)
|
||||
{
|
||||
if(data) {
|
||||
void *twentybytes = ((struct libthreaddata *) data)->twentybytes;
|
||||
|
||||
free(twentybytes);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* __NOVELL_LIBC__ */
|
||||
/* For native CLib-based NLM seems we can do a bit more simple. */
|
||||
#include <nwthread.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* initialize any globals here... */
|
||||
|
||||
/* do this if any global initializing was done
|
||||
SynchronizeStart();
|
||||
*/
|
||||
ExitThread(TSR_THREAD, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
#else /* NETWARE */
|
||||
|
||||
#ifdef __POCC__
|
||||
# pragma warn(disable:2024) /* Disable warning #2024: Empty input file */
|
||||
#endif
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -1,88 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef NETWARE /* Novell NetWare */
|
||||
|
||||
#ifdef __NOVELL_LIBC__
|
||||
/* For native LibC-based NLM we need to do nothing. */
|
||||
int netware_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* __NOVELL_LIBC__ */
|
||||
|
||||
/* For native CLib-based NLM we need to initialize the LONG namespace. */
|
||||
#include <nwnspace.h>
|
||||
#include <nwthread.h>
|
||||
#include <nwadv.h>
|
||||
/* Make the CLIB Ctx stuff link */
|
||||
#include <netdb.h>
|
||||
NETDB_DEFINE_CONTEXT
|
||||
/* Make the CLIB Inet stuff link */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
NETINET_DEFINE_CONTEXT
|
||||
|
||||
int netware_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int myHandle = GetNLMHandle();
|
||||
/* import UnAugmentAsterisk dynamically for NW4.x compatibility */
|
||||
void (*pUnAugmentAsterisk)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
/* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
|
||||
void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
if(pUnAugmentAsterisk)
|
||||
pUnAugmentAsterisk(1);
|
||||
if(pUseAccurateCaseForPaths)
|
||||
pUseAccurateCaseForPaths(1);
|
||||
UnimportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
/* set long name space */
|
||||
if((SetCurrentNameSpace(4) == 255)) {
|
||||
rc = 1;
|
||||
}
|
||||
if((SetTargetNameSpace(4) == 255)) {
|
||||
rc = rc + 2;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __init_environment(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __deinit_environment(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "curl_ldap.h"
|
||||
#include "curl_base64.h"
|
||||
#include "connect.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "strcase.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -76,6 +78,8 @@ typedef enum {
|
||||
OLDAP_SSL, /* Performing SSL handshake. */
|
||||
OLDAP_STARTTLS, /* STARTTLS request sent. */
|
||||
OLDAP_TLS, /* Performing TLS handshake. */
|
||||
OLDAP_MECHS, /* Get SASL authentication mechanisms. */
|
||||
OLDAP_SASL, /* SASL binding reply. */
|
||||
OLDAP_BIND, /* Simple bind reply. */
|
||||
OLDAP_BINDV2, /* Simple bind reply in protocol version 2. */
|
||||
OLDAP_LAST /* Never used */
|
||||
@@ -96,6 +100,13 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done);
|
||||
static CURLcode oldap_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
|
||||
static CURLcode oldap_perform_auth(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *initresp);
|
||||
static CURLcode oldap_continue_auth(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *resp);
|
||||
static CURLcode oldap_cancel_auth(struct Curl_easy *data, const char *mech);
|
||||
static CURLcode oldap_get_message(struct Curl_easy *data, struct bufref *out);
|
||||
|
||||
static Curl_recv oldap_recv;
|
||||
|
||||
/*
|
||||
@@ -154,10 +165,26 @@ const struct Curl_handler Curl_handler_ldaps = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* SASL parameters for the ldap protocol */
|
||||
static const struct SASLproto saslldap = {
|
||||
"ldap", /* The service name */
|
||||
oldap_perform_auth, /* Send authentication command */
|
||||
oldap_continue_auth, /* Send authentication continuation */
|
||||
oldap_cancel_auth, /* Send authentication cancellation */
|
||||
oldap_get_message, /* Get SASL response message */
|
||||
0, /* Maximum initial response length (no max) */
|
||||
LDAP_SASL_BIND_IN_PROGRESS, /* Code received when continuation is expected */
|
||||
LDAP_SUCCESS, /* Code to receive upon authentication success */
|
||||
SASL_AUTH_NONE, /* Default mechanisms */
|
||||
0 /* Configuration flags */
|
||||
};
|
||||
|
||||
struct ldapconninfo {
|
||||
struct SASL sasl; /* SASL-related parameters */
|
||||
LDAP *ld; /* Openldap connection handle. */
|
||||
Curl_recv *recv; /* For stacking SSL handler */
|
||||
Curl_send *send;
|
||||
struct berval *servercred; /* SASL data from server. */
|
||||
ldapstate state; /* Current machine state. */
|
||||
int proto; /* LDAP_PROTO_TCP/LDAP_PROTO_UDP/LDAP_PROTO_IPC */
|
||||
int msgid; /* Current message id. */
|
||||
@@ -184,6 +211,8 @@ static void state(struct Curl_easy *data, ldapstate newstate)
|
||||
"SSL",
|
||||
"STARTTLS",
|
||||
"TLS",
|
||||
"MECHS",
|
||||
"SASL",
|
||||
"BIND",
|
||||
"BINDV2",
|
||||
/* LAST */
|
||||
@@ -251,6 +280,37 @@ static CURLcode oldap_url_parse(struct Curl_easy *data, LDAPURLDesc **ludp)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse the login options. */
|
||||
static CURLcode oldap_parse_login_options(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
const char *ptr = conn->options;
|
||||
|
||||
while(!result && ptr && *ptr) {
|
||||
const char *key = ptr;
|
||||
const char *value;
|
||||
|
||||
while(*ptr && *ptr != '=')
|
||||
ptr++;
|
||||
|
||||
value = ptr + 1;
|
||||
|
||||
while(*ptr && *ptr != ';')
|
||||
ptr++;
|
||||
|
||||
if(checkprefix("AUTH=", key))
|
||||
result = Curl_sasl_parse_url_auth_option(&li->sasl, value, ptr - value);
|
||||
else
|
||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||
|
||||
if(*ptr == ';')
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return result == CURLE_URL_MALFORMAT? CURLE_SETOPT_OPTION_SYNTAX: result;
|
||||
}
|
||||
|
||||
static CURLcode oldap_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
@@ -271,14 +331,94 @@ static CURLcode oldap_setup_connection(struct Curl_easy *data,
|
||||
conn->proto.ldapc = li;
|
||||
connkeep(conn, "OpenLDAP default");
|
||||
|
||||
/* Initialize the SASL storage */
|
||||
Curl_sasl_init(&li->sasl, data, &saslldap);
|
||||
|
||||
/* Clear the TLS upgraded flag */
|
||||
conn->bits.tls_upgraded = FALSE;
|
||||
|
||||
result = oldap_parse_login_options(conn);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the SASL authentication challenge from the server credential buffer.
|
||||
*/
|
||||
static CURLcode oldap_get_message(struct Curl_easy *data, struct bufref *out)
|
||||
{
|
||||
struct berval *servercred = data->conn->proto.ldapc->servercred;
|
||||
|
||||
if(!servercred || !servercred->bv_val)
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
Curl_bufref_set(out, servercred->bv_val, servercred->bv_len, NULL);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends an initial SASL bind request to the server.
|
||||
*/
|
||||
static CURLcode oldap_perform_auth(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *initresp)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct berval cred;
|
||||
struct berval *pcred = &cred;
|
||||
int rc;
|
||||
|
||||
cred.bv_val = (char *) Curl_bufref_ptr(initresp);
|
||||
cred.bv_len = Curl_bufref_len(initresp);
|
||||
if(!cred.bv_val)
|
||||
pcred = NULL;
|
||||
rc = ldap_sasl_bind(li->ld, NULL, mech, pcred, NULL, NULL, &li->msgid);
|
||||
if(rc != LDAP_SUCCESS)
|
||||
result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends SASL continuation.
|
||||
*/
|
||||
static CURLcode oldap_continue_auth(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *resp)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct berval cred;
|
||||
struct berval *pcred = &cred;
|
||||
int rc;
|
||||
|
||||
cred.bv_val = (char *) Curl_bufref_ptr(resp);
|
||||
cred.bv_len = Curl_bufref_len(resp);
|
||||
if(!cred.bv_val)
|
||||
pcred = NULL;
|
||||
rc = ldap_sasl_bind(li->ld, NULL, mech, pcred, NULL, NULL, &li->msgid);
|
||||
if(rc != LDAP_SUCCESS)
|
||||
result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends SASL bind cancellation.
|
||||
*/
|
||||
static CURLcode oldap_cancel_auth(struct Curl_easy *data, const char *mech)
|
||||
{
|
||||
struct ldapconninfo *li = data->conn->proto.ldapc;
|
||||
CURLcode result = CURLE_OK;
|
||||
int rc = ldap_sasl_bind(li->ld, NULL, LDAP_SASL_NULL, NULL, NULL, NULL,
|
||||
&li->msgid);
|
||||
|
||||
(void)mech;
|
||||
if(rc != LDAP_SUCCESS)
|
||||
result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Starts LDAP simple bind. */
|
||||
static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
|
||||
{
|
||||
@@ -292,7 +432,7 @@ static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
|
||||
passwd.bv_val = NULL;
|
||||
passwd.bv_len = 0;
|
||||
|
||||
if(conn->bits.user_passwd) {
|
||||
if(data->state.aptr.user) {
|
||||
binddn = conn->user;
|
||||
passwd.bv_val = conn->passwd;
|
||||
passwd.bv_len = strlen(passwd.bv_val);
|
||||
@@ -304,11 +444,45 @@ static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
|
||||
state(data, newstate);
|
||||
else
|
||||
result = oldap_map_error(rc,
|
||||
conn->bits.user_passwd?
|
||||
data->state.aptr.user?
|
||||
CURLE_LOGIN_DENIED: CURLE_LDAP_CANNOT_BIND);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Query the supported SASL authentication mechanisms. */
|
||||
static CURLcode oldap_perform_mechs(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ldapconninfo *li = data->conn->proto.ldapc;
|
||||
int rc;
|
||||
static const char * const supportedSASLMechanisms[] = {
|
||||
"supportedSASLMechanisms",
|
||||
NULL
|
||||
};
|
||||
|
||||
rc = ldap_search_ext(li->ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
(char **) supportedSASLMechanisms, 0,
|
||||
NULL, NULL, NULL, 0, &li->msgid);
|
||||
if(rc == LDAP_SUCCESS)
|
||||
state(data, OLDAP_MECHS);
|
||||
else
|
||||
result = oldap_map_error(rc, CURLE_LOGIN_DENIED);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Starts SASL bind. */
|
||||
static CURLcode oldap_perform_sasl(struct Curl_easy *data)
|
||||
{
|
||||
saslprogress progress = SASL_IDLE;
|
||||
struct ldapconninfo *li = data->conn->proto.ldapc;
|
||||
CURLcode result = Curl_sasl_start(&li->sasl, data, TRUE, &progress);
|
||||
|
||||
state(data, OLDAP_SASL);
|
||||
if(!result && progress != SASL_INPROGRESS)
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
static Sockbuf_IO ldapsb_tls;
|
||||
|
||||
@@ -414,11 +588,106 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||
return oldap_perform_mechs(data);
|
||||
|
||||
/* Force bind even if anonymous bind is not needed in protocol version 3
|
||||
to detect missing version 3 support. */
|
||||
return oldap_perform_bind(data, OLDAP_BIND);
|
||||
}
|
||||
|
||||
/* Handle the supported SASL mechanisms query response */
|
||||
static CURLcode oldap_state_mechs_resp(struct Curl_easy *data,
|
||||
LDAPMessage *msg, int code)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
int rc;
|
||||
BerElement *ber = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct berval bv, *bvals;
|
||||
|
||||
switch(ldap_msgtype(msg)) {
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
/* Got a list of supported SASL mechanisms. */
|
||||
if(code != LDAP_SUCCESS && code != LDAP_NO_RESULTS_RETURNED)
|
||||
return CURLE_LOGIN_DENIED;
|
||||
|
||||
rc = ldap_get_dn_ber(li->ld, msg, &ber, &bv);
|
||||
if(rc < 0)
|
||||
return oldap_map_error(rc, CURLE_BAD_CONTENT_ENCODING);
|
||||
for(rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals);
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals)) {
|
||||
int i;
|
||||
|
||||
if(!bv.bv_val)
|
||||
break;
|
||||
|
||||
if(bvals) {
|
||||
for(i = 0; bvals[i].bv_val; i++) {
|
||||
size_t llen;
|
||||
unsigned short mech = Curl_sasl_decode_mech((char *) bvals[i].bv_val,
|
||||
bvals[i].bv_len, &llen);
|
||||
if(bvals[i].bv_len == llen)
|
||||
li->sasl.authmechs |= mech;
|
||||
}
|
||||
ber_memfree(bvals);
|
||||
}
|
||||
}
|
||||
ber_free(ber, 0);
|
||||
break;
|
||||
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
switch(code) {
|
||||
case LDAP_SIZELIMIT_EXCEEDED:
|
||||
infof(data, "Too many authentication mechanisms\n");
|
||||
/* FALLTHROUGH */
|
||||
case LDAP_SUCCESS:
|
||||
case LDAP_NO_RESULTS_RETURNED:
|
||||
if(Curl_sasl_can_authenticate(&li->sasl, data))
|
||||
result = oldap_perform_sasl(data);
|
||||
else
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
break;
|
||||
default:
|
||||
result = oldap_map_error(code, CURLE_LOGIN_DENIED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Handle a SASL bind response. */
|
||||
static CURLcode oldap_state_sasl_resp(struct Curl_easy *data,
|
||||
LDAPMessage *msg, int code)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
CURLcode result = CURLE_OK;
|
||||
saslprogress progress;
|
||||
int rc;
|
||||
|
||||
li->servercred = NULL;
|
||||
rc = ldap_parse_sasl_bind_result(li->ld, msg, &li->servercred, 0);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: sasl ldap_parse_result %s", ldap_err2string(rc));
|
||||
result = oldap_map_error(rc, CURLE_LOGIN_DENIED);
|
||||
}
|
||||
else {
|
||||
result = Curl_sasl_continue(&li->sasl, data, code, &progress);
|
||||
if(!result && progress != SASL_INPROGRESS)
|
||||
state(data, OLDAP_STOP);
|
||||
}
|
||||
|
||||
if(li->servercred)
|
||||
ber_bvfree(li->servercred);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Handle a simple bind response. */
|
||||
static CURLcode oldap_state_bind_resp(struct Curl_easy *data, LDAPMessage *msg,
|
||||
int code)
|
||||
@@ -459,12 +728,20 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
if(li->state != OLDAP_SSL && li->state != OLDAP_TLS) {
|
||||
/* Get response to last command. */
|
||||
rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, &tv, &msg);
|
||||
if(!rc)
|
||||
return CURLE_OK; /* Timed out. */
|
||||
if(rc < 0) {
|
||||
failf(data, "LDAP local: connecting ldap_result %s",
|
||||
ldap_err2string(rc));
|
||||
return oldap_map_error(rc, CURLE_COULDNT_CONNECT);
|
||||
switch(rc) {
|
||||
case 0: /* Timed out. */
|
||||
return CURLE_OK;
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
case LDAP_RES_SEARCH_REFERENCE:
|
||||
break;
|
||||
default:
|
||||
li->msgid = 0; /* Nothing to abandon upon error. */
|
||||
if(rc < 0) {
|
||||
failf(data, "LDAP local: connecting ldap_result %s",
|
||||
ldap_err2string(rc));
|
||||
return oldap_map_error(rc, CURLE_COULDNT_CONNECT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get error code from message. */
|
||||
@@ -477,11 +754,11 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
/* If protocol version 3 is not supported, fallback to version 2. */
|
||||
if(code == LDAP_PROTOCOL_ERROR && li->state != OLDAP_BINDV2
|
||||
if(code == LDAP_PROTOCOL_ERROR && li->state != OLDAP_BINDV2 &&
|
||||
#ifdef USE_SSL
|
||||
&& (ssl_installed(conn) || data->set.use_ssl <= CURLUSESSL_TRY)
|
||||
(ssl_installed(conn) || data->set.use_ssl <= CURLUSESSL_TRY) &&
|
||||
#endif
|
||||
) {
|
||||
li->sasl.prefmech == SASL_AUTH_NONE) {
|
||||
static const int version = LDAP_VERSION2;
|
||||
|
||||
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
@@ -496,13 +773,19 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
#ifdef USE_SSL
|
||||
case OLDAP_SSL:
|
||||
result = oldap_ssl_connect(data, OLDAP_SSL);
|
||||
if(!result && ssl_installed(conn))
|
||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||
if(!result && ssl_installed(conn)) {
|
||||
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||
result = oldap_perform_mechs(data);
|
||||
else
|
||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||
}
|
||||
break;
|
||||
case OLDAP_STARTTLS:
|
||||
if(code != LDAP_SUCCESS) {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY)
|
||||
result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
|
||||
else if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||
result = oldap_perform_mechs(data);
|
||||
else
|
||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||
break;
|
||||
@@ -514,7 +797,9 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
|
||||
else if(ssl_installed(conn)) {
|
||||
conn->bits.tls_upgraded = TRUE;
|
||||
if(conn->bits.user_passwd)
|
||||
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||
result = oldap_perform_mechs(data);
|
||||
else if(data->state.aptr.user)
|
||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||
else {
|
||||
state(data, OLDAP_STOP); /* Version 3 supported: no bind required */
|
||||
@@ -524,6 +809,12 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OLDAP_MECHS:
|
||||
result = oldap_state_mechs_resp(data, msg, code);
|
||||
break;
|
||||
case OLDAP_SASL:
|
||||
result = oldap_state_sasl_resp(data, msg, code);
|
||||
break;
|
||||
case OLDAP_BIND:
|
||||
case OLDAP_BINDV2:
|
||||
result = oldap_state_bind_resp(data, msg, code);
|
||||
@@ -540,6 +831,10 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
if(*done)
|
||||
conn->recv[FIRSTSOCKET] = oldap_recv;
|
||||
|
||||
if(result && li->msgid) {
|
||||
ldap_abandon_ext(li->ld, li->msgid, NULL, NULL);
|
||||
li->msgid = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -549,6 +844,9 @@ static CURLcode oldap_disconnect(struct Curl_easy *data,
|
||||
{
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
(void) dead_connection;
|
||||
#ifndef USE_SSL
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
if(li) {
|
||||
if(li->ld) {
|
||||
@@ -562,6 +860,7 @@ static CURLcode oldap_disconnect(struct Curl_easy *data,
|
||||
ldap_unbind_ext(li->ld, NULL, NULL);
|
||||
li->ld = NULL;
|
||||
}
|
||||
Curl_sasl_cleanup(conn, li->sasl.authused);
|
||||
conn->proto.ldapc = NULL;
|
||||
free(li);
|
||||
}
|
||||
@@ -632,21 +931,21 @@ static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode client_write(struct Curl_easy *data, const char *prefix,
|
||||
const char *value, size_t len, const char *suffix)
|
||||
static CURLcode client_write(struct Curl_easy *data,
|
||||
const char *prefix, size_t plen,
|
||||
const char *value, size_t len,
|
||||
const char *suffix, size_t slen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t l;
|
||||
|
||||
if(prefix) {
|
||||
l = strlen(prefix);
|
||||
/* If we have a zero-length value and the prefix ends with a space
|
||||
separator, drop the latter. */
|
||||
if(!len && l && prefix[l - 1] == ' ')
|
||||
l--;
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) prefix, l);
|
||||
if(!len && plen && prefix[plen - 1] == ' ')
|
||||
plen--;
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) prefix, plen);
|
||||
if(!result)
|
||||
data->req.bytecount += l;
|
||||
data->req.bytecount += plen;
|
||||
}
|
||||
if(!result && value) {
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) value, len);
|
||||
@@ -654,10 +953,9 @@ static CURLcode client_write(struct Curl_easy *data, const char *prefix,
|
||||
data->req.bytecount += len;
|
||||
}
|
||||
if(!result && suffix) {
|
||||
l = strlen(suffix);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) suffix, l);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) suffix, slen);
|
||||
if(!result)
|
||||
data->req.bytecount += l;
|
||||
data->req.bytecount += slen;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -734,7 +1032,8 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
break;
|
||||
}
|
||||
|
||||
result = client_write(data, "DN: ", bv.bv_val, bv.bv_len, "\n");
|
||||
result = client_write(data, STRCONST("DN: "), bv.bv_val, bv.bv_len,
|
||||
STRCONST("\n"));
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@@ -747,7 +1046,8 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
break;
|
||||
|
||||
if(!bvals) {
|
||||
result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":\n");
|
||||
result = client_write(data, STRCONST("\t"), bv.bv_val, bv.bv_len,
|
||||
STRCONST(":\n"));
|
||||
if(result)
|
||||
break;
|
||||
continue;
|
||||
@@ -759,7 +1059,8 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
for(i = 0; bvals[i].bv_val != NULL; i++) {
|
||||
int binval = 0;
|
||||
|
||||
result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":");
|
||||
result = client_write(data, STRCONST("\t"), bv.bv_val, bv.bv_len,
|
||||
STRCONST(":"));
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@@ -784,15 +1085,17 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
|
||||
/* Binary value, encode to base64. */
|
||||
if(bvals[i].bv_len)
|
||||
result = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len,
|
||||
result = Curl_base64_encode(bvals[i].bv_val, bvals[i].bv_len,
|
||||
&val_b64, &val_b64_sz);
|
||||
if(!result)
|
||||
result = client_write(data, ": ", val_b64, val_b64_sz, "\n");
|
||||
result = client_write(data, STRCONST(": "), val_b64, val_b64_sz,
|
||||
STRCONST("\n"));
|
||||
free(val_b64);
|
||||
}
|
||||
else
|
||||
result = client_write(data, " ",
|
||||
bvals[i].bv_val, bvals[i].bv_len, "\n");
|
||||
result = client_write(data, STRCONST(" "),
|
||||
bvals[i].bv_val, bvals[i].bv_len,
|
||||
STRCONST("\n"));
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
@@ -800,7 +1103,7 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
ber_memfree(bvals);
|
||||
bvals = NULL;
|
||||
if(!result)
|
||||
result = client_write(data, "\n", NULL, 0, NULL);
|
||||
result = client_write(data, STRCONST("\n"), NULL, 0, NULL, 0);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
@@ -808,7 +1111,7 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
ber_free(ber, 0);
|
||||
|
||||
if(!result)
|
||||
result = client_write(data, "\n", NULL, 0, NULL);
|
||||
result = client_write(data, STRCONST("\n"), NULL, 0, NULL, 0);
|
||||
if(!result)
|
||||
result = CURLE_AGAIN;
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "speedcheck.h"
|
||||
#include "pingpong.h"
|
||||
#include "multiif.h"
|
||||
#include "non-ascii.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -199,11 +198,6 @@ CURLcode Curl_pp_vsendf(struct Curl_easy *data,
|
||||
s = Curl_dyn_ptr(&pp->sendbuf);
|
||||
Curl_pp_init(data, pp);
|
||||
|
||||
result = Curl_convert_to_network(data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
#endif
|
||||
@@ -299,7 +293,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
*/
|
||||
if((ptr + pp->cache_size) > (buf + data->set.buffer_size + 1)) {
|
||||
failf(data, "cached response data too big to handle");
|
||||
return CURLE_RECV_ERROR;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
memcpy(ptr, pp->cache, pp->cache_size);
|
||||
gotbytes = (ssize_t)pp->cache_size;
|
||||
@@ -324,11 +318,6 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
if(result == CURLE_AGAIN)
|
||||
return CURLE_OK; /* return */
|
||||
|
||||
if(!result && (gotbytes > 0))
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, ptr, gotbytes);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
|
||||
if(result)
|
||||
/* Set outer result variable to this error. */
|
||||
keepon = FALSE;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -401,7 +401,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
||||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!conn->bits.user_passwd) {
|
||||
if(!data->state.aptr.user) {
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
@@ -435,7 +435,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
||||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!conn->bits.user_passwd) {
|
||||
if(!data->state.aptr.user) {
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
@@ -545,7 +545,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
|
||||
|
||||
/* Check we have enough data to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
|
||||
if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) {
|
||||
state(data, POP3_STOP);
|
||||
return result;
|
||||
}
|
||||
@@ -571,7 +571,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
|
||||
result = pop3_perform_user(data, conn);
|
||||
else {
|
||||
/* Other mechanisms not supported */
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
infof(data, "No known authentication mechanisms supported");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -924,7 +924,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
|
||||
|
||||
if(pop3code != '+') {
|
||||
state(data, POP3_STOP);
|
||||
return CURLE_RECV_ERROR;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* This 'OK' line ends with a CR LF pair which is the two first bytes of the
|
||||
@@ -1423,7 +1423,7 @@ static CURLcode pop3_parse_url_path(struct Curl_easy *data)
|
||||
const char *path = &data->state.up.path[1]; /* skip leading path */
|
||||
|
||||
/* URL decode the path for the message ID */
|
||||
return Curl_urldecode(data, path, 0, &pop3->id, NULL, REJECT_CTRL);
|
||||
return Curl_urldecode(path, 0, &pop3->id, NULL, REJECT_CTRL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1440,7 +1440,7 @@ static CURLcode pop3_parse_custom_request(struct Curl_easy *data)
|
||||
|
||||
/* URL decode the custom request */
|
||||
if(custom)
|
||||
result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, REJECT_CTRL);
|
||||
result = Curl_urldecode(custom, 0, &pop3->custom, NULL, REJECT_CTRL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -31,6 +31,9 @@
|
||||
#ifdef USE_QUICHE
|
||||
#include "vquic/quiche.h"
|
||||
#endif
|
||||
#ifdef USE_MSH3
|
||||
#include "vquic/msh3.h"
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -87,7 +87,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
|
||||
|
||||
if(!seeded) {
|
||||
struct curltime now = Curl_now();
|
||||
infof(data, "WARNING: Using weak random seed");
|
||||
infof(data, "WARNING: using weak random seed");
|
||||
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
|
||||
randseed = randseed * 1103515245 + 12345;
|
||||
randseed = randseed * 1103515245 + 12345;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -219,7 +219,7 @@ static CURLcode rtsp_done(struct Curl_easy *data,
|
||||
|
||||
httpStatus = Curl_http_done(data, status, premature);
|
||||
|
||||
if(rtsp) {
|
||||
if(rtsp && !status && !httpStatus) {
|
||||
/* Check the sequence numbers */
|
||||
long CSeq_sent = rtsp->CSeq_sent;
|
||||
long CSeq_recv = rtsp->CSeq_recv;
|
||||
@@ -340,7 +340,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
/* Transport Header for SETUP requests */
|
||||
p_transport = Curl_checkheaders(data, "Transport");
|
||||
p_transport = Curl_checkheaders(data, STRCONST("Transport"));
|
||||
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
|
||||
/* New Transport: setting? */
|
||||
if(data->set.str[STRING_RTSP_TRANSPORT]) {
|
||||
@@ -364,11 +364,11 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
/* Accept Headers for DESCRIBE requests */
|
||||
if(rtspreq == RTSPREQ_DESCRIBE) {
|
||||
/* Accept Header */
|
||||
p_accept = Curl_checkheaders(data, "Accept")?
|
||||
p_accept = Curl_checkheaders(data, STRCONST("Accept"))?
|
||||
NULL:"Accept: application/sdp\r\n";
|
||||
|
||||
/* Accept-Encoding header */
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding") &&
|
||||
if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
data->state.aptr.accept_encoding =
|
||||
@@ -385,11 +385,12 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(data, "User-Agent") && data->state.aptr.uagent) {
|
||||
if(Curl_checkheaders(data, STRCONST("User-Agent")) &&
|
||||
data->state.aptr.uagent) {
|
||||
Curl_safefree(data->state.aptr.uagent);
|
||||
data->state.aptr.uagent = NULL;
|
||||
}
|
||||
else if(!Curl_checkheaders(data, "User-Agent") &&
|
||||
else if(!Curl_checkheaders(data, STRCONST("User-Agent")) &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
p_uagent = data->state.aptr.uagent;
|
||||
}
|
||||
@@ -405,7 +406,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
/* Referrer */
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->state.referer && !Curl_checkheaders(data, "Referer"))
|
||||
if(data->state.referer && !Curl_checkheaders(data, STRCONST("Referer")))
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer);
|
||||
else
|
||||
data->state.aptr.ref = NULL;
|
||||
@@ -422,7 +423,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
(rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
|
||||
|
||||
/* Check to see if there is a range set in the custom headers */
|
||||
if(!Curl_checkheaders(data, "Range") && data->state.range) {
|
||||
if(!Curl_checkheaders(data, STRCONST("Range")) && data->state.range) {
|
||||
Curl_safefree(data->state.aptr.rangeline);
|
||||
data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
|
||||
p_range = data->state.aptr.rangeline;
|
||||
@@ -432,11 +433,11 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
/*
|
||||
* Sanity check the custom headers
|
||||
*/
|
||||
if(Curl_checkheaders(data, "CSeq")) {
|
||||
if(Curl_checkheaders(data, STRCONST("CSeq"))) {
|
||||
failf(data, "CSeq cannot be set as a custom header.");
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
if(Curl_checkheaders(data, "Session")) {
|
||||
if(Curl_checkheaders(data, STRCONST("Session"))) {
|
||||
failf(data, "Session ID cannot be set as a custom header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
@@ -523,7 +524,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
if(putsize > 0 || postsize > 0) {
|
||||
/* As stated in the http comments, it is probably not wise to
|
||||
* actually set a custom Content-Length in the headers */
|
||||
if(!Curl_checkheaders(data, "Content-Length")) {
|
||||
if(!Curl_checkheaders(data, STRCONST("Content-Length"))) {
|
||||
result =
|
||||
Curl_dyn_addf(&req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||
@@ -534,18 +535,20 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
if(rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_addf(&req_buffer,
|
||||
"Content-Type: text/parameters\r\n");
|
||||
if(!Curl_checkheaders(data, STRCONST("Content-Type"))) {
|
||||
result = Curl_dyn_addn(&req_buffer,
|
||||
STRCONST("Content-Type: "
|
||||
"text/parameters\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE) {
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_addf(&req_buffer,
|
||||
"Content-Type: application/sdp\r\n");
|
||||
if(!Curl_checkheaders(data, STRCONST("Content-Type"))) {
|
||||
result = Curl_dyn_addn(&req_buffer,
|
||||
STRCONST("Content-Type: "
|
||||
"application/sdp\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -563,7 +566,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
/* RTSP never allows chunked transfer */
|
||||
data->req.forbidchunk = TRUE;
|
||||
/* Finish the request buffer */
|
||||
result = Curl_dyn_add(&req_buffer, "\r\n");
|
||||
result = Curl_dyn_addn(&req_buffer, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -34,25 +34,16 @@
|
||||
#error "We can't compile without select() or poll() support."
|
||||
#endif
|
||||
|
||||
#if defined(__BEOS__)
|
||||
/* BeOS has FD_SET defined in socket.h */
|
||||
#include <socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
#include <dos.h> /* delay() */
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
#include <strings.h> /* bzero() in FD_SET */
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "timeval.h"
|
||||
#include "timediff.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/*
|
||||
@@ -102,26 +93,7 @@ int Curl_wait_ms(timediff_t timeout_ms)
|
||||
#else
|
||||
{
|
||||
struct timeval pending_tv;
|
||||
timediff_t tv_sec = timeout_ms / 1000;
|
||||
timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
|
||||
#ifdef HAVE_SUSECONDS_T
|
||||
#if TIMEDIFF_T_MAX > TIME_T_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > TIME_T_MAX)
|
||||
tv_sec = TIME_T_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (time_t)tv_sec;
|
||||
pending_tv.tv_usec = (suseconds_t)tv_usec;
|
||||
#else
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > INT_MAX)
|
||||
tv_sec = INT_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (int)tv_sec;
|
||||
pending_tv.tv_usec = (int)tv_usec;
|
||||
#endif
|
||||
r = select(0, NULL, NULL, NULL, &pending_tv);
|
||||
r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms));
|
||||
}
|
||||
#endif /* HAVE_POLL_FINE */
|
||||
#endif /* USE_WINSOCK */
|
||||
@@ -161,43 +133,7 @@ static int our_select(curl_socket_t maxfd, /* highest socket number */
|
||||
}
|
||||
#endif
|
||||
|
||||
ptimeout = &pending_tv;
|
||||
if(timeout_ms < 0) {
|
||||
ptimeout = NULL;
|
||||
}
|
||||
else if(timeout_ms > 0) {
|
||||
timediff_t tv_sec = timeout_ms / 1000;
|
||||
timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
|
||||
#ifdef HAVE_SUSECONDS_T
|
||||
#if TIMEDIFF_T_MAX > TIME_T_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > TIME_T_MAX)
|
||||
tv_sec = TIME_T_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (time_t)tv_sec;
|
||||
pending_tv.tv_usec = (suseconds_t)tv_usec;
|
||||
#elif defined(WIN32) /* maybe also others in the future */
|
||||
#if TIMEDIFF_T_MAX > LONG_MAX
|
||||
/* tv_sec overflow check on Windows there we know it is long */
|
||||
if(tv_sec > LONG_MAX)
|
||||
tv_sec = LONG_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (long)tv_sec;
|
||||
pending_tv.tv_usec = (long)tv_usec;
|
||||
#else
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > INT_MAX)
|
||||
tv_sec = INT_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (int)tv_sec;
|
||||
pending_tv.tv_usec = (int)tv_usec;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
pending_tv.tv_sec = 0;
|
||||
pending_tv.tv_usec = 0;
|
||||
}
|
||||
ptimeout = curlx_mstotv(&pending_tv, timeout_ms);
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* WinSock select() must not be called with an fd_set that contains zero
|
||||
@@ -450,23 +386,3 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef TPF
|
||||
/*
|
||||
* This is a replacement for select() on the TPF platform.
|
||||
* It is used whenever libcurl calls select().
|
||||
* The call below to tpf_process_signals() is required because
|
||||
* TPF's select calls are not signal interruptible.
|
||||
*
|
||||
* Return values are the same as select's.
|
||||
*/
|
||||
int tpf_select_libcurl(int maxfds, fd_set *reads, fd_set *writes,
|
||||
fd_set *excepts, struct timeval *tv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
|
||||
tpf_process_signals();
|
||||
return rc;
|
||||
}
|
||||
#endif /* TPF */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -83,22 +83,11 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
|
||||
int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms);
|
||||
int Curl_wait_ms(timediff_t timeout_ms);
|
||||
|
||||
#ifdef TPF
|
||||
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
|
||||
fd_set* excepts, struct timeval *tv);
|
||||
#endif
|
||||
|
||||
/* TPF sockets are not in range [0..FD_SETSIZE-1], which
|
||||
unfortunately makes it impossible for us to easily check if they're valid
|
||||
|
||||
/*
|
||||
With Winsock the valid range is [0..INVALID_SOCKET-1] according to
|
||||
https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2
|
||||
*/
|
||||
#if defined(TPF)
|
||||
#define VALID_SOCK(x) 1
|
||||
#define VERIFY_SOCK(x) Curl_nop_stmt
|
||||
#define FDSET_SOCK(x) 1
|
||||
#elif defined(USE_WINSOCK)
|
||||
#ifdef USE_WINSOCK
|
||||
#define VALID_SOCK(s) ((s) < INVALID_SOCKET)
|
||||
#define FDSET_SOCK(x) 1
|
||||
#define VERIFY_SOCK(x) do { \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -41,11 +41,11 @@
|
||||
#include "vssh/ssh.h"
|
||||
#include "easyif.h"
|
||||
#include "multiif.h"
|
||||
#include "non-ascii.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "strdup.h"
|
||||
#include "http2.h"
|
||||
#include "headers.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -566,7 +566,7 @@ static CURLcode chop_write(struct Curl_easy *data,
|
||||
/* Protocols that work without network cannot be paused. This is
|
||||
actually only FILE:// just now, and it can't pause since the
|
||||
transfer isn't done using the "normal" procedure. */
|
||||
failf(data, "Write callback asked for PAUSE when not supported!");
|
||||
failf(data, "Write callback asked for PAUSE when not supported");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
return pausewrite(data, type, ptr, len);
|
||||
@@ -581,21 +581,33 @@ static CURLcode chop_write(struct Curl_easy *data,
|
||||
len -= chunklen;
|
||||
}
|
||||
|
||||
/* HTTP header, but not status-line */
|
||||
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
(type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS) ) {
|
||||
CURLcode result =
|
||||
Curl_headers_push(data, optr,
|
||||
type & CLIENTWRITE_CONNECT ? CURLH_CONNECT :
|
||||
(type & CLIENTWRITE_1XX ? CURLH_1XX :
|
||||
(type & CLIENTWRITE_TRAILER ? CURLH_TRAILER :
|
||||
CURLH_HEADER)));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(writeheader) {
|
||||
size_t wrote;
|
||||
ptr = optr;
|
||||
len = olen;
|
||||
|
||||
Curl_set_in_callback(data, true);
|
||||
wrote = writeheader(ptr, 1, len, data->set.writeheader);
|
||||
wrote = writeheader(optr, 1, olen, data->set.writeheader);
|
||||
Curl_set_in_callback(data, false);
|
||||
|
||||
if(CURL_WRITEFUNC_PAUSE == wrote)
|
||||
/* here we pass in the HEADER bit only since if this was body as well
|
||||
then it was passed already and clearly that didn't trigger the
|
||||
pause, so this is saved for later with the HEADER bit only */
|
||||
return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
|
||||
return pausewrite(data, CLIENTWRITE_HEADER, optr, olen);
|
||||
|
||||
if(wrote != len) {
|
||||
if(wrote != olen) {
|
||||
failf(data, "Failed writing header");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
@@ -621,26 +633,19 @@ CURLcode Curl_client_write(struct Curl_easy *data,
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGASSERT(!(type & ~CLIENTWRITE_BOTH));
|
||||
|
||||
if(!len)
|
||||
return CURLE_OK;
|
||||
|
||||
/* FTP data may need conversion. */
|
||||
if((type & CLIENTWRITE_BODY) &&
|
||||
(conn->handler->protocol & PROTO_FAMILY_FTP) &&
|
||||
conn->proto.ftpc.transfertype == 'A') {
|
||||
/* convert from the network encoding */
|
||||
CURLcode result = Curl_convert_from_network(data, ptr, len);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
(conn->handler->protocol & PROTO_FAMILY_FTP) &&
|
||||
conn->proto.ftpc.transfertype == 'A') {
|
||||
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/* convert end-of-line markers */
|
||||
len = convert_lineends(data, ptr, len);
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
}
|
||||
}
|
||||
|
||||
return chop_write(data, type, ptr, len);
|
||||
}
|
||||
@@ -716,44 +721,6 @@ int Curl_debug(struct Curl_easy *data, curl_infotype type,
|
||||
if(data->set.verbose) {
|
||||
static const char s_infotype[CURLINFO_END][3] = {
|
||||
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char *buf = NULL;
|
||||
size_t conv_size = 0;
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_HEADER_OUT:
|
||||
buf = Curl_memdup(ptr, size);
|
||||
if(!buf)
|
||||
return 1;
|
||||
conv_size = size;
|
||||
|
||||
/* Special processing is needed for this block if it
|
||||
* contains both headers and data (separated by CRLFCRLF).
|
||||
* We want to convert just the headers, leaving the data as-is.
|
||||
*/
|
||||
if(size > 4) {
|
||||
size_t i;
|
||||
for(i = 0; i < size-4; i++) {
|
||||
if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
|
||||
/* convert everything through this CRLFCRLF but no further */
|
||||
conv_size = i + 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Curl_convert_from_network(data, buf, conv_size);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* we might as well continue even if it fails... */
|
||||
ptr = buf; /* switch pointer to use my buffer instead */
|
||||
break;
|
||||
default:
|
||||
/* leave everything else as-is */
|
||||
break;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(data->set.fdebug) {
|
||||
Curl_set_in_callback(data, true);
|
||||
rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
|
||||
@@ -766,20 +733,11 @@ int Curl_debug(struct Curl_easy *data, curl_infotype type,
|
||||
case CURLINFO_HEADER_IN:
|
||||
fwrite(s_infotype[type], 2, 1, data->set.err);
|
||||
fwrite(ptr, size, 1, data->set.err);
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(size != conv_size) {
|
||||
/* we had untranslated data so we need an explicit newline */
|
||||
fwrite("\n", 1, 1, data->set.err);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default: /* nada */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
free(buf);
|
||||
#endif
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -45,8 +45,12 @@ void Curl_failf(struct Curl_easy *, const char *fmt, ...);
|
||||
|
||||
#define failf Curl_failf
|
||||
|
||||
#define CLIENTWRITE_BODY (1<<0)
|
||||
#define CLIENTWRITE_HEADER (1<<1)
|
||||
#define CLIENTWRITE_BODY (1<<0)
|
||||
#define CLIENTWRITE_HEADER (1<<1)
|
||||
#define CLIENTWRITE_STATUS (1<<2) /* the first "header" is the status line */
|
||||
#define CLIENTWRITE_CONNECT (1<<3) /* a CONNECT response */
|
||||
#define CLIENTWRITE_1XX (1<<4) /* a 1xx response */
|
||||
#define CLIENTWRITE_TRAILER (1<<5) /* a trailer header */
|
||||
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
|
||||
|
||||
CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -62,19 +62,12 @@ CURLcode Curl_setstropt(char **charp, const char *s)
|
||||
Curl_safefree(*charp);
|
||||
|
||||
if(s) {
|
||||
char *str = strdup(s);
|
||||
if(strlen(s) > CURL_MAX_INPUT_LENGTH)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
if(str) {
|
||||
size_t len = strlen(str);
|
||||
if(len > CURL_MAX_INPUT_LENGTH) {
|
||||
free(str);
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
}
|
||||
if(!str)
|
||||
*charp = strdup(s);
|
||||
if(!*charp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
*charp = str;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -162,7 +155,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
char *argptr;
|
||||
CURLcode result = CURLE_OK;
|
||||
long arg;
|
||||
#ifdef ENABLE_IPV6
|
||||
unsigned long uarg;
|
||||
#endif
|
||||
curl_off_t bigsize;
|
||||
|
||||
switch(option) {
|
||||
@@ -895,7 +890,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
;
|
||||
else
|
||||
#endif
|
||||
#if !defined(USE_NGHTTP2) && !defined(USE_HYPER)
|
||||
#ifndef USE_HTTP2
|
||||
if(arg >= CURL_HTTP_VERSION_2)
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#else
|
||||
@@ -1650,24 +1645,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
*/
|
||||
data->set.seek_client = va_arg(param, void *);
|
||||
break;
|
||||
case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
|
||||
/*
|
||||
* "Convert from network encoding" callback
|
||||
*/
|
||||
data->set.convfromnetwork = va_arg(param, curl_conv_callback);
|
||||
break;
|
||||
case CURLOPT_CONV_TO_NETWORK_FUNCTION:
|
||||
/*
|
||||
* "Convert to network encoding" callback
|
||||
*/
|
||||
data->set.convtonetwork = va_arg(param, curl_conv_callback);
|
||||
break;
|
||||
case CURLOPT_CONV_FROM_UTF8_FUNCTION:
|
||||
/*
|
||||
* "Convert from UTF-8 encoding" callback
|
||||
*/
|
||||
data->set.convfromutf8 = va_arg(param, curl_conv_callback);
|
||||
break;
|
||||
case CURLOPT_IOCTLFUNCTION:
|
||||
/*
|
||||
* I/O control callback. Might be NULL.
|
||||
@@ -2558,6 +2535,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
case CURLOPT_ADDRESS_SCOPE:
|
||||
/*
|
||||
* Use this scope id when using IPv6
|
||||
@@ -2571,6 +2549,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
#endif
|
||||
data->set.scope_id = (unsigned int)uarg;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CURLOPT_PROTOCOLS:
|
||||
/* set the bitmask for the protocols that are allowed to be used for the
|
||||
@@ -2623,7 +2602,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
#endif
|
||||
|
||||
case CURLOPT_SASL_AUTHZID:
|
||||
/* Authorisation identity (identity to act as) */
|
||||
/* Authorization identity (identity to act as) */
|
||||
result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
|
||||
va_arg(param, char *));
|
||||
break;
|
||||
@@ -2769,30 +2748,30 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
break;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
case CURLOPT_PROXY_TLSAUTH_USERNAME:
|
||||
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
|
||||
va_arg(param, char *));
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
|
||||
!data->set.proxy_ssl.authtype)
|
||||
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case CURLOPT_TLSAUTH_PASSWORD:
|
||||
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
|
||||
va_arg(param, char *));
|
||||
if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
break;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
case CURLOPT_PROXY_TLSAUTH_PASSWORD:
|
||||
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
|
||||
va_arg(param, char *));
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
|
||||
!data->set.proxy_ssl.authtype)
|
||||
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case CURLOPT_TLSAUTH_TYPE:
|
||||
argptr = va_arg(param, char *);
|
||||
if(!argptr ||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
|
||||
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,7 @@
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090700fL)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
|
||||
#define USE_OPENSSL_SHA256
|
||||
#endif
|
||||
|
||||
@@ -69,8 +69,14 @@
|
||||
|
||||
#if defined(USE_OPENSSL_SHA256)
|
||||
|
||||
/* When OpenSSL is available we use the SHA256-function from OpenSSL */
|
||||
/* When OpenSSL or wolfSSL is available is available we use their
|
||||
* SHA256-functions.
|
||||
*/
|
||||
#if defined(USE_OPENSSL)
|
||||
#include <openssl/evp.h>
|
||||
#elif defined(USE_WOLFSSL)
|
||||
#include <wolfssl/openssl/evp.h>
|
||||
#endif
|
||||
|
||||
#include "curl_memory.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2016 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -262,7 +262,7 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
||||
(void) done;
|
||||
|
||||
/* Check we have a username and password to authenticate with */
|
||||
if(!conn->bits.user_passwd)
|
||||
if(!data->state.aptr.user)
|
||||
return CURLE_LOGIN_DENIED;
|
||||
|
||||
/* Initialize the connection state */
|
||||
@@ -299,6 +299,7 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
||||
static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *buf = smbc->recv_buf;
|
||||
ssize_t bytes_read;
|
||||
@@ -307,7 +308,7 @@ static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
|
||||
size_t len = MAX_MESSAGE_SIZE - smbc->got;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_read(data, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
|
||||
result = Curl_read(data, sockfd, buf + smbc->got, len, &bytes_read);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -377,11 +378,12 @@ static CURLcode smb_send(struct Curl_easy *data, ssize_t len,
|
||||
size_t upload_size)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_write(data, FIRSTSOCKET, data->state.ulbuf,
|
||||
result = Curl_write(data, sockfd, data->state.ulbuf,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -399,6 +401,7 @@ static CURLcode smb_send(struct Curl_easy *data, ssize_t len,
|
||||
static CURLcode smb_flush(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
ssize_t len = smbc->send_size - smbc->sent;
|
||||
@@ -407,7 +410,7 @@ static CURLcode smb_flush(struct Curl_easy *data)
|
||||
if(!smbc->send_size)
|
||||
return CURLE_OK;
|
||||
|
||||
result = Curl_write(data, FIRSTSOCKET,
|
||||
result = Curl_write(data, sockfd,
|
||||
data->state.ulbuf + smbc->sent,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
@@ -459,14 +462,10 @@ static CURLcode smb_send_setup(struct Curl_easy *data)
|
||||
if(byte_count > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(data, conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_mk_lm_hash(conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
|
||||
#ifdef USE_NTRESPONSES
|
||||
Curl_ntlm_core_mk_nt_hash(data, conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_mk_nt_hash(conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||
#else
|
||||
memset(nt, 0, sizeof(nt));
|
||||
#endif
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_SETUP_ANDX;
|
||||
@@ -989,7 +988,7 @@ static CURLcode smb_parse_url_path(struct Curl_easy *data,
|
||||
char *slash;
|
||||
|
||||
/* URL decode the path */
|
||||
CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL,
|
||||
CURLcode result = Curl_urldecode(data->state.up.path, 0, &path, NULL,
|
||||
REJECT_CTRL);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -492,7 +492,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
|
||||
/* Check we have enough data to authenticate with, and the
|
||||
server supports authentication, and end the connect phase if not */
|
||||
if(!smtpc->auth_supported ||
|
||||
!Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
|
||||
!Curl_sasl_can_authenticate(&smtpc->sasl, data)) {
|
||||
state(data, SMTP_STOP);
|
||||
return result;
|
||||
}
|
||||
@@ -505,7 +505,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
|
||||
state(data, SMTP_AUTH);
|
||||
else {
|
||||
/* Other mechanisms not supported */
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
infof(data, "No known authentication mechanisms supported");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -698,7 +698,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data)
|
||||
NULL, MIMESTRATEGY_MAIL);
|
||||
|
||||
if(!result)
|
||||
if(!Curl_checkheaders(data, "Mime-Version"))
|
||||
if(!Curl_checkheaders(data, STRCONST("Mime-Version")))
|
||||
result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
|
||||
"Mime-Version: 1.0");
|
||||
|
||||
@@ -1037,7 +1037,7 @@ static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
|
||||
if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
|
||||
(!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
|
||||
failf(data, "Command failed: %d", smtpcode);
|
||||
result = CURLE_RECV_ERROR;
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
else {
|
||||
/* Temporarily add the LF character back and send as body to the client */
|
||||
@@ -1182,7 +1182,7 @@ static CURLcode smtp_state_postdata_resp(struct Curl_easy *data,
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(smtpcode != 250)
|
||||
result = CURLE_RECV_ERROR;
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
/* End of DONE phase */
|
||||
state(data, SMTP_STOP);
|
||||
@@ -1724,8 +1724,7 @@ static CURLcode smtp_parse_url_path(struct Curl_easy *data)
|
||||
}
|
||||
|
||||
/* URL decode the path and use it as the domain in our EHLO */
|
||||
return Curl_urldecode(data, path, 0, &smtpc->domain, NULL,
|
||||
REJECT_CTRL);
|
||||
return Curl_urldecode(path, 0, &smtpc->domain, NULL, REJECT_CTRL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1742,7 +1741,7 @@ static CURLcode smtp_parse_custom_request(struct Curl_easy *data)
|
||||
|
||||
/* URL decode the custom request */
|
||||
if(custom)
|
||||
result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, REJECT_CTRL);
|
||||
result = Curl_urldecode(custom, 0, &smtp->custom, NULL, REJECT_CTRL);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1841,7 +1840,7 @@ CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
|
||||
|
||||
scratch = newscratch = malloc(2 * data->set.upload_buffer_size);
|
||||
if(!newscratch) {
|
||||
failf(data, "Failed to alloc scratch buffer!");
|
||||
failf(data, "Failed to alloc scratch buffer");
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
if(proxy_user) {
|
||||
size_t plen = strlen(proxy_user);
|
||||
if(plen >= (size_t)data->set.buffer_size - 8) {
|
||||
failf(data, "Too long SOCKS proxy user name, can't use!");
|
||||
failf(data, "Too long SOCKS proxy user name, can't use");
|
||||
return CURLPX_LONG_USER;
|
||||
}
|
||||
/* copy the proxy name WITH trailing zero */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -69,7 +69,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_name,
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
/*
|
||||
* This function handles the SOCKS5 GSS-API negotiation and initialisation
|
||||
* This function handles the SOCKS5 GSS-API negotiation and initialization
|
||||
*/
|
||||
CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
struct Curl_easy *data);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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,142 +28,25 @@
|
||||
|
||||
static char raw_tolower(char in);
|
||||
|
||||
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
|
||||
its behavior is altered by the current locale. */
|
||||
/* Portable, consistent toupper. Do not use toupper() because its behavior is
|
||||
altered by the current locale. */
|
||||
char Curl_raw_toupper(char in)
|
||||
{
|
||||
#if !defined(CURL_DOES_CONVERSIONS)
|
||||
if(in >= 'a' && in <= 'z')
|
||||
return (char)('A' + in - 'a');
|
||||
#else
|
||||
switch(in) {
|
||||
case 'a':
|
||||
return 'A';
|
||||
case 'b':
|
||||
return 'B';
|
||||
case 'c':
|
||||
return 'C';
|
||||
case 'd':
|
||||
return 'D';
|
||||
case 'e':
|
||||
return 'E';
|
||||
case 'f':
|
||||
return 'F';
|
||||
case 'g':
|
||||
return 'G';
|
||||
case 'h':
|
||||
return 'H';
|
||||
case 'i':
|
||||
return 'I';
|
||||
case 'j':
|
||||
return 'J';
|
||||
case 'k':
|
||||
return 'K';
|
||||
case 'l':
|
||||
return 'L';
|
||||
case 'm':
|
||||
return 'M';
|
||||
case 'n':
|
||||
return 'N';
|
||||
case 'o':
|
||||
return 'O';
|
||||
case 'p':
|
||||
return 'P';
|
||||
case 'q':
|
||||
return 'Q';
|
||||
case 'r':
|
||||
return 'R';
|
||||
case 's':
|
||||
return 'S';
|
||||
case 't':
|
||||
return 'T';
|
||||
case 'u':
|
||||
return 'U';
|
||||
case 'v':
|
||||
return 'V';
|
||||
case 'w':
|
||||
return 'W';
|
||||
case 'x':
|
||||
return 'X';
|
||||
case 'y':
|
||||
return 'Y';
|
||||
case 'z':
|
||||
return 'Z';
|
||||
}
|
||||
#endif
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
|
||||
its behavior is altered by the current locale. */
|
||||
/* Portable, consistent tolower. Do not use tolower() because its behavior is
|
||||
altered by the current locale. */
|
||||
static char raw_tolower(char in)
|
||||
{
|
||||
#if !defined(CURL_DOES_CONVERSIONS)
|
||||
if(in >= 'A' && in <= 'Z')
|
||||
return (char)('a' + in - 'A');
|
||||
#else
|
||||
switch(in) {
|
||||
case 'A':
|
||||
return 'a';
|
||||
case 'B':
|
||||
return 'b';
|
||||
case 'C':
|
||||
return 'c';
|
||||
case 'D':
|
||||
return 'd';
|
||||
case 'E':
|
||||
return 'e';
|
||||
case 'F':
|
||||
return 'f';
|
||||
case 'G':
|
||||
return 'g';
|
||||
case 'H':
|
||||
return 'h';
|
||||
case 'I':
|
||||
return 'i';
|
||||
case 'J':
|
||||
return 'j';
|
||||
case 'K':
|
||||
return 'k';
|
||||
case 'L':
|
||||
return 'l';
|
||||
case 'M':
|
||||
return 'm';
|
||||
case 'N':
|
||||
return 'n';
|
||||
case 'O':
|
||||
return 'o';
|
||||
case 'P':
|
||||
return 'p';
|
||||
case 'Q':
|
||||
return 'q';
|
||||
case 'R':
|
||||
return 'r';
|
||||
case 'S':
|
||||
return 's';
|
||||
case 'T':
|
||||
return 't';
|
||||
case 'U':
|
||||
return 'u';
|
||||
case 'V':
|
||||
return 'v';
|
||||
case 'W':
|
||||
return 'w';
|
||||
case 'X':
|
||||
return 'x';
|
||||
case 'Y':
|
||||
return 'y';
|
||||
case 'Z':
|
||||
return 'z';
|
||||
}
|
||||
#endif
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
|
||||
* meant to be locale independent and only compare strings we know are safe
|
||||
@@ -171,9 +54,6 @@ static char raw_tolower(char in)
|
||||
* https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some
|
||||
* further explanation to why this function is necessary.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
|
||||
@@ -251,6 +131,16 @@ void Curl_strntolower(char *dest, const char *src, size_t n)
|
||||
} while(*src++ && --n);
|
||||
}
|
||||
|
||||
/* Compare case-sensitive NUL-terminated strings, taking care of possible
|
||||
* null pointers. Return true if arguments match.
|
||||
*/
|
||||
bool Curl_safecmp(char *a, char *b)
|
||||
{
|
||||
if(a && b)
|
||||
return !strcmp(a, b);
|
||||
return !a && !b;
|
||||
}
|
||||
|
||||
/* --- public functions --- */
|
||||
|
||||
int curl_strequal(const char *first, const char *second)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -28,8 +28,9 @@
|
||||
* Only "raw" case insensitive strings. This is meant to be locale independent
|
||||
* and only compare strings we know are safe for this.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
* The function is capable of comparing a-z case insensitively.
|
||||
*
|
||||
* Result is 1 if text matches and 0 if not.
|
||||
*/
|
||||
|
||||
#define strcasecompare(a,b) Curl_strcasecompare(a,b)
|
||||
@@ -42,10 +43,12 @@ int Curl_strncasecompare(const char *first, const char *second, size_t max);
|
||||
char Curl_raw_toupper(char in);
|
||||
|
||||
/* checkprefix() is a shorter version of the above, used when the first
|
||||
argument is zero-byte terminated */
|
||||
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
|
||||
argument is the string literal */
|
||||
#define checkprefix(a,b) curl_strnequal(b, STRCONST(a))
|
||||
|
||||
void Curl_strntoupper(char *dest, const char *src, size_t n);
|
||||
void Curl_strntolower(char *dest, const char *src, size_t n);
|
||||
|
||||
bool Curl_safecmp(char *a, char *b);
|
||||
|
||||
#endif /* HEADER_CURL_STRCASE_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2004 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2004 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,12 +24,9 @@
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
# if (!defined(HAVE_POSIX_STRERROR_R) && \
|
||||
!defined(HAVE_GLIBC_STRERROR_R) && \
|
||||
!defined(HAVE_VXWORKS_STRERROR_R)) || \
|
||||
(defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
|
||||
(defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
|
||||
!defined(HAVE_GLIBC_STRERROR_R)) || \
|
||||
(defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
|
||||
# error "strerror_r MUST be either POSIX, glibc or vxworks-style"
|
||||
# error "strerror_r MUST be either POSIX, glibc style"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -224,9 +221,6 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_BAD_CONTENT_ENCODING:
|
||||
return "Unrecognized or bad HTTP Content or Transfer-Encoding";
|
||||
|
||||
case CURLE_LDAP_INVALID_URL:
|
||||
return "Invalid LDAP URL";
|
||||
|
||||
case CURLE_FILESIZE_EXCEEDED:
|
||||
return "Maximum file size exceeded";
|
||||
|
||||
@@ -272,9 +266,6 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_CONV_FAILED:
|
||||
return "Conversion failed";
|
||||
|
||||
case CURLE_CONV_REQD:
|
||||
return "Caller must register CURLOPT_CONV_ callback options";
|
||||
|
||||
case CURLE_REMOTE_FILE_NOT_FOUND:
|
||||
return "Remote file not found";
|
||||
|
||||
@@ -337,6 +328,8 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_OBSOLETE50:
|
||||
case CURLE_OBSOLETE51:
|
||||
case CURLE_OBSOLETE57:
|
||||
case CURLE_OBSOLETE62:
|
||||
case CURLE_OBSOLETE76:
|
||||
case CURL_LAST:
|
||||
break;
|
||||
}
|
||||
@@ -883,18 +876,6 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
|
||||
else
|
||||
msnprintf(buf, max, "Unknown error %d", err);
|
||||
}
|
||||
#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
|
||||
/*
|
||||
* The vxworks-style strerror_r() does use the buffer we pass to the function.
|
||||
* The buffer size should be at least NAME_MAX (256)
|
||||
*/
|
||||
{
|
||||
char buffer[256];
|
||||
if(OK == strerror_r(err, buffer))
|
||||
strncpy(buf, buffer, max);
|
||||
else
|
||||
msnprintf(buf, max, "Unknown error %d", err);
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* !checksrc! disable STRERROR 1 */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -687,7 +687,7 @@ static void printsub(struct Curl_easy *data,
|
||||
infof(data, "%s", CURL_TELCMD(j));
|
||||
else
|
||||
infof(data, "%d", j);
|
||||
infof(data, ", not IAC SE!) ");
|
||||
infof(data, ", not IAC SE) ");
|
||||
}
|
||||
}
|
||||
length -= 2;
|
||||
@@ -781,7 +781,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data)
|
||||
|
||||
/* Add the user name as an environment variable if it
|
||||
was given on the command line */
|
||||
if(conn->bits.user_passwd) {
|
||||
if(data->state.aptr.user) {
|
||||
msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
|
||||
beg = curl_slist_append(tn->telnet_vars, option_arg);
|
||||
if(!beg) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -327,7 +327,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||
|
||||
infof(data, "got option=(%s) value=(%s)", option, value);
|
||||
|
||||
if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
|
||||
if(checkprefix(TFTP_OPTION_BLKSIZE, option)) {
|
||||
long blksize;
|
||||
|
||||
blksize = strtol(value, NULL, 10);
|
||||
@@ -359,7 +359,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||
infof(data, "%s (%d) %s (%d)", "blksize parsed from OACK",
|
||||
state->blksize, "requested", state->requested_blksize);
|
||||
}
|
||||
else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
|
||||
else if(checkprefix(TFTP_OPTION_TSIZE, option)) {
|
||||
long tsize = 0;
|
||||
|
||||
tsize = strtol(value, NULL, 10);
|
||||
@@ -463,7 +463,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
/* As RFC3617 describes the separator slash is not actually part of the
|
||||
file name so we skip the always-present first letter of the path
|
||||
string. */
|
||||
result = Curl_urldecode(data, &state->data->state.up.path[1], 0,
|
||||
result = Curl_urldecode(&state->data->state.up.path[1], 0,
|
||||
&filename, NULL, REJECT_ZERO);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
84
Utilities/cmcurl/lib/timediff.c
Normal file
84
Utilities/cmcurl/lib/timediff.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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 "timediff.h"
|
||||
|
||||
/*
|
||||
* Converts number of milliseconds into a timeval structure.
|
||||
*
|
||||
* Return values:
|
||||
* NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select)
|
||||
* tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select)
|
||||
* tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select)
|
||||
*/
|
||||
struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms)
|
||||
{
|
||||
if(!tv)
|
||||
return NULL;
|
||||
|
||||
if(ms < 0)
|
||||
return NULL;
|
||||
|
||||
if(ms > 0) {
|
||||
timediff_t tv_sec = ms / 1000;
|
||||
timediff_t tv_usec = (ms % 1000) * 1000; /* max=999999 */
|
||||
#ifdef HAVE_SUSECONDS_T
|
||||
#if TIMEDIFF_T_MAX > TIME_T_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > TIME_T_MAX)
|
||||
tv_sec = TIME_T_MAX;
|
||||
#endif
|
||||
tv->tv_sec = (time_t)tv_sec;
|
||||
tv->tv_usec = (suseconds_t)tv_usec;
|
||||
#elif defined(WIN32) /* maybe also others in the future */
|
||||
#if TIMEDIFF_T_MAX > LONG_MAX
|
||||
/* tv_sec overflow check on Windows there we know it is long */
|
||||
if(tv_sec > LONG_MAX)
|
||||
tv_sec = LONG_MAX;
|
||||
#endif
|
||||
tv->tv_sec = (long)tv_sec;
|
||||
tv->tv_usec = (long)tv_usec;
|
||||
#else
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > INT_MAX)
|
||||
tv_sec = INT_MAX;
|
||||
#endif
|
||||
tv->tv_sec = (int)tv_sec;
|
||||
tv->tv_usec = (int)tv_usec;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
tv->tv_sec = 0;
|
||||
tv->tv_usec = 0;
|
||||
}
|
||||
|
||||
return tv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts a timeval structure into number of milliseconds.
|
||||
*/
|
||||
timediff_t curlx_tvtoms(struct timeval *tv)
|
||||
{
|
||||
return (tv->tv_sec*1000) + (timediff_t)(((double)tv->tv_usec)/1000.0);
|
||||
}
|
||||
50
Utilities/cmcurl/lib/timediff.h
Normal file
50
Utilities/cmcurl/lib/timediff.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef HEADER_CURL_TIMEDIFF_H
|
||||
#define HEADER_CURL_TIMEDIFF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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.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"
|
||||
|
||||
/* Use a larger type even for 32 bit time_t systems so that we can keep
|
||||
microsecond accuracy in it */
|
||||
typedef curl_off_t timediff_t;
|
||||
#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
|
||||
|
||||
#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
|
||||
#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
|
||||
|
||||
/*
|
||||
* Converts number of milliseconds into a timeval structure.
|
||||
*
|
||||
* Return values:
|
||||
* NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select)
|
||||
* tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select)
|
||||
* tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select)
|
||||
*/
|
||||
struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms);
|
||||
|
||||
/*
|
||||
* Converts a timeval structure into number of milliseconds.
|
||||
*/
|
||||
timediff_t curlx_tvtoms(struct timeval *tv);
|
||||
|
||||
#endif /* HEADER_CURL_TIMEDIFF_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user