Merge branch 'upstream-curl' into update-curl

* upstream-curl:
  curl 2022-04-27 (1669b17d)
This commit is contained in:
Brad King
2022-04-28 15:20:13 -04:00
146 changed files with 4741 additions and 4576 deletions

View File

@@ -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

View 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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.

View File

@@ -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__) && \

View File

@@ -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

View 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 */

View File

@@ -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);

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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 =

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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'))

View File

@@ -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

View File

@@ -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 */

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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
*/
/*

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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
}
}

View File

@@ -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;
}

View File

@@ -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
View 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 */

View 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 */

View 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

View 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 */

View File

@@ -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;

View File

@@ -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

View File

@@ -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"

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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,

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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. */
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 { \

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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 ||

View File

@@ -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"

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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;

View 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);
}

View 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