mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-13 01:29:02 -05:00
curl 2021-09-14 (8e82f2a0)
Code extracted from:
https://github.com/curl/curl.git
at commit 8e82f2a04a238c54ba91e553e9a8452e6d405965 (curl-7_79_0).
This commit is contained in:
+6
-69
@@ -71,21 +71,15 @@ main ()
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tests for gethostbyaddr_r or gethostbyname_r */
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
|
||||
/* tests for gethostbyname_r */
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
# define _REENTRANT
|
||||
/* no idea whether _REENTRANT is always set, just invent a new flag */
|
||||
# define TEST_GETHOSTBYFOO_REENTRANT
|
||||
#endif
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(TEST_GETHOSTBYFOO_REENTRANT)
|
||||
@@ -98,18 +92,10 @@ int main(void)
|
||||
int type = 0;
|
||||
struct hostent h;
|
||||
int rc = 0;
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
struct hostent_data hdata;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
@@ -118,24 +104,6 @@ int main(void)
|
||||
struct hostent *hp;
|
||||
#endif
|
||||
|
||||
#ifndef gethostbyaddr_r
|
||||
(void)gethostbyaddr_r;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, &hdata);
|
||||
(void)rc;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
|
||||
hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
|
||||
(void)hp;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
|
||||
(void)rc;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, &hdata);
|
||||
@@ -214,37 +182,6 @@ if (sizeof (bool *) )
|
||||
#include <float.h>
|
||||
int main() { return 0; }
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT
|
||||
#define _REENTRANT
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)&inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
@@ -361,7 +298,7 @@ main ()
|
||||
|
||||
/* IoctlSocket source code */
|
||||
long flags = 0;
|
||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
||||
if(0 != IoctlSocket(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
|
||||
+83
-87
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# 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
|
||||
@@ -47,6 +47,40 @@ endif()
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
function(curl_cv_func_recv_run_test recv_retv recv_arg1 recv_arg2 recv_arg3 recv_arg4)
|
||||
unset(curl_cv_func_recv_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${recv_retv} ${signature_call_conv}
|
||||
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
|
||||
int main(void) {
|
||||
${recv_arg1} s=0;
|
||||
${recv_arg2} buf=0;
|
||||
${recv_arg3} len=0;
|
||||
${recv_arg4} flags=0;
|
||||
${recv_retv} res = recv(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_recv_test)
|
||||
message(STATUS
|
||||
"Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
|
||||
if(curl_cv_func_recv_test)
|
||||
set(curl_cv_func_recv_args
|
||||
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}" PARENT_SCOPE)
|
||||
set(RECV_TYPE_ARG1 "${recv_arg1}" PARENT_SCOPE)
|
||||
set(RECV_TYPE_ARG2 "${recv_arg2}" PARENT_SCOPE)
|
||||
set(RECV_TYPE_ARG3 "${recv_arg3}" PARENT_SCOPE)
|
||||
set(RECV_TYPE_ARG4 "${recv_arg4}" PARENT_SCOPE)
|
||||
set(RECV_TYPE_RETV "${recv_retv}" PARENT_SCOPE)
|
||||
set(HAVE_RECV 1 PARENT_SCOPE)
|
||||
set(curl_cv_func_recv_done 1 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
recv(0, 0, 0, 0);
|
||||
@@ -54,43 +88,16 @@ int main(void) {
|
||||
}" curl_cv_recv)
|
||||
if(curl_cv_recv)
|
||||
if(NOT DEFINED curl_cv_func_recv_args OR curl_cv_func_recv_args STREQUAL "unknown")
|
||||
if(APPLE)
|
||||
curl_cv_func_recv_run_test("ssize_t" "int" "void *" "size_t" "int")
|
||||
endif()
|
||||
foreach(recv_retv "int" "ssize_t" )
|
||||
foreach(recv_arg1 "SOCKET" "int" )
|
||||
foreach(recv_arg2 "char *" "void *" )
|
||||
foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int")
|
||||
foreach(recv_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_recv_done)
|
||||
unset(curl_cv_func_recv_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${recv_retv} ${signature_call_conv}
|
||||
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
|
||||
int main(void) {
|
||||
${recv_arg1} s=0;
|
||||
${recv_arg2} buf=0;
|
||||
${recv_arg3} len=0;
|
||||
${recv_arg4} flags=0;
|
||||
${recv_retv} res = recv(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_recv_test)
|
||||
message(STATUS
|
||||
"Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
|
||||
if(curl_cv_func_recv_test)
|
||||
set(curl_cv_func_recv_args
|
||||
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
|
||||
set(RECV_TYPE_ARG1 "${recv_arg1}")
|
||||
set(RECV_TYPE_ARG2 "${recv_arg2}")
|
||||
set(RECV_TYPE_ARG3 "${recv_arg3}")
|
||||
set(RECV_TYPE_ARG4 "${recv_arg4}")
|
||||
set(RECV_TYPE_RETV "${recv_retv}")
|
||||
set(HAVE_RECV 1)
|
||||
set(curl_cv_func_recv_done 1)
|
||||
endif()
|
||||
curl_cv_func_recv_run_test(${recv_retv} ${recv_arg1} ${recv_arg2} ${recv_arg3} ${recv_arg4})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
@@ -114,6 +121,42 @@ endif()
|
||||
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
|
||||
set(HAVE_RECV 1)
|
||||
|
||||
function(curl_cv_func_send_run_test send_retv send_arg1 send_arg2 send_arg3 send_arg4)
|
||||
unset(curl_cv_func_send_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${send_retv} ${signature_call_conv}
|
||||
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
|
||||
int main(void) {
|
||||
${send_arg1} s=0;
|
||||
${send_arg2} buf=0;
|
||||
${send_arg3} len=0;
|
||||
${send_arg4} flags=0;
|
||||
${send_retv} res = send(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_send_test)
|
||||
message(STATUS
|
||||
"Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
|
||||
if(curl_cv_func_send_test)
|
||||
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
|
||||
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
|
||||
set(curl_cv_func_send_args
|
||||
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}" PARENT_SCOPE)
|
||||
set(SEND_TYPE_ARG1 "${send_arg1}" PARENT_SCOPE)
|
||||
set(SEND_TYPE_ARG2 "${send_arg2}" PARENT_SCOPE)
|
||||
set(SEND_TYPE_ARG3 "${send_arg3}" PARENT_SCOPE)
|
||||
set(SEND_TYPE_ARG4 "${send_arg4}" PARENT_SCOPE)
|
||||
set(SEND_TYPE_RETV "${send_retv}" PARENT_SCOPE)
|
||||
set(HAVE_SEND 1 PARENT_SCOPE)
|
||||
set(curl_cv_func_send_done 1 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
send(0, 0, 0, 0);
|
||||
@@ -121,45 +164,16 @@ int main(void) {
|
||||
}" curl_cv_send)
|
||||
if(curl_cv_send)
|
||||
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
if(APPLE)
|
||||
curl_cv_func_send_run_test("ssize_t" "int" "const void *" "size_t" "int")
|
||||
endif()
|
||||
foreach(send_retv "int" "ssize_t" )
|
||||
foreach(send_arg1 "SOCKET" "int" "ssize_t" )
|
||||
foreach(send_arg2 "const char *" "const void *" "void *" "char *")
|
||||
foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int")
|
||||
foreach(send_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_send_done)
|
||||
unset(curl_cv_func_send_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
#ifdef WINSOCK_API_LINKAGE
|
||||
WINSOCK_API_LINKAGE
|
||||
#endif
|
||||
extern ${send_retv} ${signature_call_conv}
|
||||
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
|
||||
int main(void) {
|
||||
${send_arg1} s=0;
|
||||
${send_arg2} buf=0;
|
||||
${send_arg3} len=0;
|
||||
${send_arg4} flags=0;
|
||||
${send_retv} res = send(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_send_test)
|
||||
message(STATUS
|
||||
"Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
|
||||
if(curl_cv_func_send_test)
|
||||
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
|
||||
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
|
||||
set(curl_cv_func_send_args
|
||||
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
|
||||
set(SEND_TYPE_ARG1 "${send_arg1}")
|
||||
set(SEND_TYPE_ARG2 "${send_arg2}")
|
||||
set(SEND_TYPE_ARG3 "${send_arg3}")
|
||||
set(SEND_TYPE_ARG4 "${send_arg4}")
|
||||
set(SEND_TYPE_RETV "${send_retv}")
|
||||
set(HAVE_SEND 1)
|
||||
set(curl_cv_func_send_done 1)
|
||||
endif()
|
||||
curl_cv_func_send_run_test("${send_retv}" "${send_arg1}" "${send_arg2}" "${send_arg3}" "${send_arg4}")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
@@ -206,28 +220,6 @@ int main(void) {
|
||||
return 0;
|
||||
}" HAVE_STRUCT_TIMEVAL)
|
||||
|
||||
set(HAVE_SIG_ATOMIC_T 1)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SIGNAL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
|
||||
endif()
|
||||
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
|
||||
if(HAVE_SIZEOF_SIG_ATOMIC_T)
|
||||
check_c_source_compiles("
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
#endif
|
||||
int main(void) {
|
||||
static volatile sig_atomic_t dummy = 0;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_WINDOWS_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
|
||||
else()
|
||||
@@ -245,6 +237,9 @@ 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 cross-compilation...
|
||||
include(CheckCSourceRuns)
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
@@ -287,5 +282,6 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
}
|
||||
return 0;
|
||||
}" HAVE_POLL_FINE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ if(NOT UNIX)
|
||||
set(HAVE_PROCESS_H 1)
|
||||
set(HAVE_PWD_H 0)
|
||||
set(HAVE_SETJMP_H 1)
|
||||
set(HAVE_SGTTY_H 0)
|
||||
set(HAVE_SIGNAL_H 1)
|
||||
set(HAVE_SOCKIO_H 0)
|
||||
set(HAVE_STDINT_H 0)
|
||||
@@ -84,12 +83,8 @@ if(NOT UNIX)
|
||||
set(HAVE_STRCASECMP 0)
|
||||
set(HAVE_STRICMP 1)
|
||||
set(HAVE_STRCMPI 1)
|
||||
set(HAVE_GETHOSTBYADDR 1)
|
||||
set(HAVE_GETTIMEOFDAY 0)
|
||||
set(HAVE_INET_ADDR 1)
|
||||
set(HAVE_INET_NTOA 1)
|
||||
set(HAVE_INET_NTOA_R 0)
|
||||
set(HAVE_PERROR 1)
|
||||
set(HAVE_CLOSESOCKET 1)
|
||||
set(HAVE_SETVBUF 0)
|
||||
set(HAVE_SIGSETJMP 0)
|
||||
@@ -103,17 +98,10 @@ if(NOT UNIX)
|
||||
set(HAVE_RAND_STATUS 0)
|
||||
set(HAVE_GMTIME_R 0)
|
||||
set(HAVE_LOCALTIME_R 0)
|
||||
set(HAVE_GETHOSTBYADDR_R 0)
|
||||
set(HAVE_GETHOSTBYNAME_R 0)
|
||||
set(HAVE_SIGNAL_FUNC 1)
|
||||
set(HAVE_SIGNAL_MACRO 0)
|
||||
|
||||
set(HAVE_GETHOSTBYADDR_R_5 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_5 0)
|
||||
@@ -124,8 +112,6 @@ if(NOT UNIX)
|
||||
set(TIME_WITH_SYS_TIME 0)
|
||||
set(HAVE_O_NONBLOCK 0)
|
||||
set(HAVE_IN_ADDR_T 0)
|
||||
set(HAVE_INET_NTOA_R_DECL 0)
|
||||
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
||||
if(ENABLE_IPV6)
|
||||
set(HAVE_GETADDRINFO 1)
|
||||
else()
|
||||
|
||||
+93
-104
@@ -156,44 +156,78 @@ endif()
|
||||
|
||||
include(CurlSymbolHiding)
|
||||
|
||||
option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
|
||||
mark_as_advanced(HTTP_ONLY)
|
||||
option(CURL_DISABLE_FTP "disables FTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_FTP)
|
||||
option(CURL_DISABLE_LDAP "disables LDAP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LDAP)
|
||||
option(CURL_DISABLE_TELNET "disables Telnet" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TELNET)
|
||||
option(CURL_DISABLE_DICT "disables DICT" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_DICT)
|
||||
option(CURL_DISABLE_FILE "disables FILE" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_FILE)
|
||||
option(CURL_DISABLE_TFTP "disables TFTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TFTP)
|
||||
option(CURL_DISABLE_HTTP "disables HTTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_HTTP)
|
||||
|
||||
option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LDAPS)
|
||||
|
||||
option(CURL_DISABLE_RTSP "to disable RTSP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_RTSP)
|
||||
option(CURL_DISABLE_PROXY "to disable proxy" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_PROXY)
|
||||
option(CURL_DISABLE_POP3 "to disable POP3" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_POP3)
|
||||
option(CURL_DISABLE_IMAP "to disable IMAP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_IMAP)
|
||||
option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMTP)
|
||||
option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_GOPHER)
|
||||
option(CURL_DISABLE_MQTT "to disable MQTT" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_MQTT)
|
||||
|
||||
option(CURL_ENABLE_EXPORT_TARGET "to enable cmake export target" ON)
|
||||
mark_as_advanced(CURL_ENABLE_EXPORT_TARGET)
|
||||
|
||||
option(CURL_DISABLE_ALTSVC "disables alt-svc support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_ALTSVC)
|
||||
option(CURL_DISABLE_COOKIES "disables cookies support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_COOKIES)
|
||||
option(CURL_DISABLE_CRYPTO_AUTH "disables cryptographic authentication" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
|
||||
option(CURL_DISABLE_DICT "disables DICT" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_DICT)
|
||||
option(CURL_DISABLE_DOH "disables DNS-over-HTTPS" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_DOH)
|
||||
option(CURL_DISABLE_FILE "disables FILE" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_FILE)
|
||||
option(CURL_DISABLE_FTP "disables FTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_FTP)
|
||||
option(CURL_DISABLE_GETOPTIONS "disables curl_easy_options API for existing options to curl_easy_setopt" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_GETOPTIONS)
|
||||
option(CURL_DISABLE_GOPHER "disables Gopher" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_GOPHER)
|
||||
option(CURL_DISABLE_HSTS "disables HSTS support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_HSTS)
|
||||
option(CURL_DISABLE_HTTP "disables HTTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_HTTP)
|
||||
option(CURL_DISABLE_HTTP_AUTH "disables all HTTP authentication methods" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_HTTP_AUTH)
|
||||
option(CURL_DISABLE_IMAP "disables IMAP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_IMAP)
|
||||
option(CURL_DISABLE_LDAP "disables LDAP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LDAP)
|
||||
option(CURL_DISABLE_LDAPS "disables LDAPS" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LDAPS)
|
||||
option(CURL_DISABLE_LIBCURL_OPTION "disables --libcurl option from the curl tool" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION)
|
||||
option(CURL_DISABLE_MIME "disables MIME support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_MIME)
|
||||
option(CURL_DISABLE_MQTT "disables MQTT" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_MQTT)
|
||||
option(CURL_DISABLE_NETRC "disables netrc parser" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_NETRC)
|
||||
option(CURL_DISABLE_NTLM "disables NTLM support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_NTLM)
|
||||
option(CURL_DISABLE_PARSEDATE "disables date parsing" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_PARSEDATE)
|
||||
option(CURL_DISABLE_POP3 "disables POP3" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_POP3)
|
||||
option(CURL_DISABLE_PROGRESS_METER "disables built-in progress meter" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_PROGRESS_METER)
|
||||
option(CURL_DISABLE_PROXY "disables proxy support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_PROXY)
|
||||
option(CURL_DISABLE_RTSP "disables RTSP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_RTSP)
|
||||
option(CURL_DISABLE_SHUFFLE_DNS "disables shuffle DNS feature" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SHUFFLE_DNS)
|
||||
option(CURL_DISABLE_SMB "disables SMB" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMB)
|
||||
option(CURL_DISABLE_SMTP "disables SMTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMTP)
|
||||
option(CURL_DISABLE_SOCKETPAIR "disables use of socketpair for curl_multi_poll" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SOCKETPAIR)
|
||||
option(CURL_DISABLE_TELNET "disables Telnet" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TELNET)
|
||||
option(CURL_DISABLE_TFTP "disables TFTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TFTP)
|
||||
option(CURL_DISABLE_VERBOSE_STRINGS "disables verbose strings" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
|
||||
# Corresponds to HTTP_ONLY in lib/curl_setup.h
|
||||
option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
|
||||
mark_as_advanced(HTTP_ONLY)
|
||||
|
||||
if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_DICT ON)
|
||||
set(CURL_DISABLE_FILE ON)
|
||||
@@ -211,16 +245,6 @@ if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_TFTP ON)
|
||||
endif()
|
||||
|
||||
option(CURL_DISABLE_ALTSVC "to disable alt-svc support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_ALTSVC)
|
||||
option(CURL_DISABLE_HSTS "to disable HSTS support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_HSTS)
|
||||
option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_COOKIES)
|
||||
option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
|
||||
option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
|
||||
mark_as_advanced(ENABLE_IPV6)
|
||||
if(ENABLE_IPV6 AND NOT WIN32)
|
||||
@@ -370,28 +394,29 @@ if(CMAKE_USE_DARWINSSL)
|
||||
message(FATAL_ERROR "The cmake option CMAKE_USE_DARWINSSL was renamed to CMAKE_USE_SECTRANSP.")
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_SECTRANSP)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
|
||||
if(NOT COREFOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "CoreFoundation framework not found")
|
||||
endif()
|
||||
|
||||
find_library(SECURITY_FRAMEWORK "Security")
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_SECTRANSP ON)
|
||||
list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}")
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
find_library(SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration")
|
||||
if(NOT SYSTEMCONFIGURATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "SystemConfiguration framework not found")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS "${SYSTEMCONFIGURATION_FRAMEWORK}")
|
||||
|
||||
list(APPEND CURL_LIBS "-framework CoreFoundation" "-framework SystemConfiguration")
|
||||
|
||||
if(CMAKE_USE_SECTRANSP)
|
||||
find_library(SECURITY_FRAMEWORK "Security")
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_SECTRANSP ON)
|
||||
list(APPEND CURL_LIBS "-framework Security")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
@@ -713,15 +738,6 @@ if(CMAKE_USE_LIBSSH2)
|
||||
set(HAVE_LIBSSH2_H ON)
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
|
||||
|
||||
# now check for specific libssh2 symbols as they were added in different versions
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h")
|
||||
check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION)
|
||||
check_function_exists(libssh2_init HAVE_LIBSSH2_INIT)
|
||||
check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT)
|
||||
check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
|
||||
check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "")
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
endif()
|
||||
@@ -804,7 +820,11 @@ endif()
|
||||
option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
|
||||
if(ENABLE_UNIX_SOCKETS)
|
||||
include(CheckStructHasMember)
|
||||
check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
|
||||
if(WIN32)
|
||||
set(USE_UNIX_SOCKETS ON)
|
||||
else()
|
||||
check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
|
||||
endif()
|
||||
else()
|
||||
unset(USE_UNIX_SOCKETS CACHE)
|
||||
endif()
|
||||
@@ -915,8 +935,6 @@ check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
|
||||
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
|
||||
check_include_file_concat("assert.h" HAVE_ASSERT_H)
|
||||
check_include_file_concat("crypto.h" HAVE_CRYPTO_H)
|
||||
check_include_file_concat("err.h" HAVE_ERR_H)
|
||||
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
||||
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
||||
check_include_file_concat("idn2.h" HAVE_IDN2_H)
|
||||
@@ -934,9 +952,7 @@ check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
|
||||
check_include_file_concat("pem.h" HAVE_PEM_H)
|
||||
check_include_file_concat("poll.h" HAVE_POLL_H)
|
||||
check_include_file_concat("pwd.h" HAVE_PWD_H)
|
||||
check_include_file_concat("rsa.h" HAVE_RSA_H)
|
||||
check_include_file_concat("setjmp.h" HAVE_SETJMP_H)
|
||||
check_include_file_concat("sgtty.h" HAVE_SGTTY_H)
|
||||
check_include_file_concat("signal.h" HAVE_SIGNAL_H)
|
||||
check_include_file_concat("ssl.h" HAVE_SSL_H)
|
||||
check_include_file_concat("stdbool.h" HAVE_STDBOOL_H)
|
||||
@@ -1017,12 +1033,8 @@ endif()
|
||||
check_symbol_exists(getppid "${CURL_INCLUDES}" HAVE_GETPPID)
|
||||
check_symbol_exists(utimes "${CURL_INCLUDES}" HAVE_UTIMES)
|
||||
|
||||
check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
|
||||
check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
|
||||
check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
|
||||
check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
|
||||
check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA)
|
||||
check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
|
||||
check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
|
||||
check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
|
||||
check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
|
||||
@@ -1047,11 +1059,8 @@ check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
|
||||
check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
|
||||
check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
|
||||
check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
|
||||
check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR)
|
||||
check_symbol_exists(fork "${CURL_INCLUDES}" HAVE_FORK)
|
||||
check_symbol_exists(getaddrinfo "${CURL_INCLUDES}" HAVE_GETADDRINFO)
|
||||
check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
|
||||
check_symbol_exists(freeifaddrs "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
|
||||
check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
|
||||
check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
|
||||
check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
|
||||
@@ -1118,12 +1127,6 @@ foreach(CURL_TEST
|
||||
HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
TIME_WITH_SYS_TIME
|
||||
HAVE_O_NONBLOCK
|
||||
HAVE_GETHOSTBYADDR_R_5
|
||||
HAVE_GETHOSTBYADDR_R_7
|
||||
HAVE_GETHOSTBYADDR_R_8
|
||||
HAVE_GETHOSTBYADDR_R_5_REENTRANT
|
||||
HAVE_GETHOSTBYADDR_R_7_REENTRANT
|
||||
HAVE_GETHOSTBYADDR_R_8_REENTRANT
|
||||
HAVE_GETHOSTBYNAME_R_3
|
||||
HAVE_GETHOSTBYNAME_R_5
|
||||
HAVE_GETHOSTBYNAME_R_6
|
||||
@@ -1133,8 +1136,6 @@ foreach(CURL_TEST
|
||||
HAVE_IN_ADDR_T
|
||||
HAVE_BOOL_T
|
||||
STDC_HEADERS
|
||||
HAVE_INET_NTOA_R_DECL
|
||||
HAVE_INET_NTOA_R_DECL_REENTRANT
|
||||
HAVE_GETADDRINFO
|
||||
HAVE_FILE_OFFSET_BITS
|
||||
HAVE_VARIADIC_MACROS_C99
|
||||
@@ -1166,13 +1167,9 @@ endforeach()
|
||||
|
||||
# Check for reentrant
|
||||
foreach(CURL_TEST
|
||||
HAVE_GETHOSTBYADDR_R_5
|
||||
HAVE_GETHOSTBYADDR_R_7
|
||||
HAVE_GETHOSTBYADDR_R_8
|
||||
HAVE_GETHOSTBYNAME_R_3
|
||||
HAVE_GETHOSTBYNAME_R_5
|
||||
HAVE_GETHOSTBYNAME_R_6
|
||||
HAVE_INET_NTOA_R_DECL_REENTRANT)
|
||||
HAVE_GETHOSTBYNAME_R_6)
|
||||
if(NOT ${CURL_TEST})
|
||||
if(${CURL_TEST}_REENTRANT)
|
||||
set(NEED_REENTRANT 1)
|
||||
@@ -1182,9 +1179,6 @@ endforeach()
|
||||
|
||||
if(NEED_REENTRANT)
|
||||
foreach(CURL_TEST
|
||||
HAVE_GETHOSTBYADDR_R_5
|
||||
HAVE_GETHOSTBYADDR_R_7
|
||||
HAVE_GETHOSTBYADDR_R_8
|
||||
HAVE_GETHOSTBYNAME_R_3
|
||||
HAVE_GETHOSTBYNAME_R_5
|
||||
HAVE_GETHOSTBYNAME_R_6)
|
||||
@@ -1195,11 +1189,6 @@ if(NEED_REENTRANT)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(HAVE_INET_NTOA_R_DECL_REENTRANT)
|
||||
set(HAVE_INET_NTOA_R_DECL 1)
|
||||
set(NEED_REENTRANT 1)
|
||||
endif()
|
||||
|
||||
# Check clock_gettime(CLOCK_MONOTONIC, x) support
|
||||
curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC)
|
||||
|
||||
@@ -1380,8 +1369,8 @@ endmacro()
|
||||
|
||||
# NTLM support requires crypto function adaptions from various SSL libs
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
|
||||
if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_MBEDTLS OR
|
||||
USE_DARWINSSL OR USE_WIN32_CRYPTO))
|
||||
if(NOT (CURL_DISABLE_CRYPTO_AUTH OR CURL_DISABLE_NTLM) AND
|
||||
(USE_OPENSSL OR USE_MBEDTLS OR USE_DARWINSSL OR USE_WIN32_CRYPTO))
|
||||
set(use_curl_ntlm_core ON)
|
||||
endif()
|
||||
|
||||
@@ -1409,10 +1398,10 @@ _add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
# NTLM support requires crypto function adaptions from various SSL libs
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
|
||||
_add_if("NTLM" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
_add_if("NTLM" NOT (CURL_DISABLE_CRYPTO_AUTH OR CURL_DISABLE_NTLM) AND
|
||||
(use_curl_ntlm_core OR USE_WINDOWS_SSPI))
|
||||
# TODO missing option (autoconf: --enable-ntlm-wb)
|
||||
_add_if("NTLM_WB" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
_add_if("NTLM_WB" NOT (CURL_DISABLE_CRYPTO_AUTH OR CURL_DISABLE_NTLM) AND
|
||||
(use_curl_ntlm_core OR USE_WINDOWS_SSPI) AND
|
||||
NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
|
||||
# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
|
||||
|
||||
+10
-9
@@ -25,9 +25,6 @@
|
||||
/*
|
||||
* If you have libcurl problems, all docs and details are found here:
|
||||
* https://curl.se/libcurl/
|
||||
*
|
||||
* curl-library mailing list subscription and unsubscription web interface:
|
||||
* https://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*/
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
@@ -74,8 +71,9 @@
|
||||
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
||||
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
||||
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
|
||||
defined(__CYGWIN__) || defined(AMIGA) || \
|
||||
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
|
||||
defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
|
||||
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
|
||||
defined(__VXWORKS__)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
@@ -541,7 +539,7 @@ typedef enum {
|
||||
CURLE_OBSOLETE46, /* 46 - NOT USED */
|
||||
CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */
|
||||
CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
|
||||
CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */
|
||||
CURLE_SETOPT_OPTION_SYNTAX, /* 49 - Malformed setopt option */
|
||||
CURLE_OBSOLETE50, /* 50 - NOT USED */
|
||||
CURLE_OBSOLETE51, /* 51 - NOT USED */
|
||||
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||
@@ -636,6 +634,9 @@ typedef enum {
|
||||
/* The following were added in 7.21.5, April 2011 */
|
||||
#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
|
||||
|
||||
/* Added for 7.78.0 */
|
||||
#define CURLE_TELNET_OPTION_SYNTAX CURLE_SETOPT_OPTION_SYNTAX
|
||||
|
||||
/* The following were added in 7.17.1 */
|
||||
/* These are scheduled to disappear by 2009 */
|
||||
#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
|
||||
@@ -2084,13 +2085,13 @@ typedef enum {
|
||||
/* Parameters for V4 signature */
|
||||
CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305),
|
||||
|
||||
/* Same as CURLOPT_SSL_VERIFYPEER but for DOH (DNS-over-HTTPS) servers. */
|
||||
/* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */
|
||||
CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306),
|
||||
|
||||
/* Same as CURLOPT_SSL_VERIFYHOST but for DOH (DNS-over-HTTPS) servers. */
|
||||
/* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */
|
||||
CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307),
|
||||
|
||||
/* Same as CURLOPT_SSL_VERIFYSTATUS but for DOH (DNS-over-HTTPS) servers. */
|
||||
/* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */
|
||||
CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308),
|
||||
|
||||
/* The CA certificates as "blob" used to validate the peer certificate
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.77.0-DEV"
|
||||
#define LIBCURL_VERSION "7.79.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 77
|
||||
#define LIBCURL_VERSION_MINOR 79
|
||||
#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 0x074d00
|
||||
#define LIBCURL_VERSION_NUM 0x074f00
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 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
|
||||
@@ -79,6 +79,7 @@ typedef enum {
|
||||
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
|
||||
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
|
||||
scheme is unknown. */
|
||||
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
|
||||
|
||||
typedef struct Curl_URL CURLU;
|
||||
|
||||
|
||||
+6
-6
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2019 - 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
|
||||
@@ -460,7 +460,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
(void)data;
|
||||
#endif
|
||||
if(result) {
|
||||
infof(data, "Excessive alt-svc header, ignoring...\n");
|
||||
infof(data, "Excessive alt-svc header, ignoring.");
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
p++;
|
||||
len = p - hostp;
|
||||
if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
|
||||
infof(data, "Excessive alt-svc host name, ignoring...\n");
|
||||
infof(data, "Excessive alt-svc host name, ignoring.");
|
||||
dstalpnid = ALPN_none;
|
||||
}
|
||||
else {
|
||||
@@ -513,7 +513,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
/* a port number */
|
||||
unsigned long port = strtoul(++p, &end_ptr, 10);
|
||||
if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
|
||||
infof(data, "Unknown alt-svc port number, ignoring...\n");
|
||||
infof(data, "Unknown alt-svc port number, ignoring.");
|
||||
dstalpnid = ALPN_none;
|
||||
}
|
||||
p = end_ptr;
|
||||
@@ -579,12 +579,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
as->expires = maxage + time(NULL);
|
||||
as->persist = persist;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
|
||||
infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport,
|
||||
Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
}
|
||||
else {
|
||||
infof(data, "Unknown alt-svc protocol \"%s\", skipping...\n",
|
||||
infof(data, "Unknown alt-svc protocol \"%s\", skipping.",
|
||||
alpnbuf);
|
||||
}
|
||||
}
|
||||
|
||||
+166
-19
@@ -59,7 +59,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "inet_pton.h"
|
||||
@@ -80,13 +79,33 @@
|
||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
||||
#endif
|
||||
|
||||
#if ARES_VERSION >= 0x010601
|
||||
/* IPv6 supported since 1.6.1 */
|
||||
#define HAVE_CARES_IPV6 1
|
||||
#endif
|
||||
|
||||
#if ARES_VERSION >= 0x010704
|
||||
#define HAVE_CARES_SERVERS_CSV 1
|
||||
#define HAVE_CARES_LOCAL_DEV 1
|
||||
#define HAVE_CARES_SET_LOCAL 1
|
||||
#endif
|
||||
|
||||
#if ARES_VERSION >= 0x010b00
|
||||
#define HAVE_CARES_PORTS_CSV 1
|
||||
#endif
|
||||
|
||||
#if ARES_VERSION >= 0x011000
|
||||
/* 1.16.0 or later has ares_getaddrinfo */
|
||||
#define HAVE_CARES_GETADDRINFO 1
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
struct thread_data {
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int last_status;
|
||||
@@ -206,7 +225,8 @@ static void destroy_async_data(struct Curl_async *async);
|
||||
*/
|
||||
void Curl_resolver_cancel(struct Curl_easy *data)
|
||||
{
|
||||
if(data && data->state.async.resolver)
|
||||
DEBUGASSERT(data);
|
||||
if(data->state.async.resolver)
|
||||
ares_cancel((ares_channel)data->state.async.resolver);
|
||||
destroy_async_data(&data->state.async);
|
||||
}
|
||||
@@ -489,21 +509,37 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
|
||||
/* Connects results to the list */
|
||||
static void compound_results(struct thread_data *res,
|
||||
struct Curl_addrinfo *ai)
|
||||
{
|
||||
struct Curl_addrinfo *ai_tail;
|
||||
if(!ai)
|
||||
return;
|
||||
ai_tail = ai;
|
||||
|
||||
while(ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
if(res->temp_ai && res->temp_ai->ai_family == PF_INET6) {
|
||||
/* We have results already, put the new IPv6 entries at the head of the
|
||||
list. */
|
||||
struct Curl_addrinfo *temp_ai_tail = res->temp_ai;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = res->temp_ai;
|
||||
res->temp_ai = ai;
|
||||
while(temp_ai_tail->ai_next)
|
||||
temp_ai_tail = temp_ai_tail->ai_next;
|
||||
|
||||
temp_ai_tail->ai_next = ai;
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
{
|
||||
/* Add the new results to the list of old results. */
|
||||
struct Curl_addrinfo *ai_tail = ai;
|
||||
while(ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
ai_tail->ai_next = res->temp_ai;
|
||||
res->temp_ai = ai;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -605,7 +641,98 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* c-ares 1.16.0 or later */
|
||||
|
||||
/*
|
||||
* ares2addr() converts an address list provided by c-ares to an internal
|
||||
* libcurl compatible list
|
||||
*/
|
||||
static struct Curl_addrinfo *ares2addr(struct ares_addrinfo_node *node)
|
||||
{
|
||||
/* traverse the ares_addrinfo_node list */
|
||||
struct ares_addrinfo_node *ai;
|
||||
struct Curl_addrinfo *cafirst = NULL;
|
||||
struct Curl_addrinfo *calast = NULL;
|
||||
int error = 0;
|
||||
|
||||
for(ai = node; ai != NULL; ai = ai->ai_next) {
|
||||
size_t ss_size;
|
||||
struct Curl_addrinfo *ca;
|
||||
/* ignore elements with unsupported address family, */
|
||||
/* settle family-specific sockaddr structure size. */
|
||||
if(ai->ai_family == AF_INET)
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(ai->ai_family == AF_INET6)
|
||||
ss_size = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
else
|
||||
continue;
|
||||
|
||||
/* ignore elements without required address info */
|
||||
if(!ai->ai_addr || !(ai->ai_addrlen > 0))
|
||||
continue;
|
||||
|
||||
/* ignore elements with bogus address size */
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy each structure member individually, member ordering, */
|
||||
/* size, or padding might be different for each platform. */
|
||||
|
||||
ca->ai_flags = ai->ai_flags;
|
||||
ca->ai_family = ai->ai_family;
|
||||
ca->ai_socktype = ai->ai_socktype;
|
||||
ca->ai_protocol = ai->ai_protocol;
|
||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||
ca->ai_addr = NULL;
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
/* if the return list is empty, this becomes the first element */
|
||||
if(!cafirst)
|
||||
cafirst = ca;
|
||||
|
||||
/* add this element last in the return list */
|
||||
if(calast)
|
||||
calast->ai_next = ca;
|
||||
calast = ca;
|
||||
}
|
||||
|
||||
/* if we failed, destroy the Curl_addrinfo list */
|
||||
if(error) {
|
||||
Curl_freeaddrinfo(cafirst);
|
||||
cafirst = NULL;
|
||||
}
|
||||
|
||||
return cafirst;
|
||||
}
|
||||
|
||||
static void addrinfo_cb(void *arg, int status, int timeouts,
|
||||
struct ares_addrinfo *result)
|
||||
{
|
||||
struct Curl_easy *data = (struct Curl_easy *)arg;
|
||||
struct thread_data *res = data->state.async.tdata;
|
||||
(void)timeouts;
|
||||
if(ARES_SUCCESS == status) {
|
||||
res->temp_ai = ares2addr(result->nodes);
|
||||
res->last_status = CURL_ASYNC_SUCCESS;
|
||||
ares_freeaddrinfo(result);
|
||||
}
|
||||
res->num_pending--;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - when using ares
|
||||
*
|
||||
@@ -643,8 +770,28 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||
/* initial status - failed */
|
||||
res->last_status = ARES_ENOTFOUND;
|
||||
|
||||
#if ARES_VERSION >= 0x010601
|
||||
/* IPv6 supported by c-ares since 1.6.1 */
|
||||
#ifdef HAVE_CARES_GETADDRINFO
|
||||
{
|
||||
struct ares_addrinfo_hints hints;
|
||||
char service[12];
|
||||
int pf = PF_INET;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
#ifdef CURLRES_IPV6
|
||||
if(Curl_ipv6works(data))
|
||||
/* The stack seems to be IPv6-enabled */
|
||||
pf = PF_UNSPEC;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
|
||||
SOCK_STREAM : SOCK_DGRAM;
|
||||
msnprintf(service, sizeof(service), "%d", port);
|
||||
res->num_pending = 1;
|
||||
ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname,
|
||||
service, &hints, addrinfo_cb, data);
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef HAVE_CARES_IPV6
|
||||
if(Curl_ipv6works(data)) {
|
||||
/* The stack seems to be IPv6-enabled */
|
||||
res->num_pending = 2;
|
||||
@@ -656,7 +803,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||
PF_INET6, query_completed_cb, data);
|
||||
}
|
||||
else
|
||||
#endif /* ARES_VERSION >= 0x010601 */
|
||||
#endif
|
||||
{
|
||||
res->num_pending = 1;
|
||||
|
||||
@@ -665,7 +812,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||
hostname, PF_INET,
|
||||
query_completed_cb, data);
|
||||
}
|
||||
|
||||
#endif
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
}
|
||||
return NULL; /* no struct yet */
|
||||
@@ -686,8 +833,8 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
if(!(servers && servers[0]))
|
||||
return CURLE_OK;
|
||||
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
#if (ARES_VERSION >= 0x010b00)
|
||||
#ifdef HAVE_CARES_SERVERS_CSV
|
||||
#ifdef HAVE_CARES_PORTS_CSV
|
||||
ares_result = ares_set_servers_ports_csv(data->state.async.resolver,
|
||||
servers);
|
||||
#else
|
||||
@@ -717,7 +864,7 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
#ifdef HAVE_CARES_LOCAL_DEV
|
||||
if(!interf)
|
||||
interf = "";
|
||||
|
||||
@@ -734,7 +881,7 @@ CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
#ifdef HAVE_CARES_SET_LOCAL
|
||||
struct in_addr a4;
|
||||
|
||||
if((!local_ip4) || (local_ip4[0] == 0)) {
|
||||
@@ -760,7 +907,7 @@ CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
|
||||
#if defined(HAVE_CARES_SET_LOCAL) && defined(ENABLE_IPV6)
|
||||
unsigned char a6[INET6_ADDRSTRLEN];
|
||||
|
||||
if((!local_ip6) || (local_ip6[0] == 0)) {
|
||||
|
||||
@@ -68,7 +68,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "inet_ntop.h"
|
||||
|
||||
+213
-42
@@ -124,6 +124,17 @@ static int hyper_each_header(void *userdata,
|
||||
size_t len;
|
||||
char *headp;
|
||||
CURLcode result;
|
||||
int writetype;
|
||||
|
||||
if(name_len + value_len + 2 > CURL_MAX_HTTP_HEADER) {
|
||||
failf(data, "Too long response header");
|
||||
data->state.hresult = CURLE_OUT_OF_MEMORY;
|
||||
return HYPER_ITER_BREAK;
|
||||
}
|
||||
|
||||
if(!data->req.bytecount)
|
||||
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
||||
|
||||
Curl_dyn_reset(&data->state.headerb);
|
||||
if(name_len) {
|
||||
if(Curl_dyn_addf(&data->state.headerb, "%.*s: %.*s\r\n",
|
||||
@@ -145,7 +156,10 @@ static int hyper_each_header(void *userdata,
|
||||
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, headp, len);
|
||||
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, headp, len);
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
result = Curl_client_write(data, writetype, headp, len);
|
||||
if(result) {
|
||||
data->state.hresult = CURLE_ABORTED_BY_CALLBACK;
|
||||
return HYPER_ITER_BREAK;
|
||||
@@ -162,13 +176,43 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
|
||||
size_t len = hyper_buf_len(chunk);
|
||||
struct Curl_easy *data = (struct Curl_easy *)userdata;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(0 == k->bodywrites++) {
|
||||
bool done = FALSE;
|
||||
result = Curl_http_firstwrite(data, data->conn, &done);
|
||||
#if defined(USE_NTLM)
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn->bits.close &&
|
||||
(((data->req.httpcode == 401) &&
|
||||
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
|
||||
infof(data, "Connection closed while negotiating NTLM");
|
||||
data->state.authproblem = TRUE;
|
||||
Curl_safefree(data->req.newurl);
|
||||
}
|
||||
#endif
|
||||
if(data->state.expect100header) {
|
||||
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||
if(data->req.httpcode < 400) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
if(data->hyp.exp100_waker) {
|
||||
hyper_waker_wake(data->hyp.exp100_waker);
|
||||
data->hyp.exp100_waker = NULL;
|
||||
}
|
||||
}
|
||||
else { /* >= 4xx */
|
||||
k->exp100 = EXP100_FAILED;
|
||||
}
|
||||
}
|
||||
if(data->state.hconnect && (data->req.httpcode/100 != 2)) {
|
||||
done = TRUE;
|
||||
result = CURLE_OK;
|
||||
}
|
||||
else
|
||||
result = Curl_http_firstwrite(data, data->conn, &done);
|
||||
if(result || done) {
|
||||
infof(data, "Return early from hyper_body_chunk\n");
|
||||
infof(data, "Return early from hyper_body_chunk");
|
||||
data->state.hresult = result;
|
||||
return HYPER_ITER_BREAK;
|
||||
}
|
||||
@@ -207,11 +251,15 @@ static CURLcode status_line(struct Curl_easy *data,
|
||||
CURLcode result;
|
||||
size_t len;
|
||||
const char *vstr;
|
||||
int writetype;
|
||||
vstr = http_version == HYPER_HTTP_VERSION_1_1 ? "1.1" :
|
||||
(http_version == HYPER_HTTP_VERSION_2 ? "2" : "1.0");
|
||||
conn->httpversion =
|
||||
http_version == HYPER_HTTP_VERSION_1_1 ? 11 :
|
||||
(http_version == HYPER_HTTP_VERSION_2 ? 20 : 10);
|
||||
if(http_version == HYPER_HTTP_VERSION_1_0)
|
||||
data->state.httpwant = CURL_HTTP_VERSION_1_0;
|
||||
|
||||
data->req.httpcode = http_status;
|
||||
|
||||
result = Curl_http_statusline(data, conn);
|
||||
@@ -229,7 +277,10 @@ static CURLcode status_line(struct Curl_easy *data,
|
||||
len = Curl_dyn_len(&data->state.headerb);
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb),
|
||||
len);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER,
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
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;
|
||||
@@ -270,8 +321,25 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
const uint8_t *reasonp;
|
||||
size_t reason_len;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k = &data->req;
|
||||
(void)conn;
|
||||
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
struct curltime now = Curl_now();
|
||||
timediff_t ms = Curl_timediff(now, k->start100);
|
||||
if(ms >= data->set.expect_100_timeout) {
|
||||
/* we've waited long enough, continue anyway */
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||
infof(data, "Done waiting for 100-continue");
|
||||
if(data->hyp.exp100_waker) {
|
||||
hyper_waker_wake(data->hyp.exp100_waker);
|
||||
data->hyp.exp100_waker = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(select_res & CURL_CSELECT_IN) {
|
||||
if(h->read_waker)
|
||||
hyper_waker_wake(h->read_waker);
|
||||
@@ -305,19 +373,22 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
hyper_task_free(task);
|
||||
|
||||
if(t == HYPER_TASK_ERROR) {
|
||||
hyper_code errnum = hyper_error_code(hypererr);
|
||||
if(errnum == HYPERE_ABORTED_BY_CALLBACK) {
|
||||
if(data->state.hresult) {
|
||||
/* override Hyper's view, might not even be an error */
|
||||
result = data->state.hresult;
|
||||
infof(data, "hyperstream is done (by early callback)\n");
|
||||
infof(data, "hyperstream is done (by early callback)");
|
||||
}
|
||||
else {
|
||||
uint8_t errbuf[256];
|
||||
size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
|
||||
hyper_code code = hyper_error_code(hypererr);
|
||||
failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf);
|
||||
if((code == HYPERE_UNEXPECTED_EOF) && !data->req.bytecount)
|
||||
if(code == HYPERE_ABORTED_BY_CALLBACK)
|
||||
result = CURLE_OK;
|
||||
else if((code == HYPERE_UNEXPECTED_EOF) && !data->req.bytecount)
|
||||
result = CURLE_GOT_NOTHING;
|
||||
else if(code == HYPERE_INVALID_PEER_MESSAGE)
|
||||
result = CURLE_UNSUPPORTED_PROTOCOL; /* maybe */
|
||||
else
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
@@ -328,10 +399,15 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
else if(h->endtask == task) {
|
||||
/* end of transfer */
|
||||
*done = TRUE;
|
||||
infof(data, "hyperstream is done!\n");
|
||||
infof(data, "hyperstream is done!");
|
||||
if(!k->bodywrites) {
|
||||
/* hyper doesn't always call the body write callback */
|
||||
bool stilldone;
|
||||
result = Curl_http_firstwrite(data, data->conn, &stilldone);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(t != HYPER_TASK_RESPONSE && t != HYPER_TASK_EMPTY) {
|
||||
else if(t != HYPER_TASK_RESPONSE) {
|
||||
*didwhat = KEEP_RECV;
|
||||
break;
|
||||
}
|
||||
@@ -472,7 +548,7 @@ CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
|
||||
|
||||
if(HYPERE_OK != hyper_headers_add(headers, (uint8_t *)n, nlen,
|
||||
(uint8_t *)v, vlen)) {
|
||||
failf(data, "hyper_headers_add host");
|
||||
failf(data, "hyper refused to add header '%s'", line);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(data->set.verbose) {
|
||||
@@ -485,7 +561,7 @@ CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
|
||||
free(ptr);
|
||||
}
|
||||
else
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)line, linelen);
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)n, linelen);
|
||||
}
|
||||
numh++;
|
||||
n += linelen;
|
||||
@@ -526,12 +602,32 @@ static int uploadpostfields(void *userdata, hyper_context *ctx,
|
||||
{
|
||||
struct Curl_easy *data = (struct Curl_easy *)userdata;
|
||||
(void)ctx;
|
||||
if(data->req.exp100 > EXP100_SEND_DATA) {
|
||||
if(data->req.exp100 == EXP100_FAILED)
|
||||
return HYPER_POLL_ERROR;
|
||||
|
||||
/* still waiting confirmation */
|
||||
if(data->hyp.exp100_waker)
|
||||
hyper_waker_free(data->hyp.exp100_waker);
|
||||
data->hyp.exp100_waker = hyper_context_waker(ctx);
|
||||
return HYPER_POLL_PENDING;
|
||||
}
|
||||
if(data->req.upload_done)
|
||||
*chunk = NULL; /* nothing more to deliver */
|
||||
else {
|
||||
/* send everything off in a single go */
|
||||
*chunk = hyper_buf_copy(data->set.postfields,
|
||||
(size_t)data->req.p.http->postsize);
|
||||
hyper_buf *copy = hyper_buf_copy(data->set.postfields,
|
||||
(size_t)data->req.p.http->postsize);
|
||||
if(copy)
|
||||
*chunk = copy;
|
||||
else {
|
||||
data->state.hresult = CURLE_OUT_OF_MEMORY;
|
||||
return HYPER_POLL_ERROR;
|
||||
}
|
||||
/* increasing the writebytecount here is a little premature but we
|
||||
don't know exactly when the body is sent*/
|
||||
data->req.writebytecount += (size_t)data->req.p.http->postsize;
|
||||
Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
|
||||
data->req.upload_done = TRUE;
|
||||
}
|
||||
return HYPER_POLL_READY;
|
||||
@@ -542,16 +638,41 @@ static int uploadstreamed(void *userdata, hyper_context *ctx,
|
||||
{
|
||||
size_t fillcount;
|
||||
struct Curl_easy *data = (struct Curl_easy *)userdata;
|
||||
CURLcode result =
|
||||
Curl_fillreadbuffer(data, data->set.upload_buffer_size, &fillcount);
|
||||
CURLcode result;
|
||||
(void)ctx;
|
||||
if(result)
|
||||
|
||||
if(data->req.exp100 > EXP100_SEND_DATA) {
|
||||
if(data->req.exp100 == EXP100_FAILED)
|
||||
return HYPER_POLL_ERROR;
|
||||
|
||||
/* still waiting confirmation */
|
||||
if(data->hyp.exp100_waker)
|
||||
hyper_waker_free(data->hyp.exp100_waker);
|
||||
data->hyp.exp100_waker = hyper_context_waker(ctx);
|
||||
return HYPER_POLL_PENDING;
|
||||
}
|
||||
|
||||
result = Curl_fillreadbuffer(data, data->set.upload_buffer_size, &fillcount);
|
||||
if(result) {
|
||||
data->state.hresult = result;
|
||||
return HYPER_POLL_ERROR;
|
||||
}
|
||||
if(!fillcount)
|
||||
/* done! */
|
||||
*chunk = NULL;
|
||||
else
|
||||
*chunk = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount);
|
||||
else {
|
||||
hyper_buf *copy = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount);
|
||||
if(copy)
|
||||
*chunk = copy;
|
||||
else {
|
||||
data->state.hresult = CURLE_OUT_OF_MEMORY;
|
||||
return HYPER_POLL_ERROR;
|
||||
}
|
||||
/* increasing the writebytecount here is a little premature but we
|
||||
don't know exactly when the body is sent*/
|
||||
data->req.writebytecount += fillcount;
|
||||
Curl_pgrsSetUploadCounter(data, fillcount);
|
||||
}
|
||||
return HYPER_POLL_READY;
|
||||
}
|
||||
|
||||
@@ -566,6 +687,7 @@ static CURLcode bodysend(struct Curl_easy *data,
|
||||
hyper_request *hyperreq,
|
||||
Curl_HttpReq httpreq)
|
||||
{
|
||||
struct HTTP *http = data->req.p.http;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct dynbuf req;
|
||||
if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD))
|
||||
@@ -598,6 +720,7 @@ static CURLcode bodysend(struct Curl_easy *data,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
http->sending = HTTPSEND_BODY;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -616,6 +739,48 @@ static CURLcode cookies(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* called on 1xx responses */
|
||||
static void http1xx_cb(void *arg, struct hyper_response *resp)
|
||||
{
|
||||
struct Curl_easy *data = (struct Curl_easy *)arg;
|
||||
hyper_headers *headers = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
uint16_t http_status;
|
||||
int http_version;
|
||||
const uint8_t *reasonp;
|
||||
size_t reason_len;
|
||||
|
||||
infof(data, "Got HTTP 1xx informational");
|
||||
|
||||
http_status = hyper_response_status(resp);
|
||||
http_version = hyper_response_version(resp);
|
||||
reasonp = hyper_response_reason_phrase(resp);
|
||||
reason_len = hyper_response_reason_phrase_len(resp);
|
||||
|
||||
result = status_line(data, data->conn,
|
||||
http_status, http_version, reasonp, reason_len);
|
||||
if(!result) {
|
||||
headers = hyper_response_headers(resp);
|
||||
if(!headers) {
|
||||
failf(data, "hyperstream: couldn't get 1xx response headers");
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
data->state.hresult = result;
|
||||
|
||||
if(!result) {
|
||||
/* the headers are already received */
|
||||
hyper_headers_foreach(headers, hyper_each_header, data);
|
||||
/* this callback also sets data->state.hresult on error */
|
||||
|
||||
if(empty_header(data))
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->state.hresult)
|
||||
infof(data, "ERROR in 1xx, bail out!");
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_http() gets called from the generic multi_do() function when a HTTP
|
||||
* request is to be performed. This creates and sends a properly constructed
|
||||
@@ -633,20 +798,20 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
hyper_request *req = NULL;
|
||||
hyper_headers *headers = NULL;
|
||||
hyper_task *handshake = NULL;
|
||||
hyper_error *hypererr = NULL;
|
||||
CURLcode result;
|
||||
const char *p_accept; /* Accept: string */
|
||||
const char *method;
|
||||
Curl_HttpReq httpreq;
|
||||
bool h2 = FALSE;
|
||||
const char *te = NULL; /* transfer-encoding */
|
||||
hyper_code rc;
|
||||
|
||||
/* Always consider the DO phase done after this function call, even if there
|
||||
may be parts of the request that is not yet sent, since we can deal with
|
||||
the rest of the request in the PERFORM phase. */
|
||||
*done = TRUE;
|
||||
|
||||
infof(data, "Time for the Hyper dance\n");
|
||||
infof(data, "Time for the Hyper dance");
|
||||
memset(h, 0, sizeof(struct hyptransfer));
|
||||
|
||||
result = Curl_http_host(data, conn);
|
||||
@@ -743,7 +908,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
if(!Curl_use_http_1_1plus(data, conn)) {
|
||||
if(HYPERE_OK != hyper_request_set_version(req,
|
||||
HYPER_HTTP_VERSION_1_0)) {
|
||||
failf(data, "error setting HTTP version");
|
||||
@@ -766,6 +931,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = hyper_request_on_informational(req, http1xx_cb, data);
|
||||
if(rc)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = Curl_http_body(data, conn, httpreq, &te);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -830,6 +999,15 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
else
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
/* we only consider transfer-encoding magic if libz support is built-in */
|
||||
result = Curl_transferencode(data);
|
||||
if(result)
|
||||
return result;
|
||||
if(Curl_hyper_header(data, headers, data->state.aptr.te))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
result = cookies(data, conn, headers);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -862,25 +1040,21 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
|
||||
hyper_clientconn_free(client);
|
||||
|
||||
do {
|
||||
task = hyper_executor_poll(h->exec);
|
||||
if(task) {
|
||||
bool error = hyper_task_type(task) == HYPER_TASK_ERROR;
|
||||
if(error)
|
||||
hypererr = hyper_task_value(task);
|
||||
hyper_task_free(task);
|
||||
if(error)
|
||||
goto error;
|
||||
}
|
||||
} while(task);
|
||||
|
||||
if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) {
|
||||
/* HTTP GET/HEAD download */
|
||||
Curl_pgrsSetUploadSize(data, 0); /* nothing */
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
|
||||
}
|
||||
conn->datastream = Curl_hyper_stream;
|
||||
if(data->state.expect100header)
|
||||
/* Timeout count starts now since with Hyper we don't know exactly when
|
||||
the full request has been sent. */
|
||||
data->req.start100 = Curl_now();
|
||||
|
||||
/* clear userpwd and proxyuserpwd to avoid re-using old credentials
|
||||
* from re-used connections */
|
||||
Curl_safefree(data->state.aptr.userpwd);
|
||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||
return CURLE_OK;
|
||||
error:
|
||||
|
||||
@@ -893,13 +1067,6 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
if(handshake)
|
||||
hyper_task_free(handshake);
|
||||
|
||||
if(hypererr) {
|
||||
uint8_t errbuf[256];
|
||||
size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
|
||||
hyper_code code = hyper_error_code(hypererr);
|
||||
failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf);
|
||||
hyper_error_free(hypererr);
|
||||
}
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -918,6 +1085,10 @@ void Curl_hyper_done(struct Curl_easy *data)
|
||||
hyper_waker_free(h->write_waker);
|
||||
h->write_waker = NULL;
|
||||
}
|
||||
if(h->exp100_waker) {
|
||||
hyper_waker_free(h->exp100_waker);
|
||||
h->exp100_waker = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
|
||||
|
||||
@@ -33,6 +33,7 @@ struct hyptransfer {
|
||||
hyper_waker *read_waker;
|
||||
const hyper_executor *exec;
|
||||
hyper_task *endtask;
|
||||
hyper_waker *exp100_waker;
|
||||
};
|
||||
|
||||
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
|
||||
|
||||
+7
-5
@@ -34,6 +34,7 @@
|
||||
#include "share.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -161,6 +162,7 @@ static void hashkey(struct connectdata *conn, char *buf,
|
||||
|
||||
/* put the number first so that the hostname gets cut off if too long */
|
||||
msnprintf(buf, len, "%ld%s", port, hostname);
|
||||
Curl_strntolower(buf, buf, len);
|
||||
}
|
||||
|
||||
/* Returns number of connections currently held in the connection cache.
|
||||
@@ -264,7 +266,7 @@ CURLcode Curl_conncache_add_conn(struct Curl_easy *data)
|
||||
connc->num_conn++;
|
||||
|
||||
DEBUGF(infof(data, "Added connection %ld. "
|
||||
"The cache now contains %zu members\n",
|
||||
"The cache now contains %zu members",
|
||||
conn->connection_id, connc->num_conn));
|
||||
|
||||
unlock:
|
||||
@@ -298,7 +300,7 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
conn->bundle = NULL; /* removed from it */
|
||||
if(connc) {
|
||||
connc->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
||||
connc->num_conn));
|
||||
}
|
||||
if(lock) {
|
||||
@@ -408,7 +410,7 @@ bool Curl_conncache_return_conn(struct Curl_easy *data,
|
||||
conn->lastused = Curl_now(); /* it was used up until now */
|
||||
if(maxconnects > 0 &&
|
||||
Curl_conncache_size(data) > maxconnects) {
|
||||
infof(data, "Connection cache is full, closing the oldest one.\n");
|
||||
infof(data, "Connection cache is full, closing the oldest one");
|
||||
|
||||
conn_candidate = Curl_conncache_extract_oldest(data);
|
||||
if(conn_candidate) {
|
||||
@@ -464,7 +466,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
|
||||
/* remove it to prevent another thread from nicking it */
|
||||
bundle_remove_conn(bundle, conn_candidate);
|
||||
data->state.conn_cache->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
||||
data->state.conn_cache->num_conn));
|
||||
}
|
||||
|
||||
@@ -526,7 +528,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
/* remove it to prevent another thread from nicking it */
|
||||
bundle_remove_conn(bundle_candidate, conn_candidate);
|
||||
connc->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
||||
connc->num_conn));
|
||||
}
|
||||
CONNCACHE_UNLOCK(data);
|
||||
|
||||
+46
-38
@@ -111,7 +111,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
/* only set IDLE and INTVL if setting KEEPALIVE is successful */
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
|
||||
infof(data, "Failed to set SO_KEEPALIVE on fd %d", sockfd);
|
||||
}
|
||||
else {
|
||||
#if defined(SIO_KEEPALIVE_VALS)
|
||||
@@ -126,7 +126,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
vals.keepaliveinterval = optval;
|
||||
if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
|
||||
NULL, 0, &dummy, NULL, NULL) != 0) {
|
||||
infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
|
||||
infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d",
|
||||
(int)sockfd, WSAGetLastError());
|
||||
}
|
||||
#else
|
||||
@@ -135,7 +135,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
|
||||
infof(data, "Failed to set TCP_KEEPIDLE on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPINTVL
|
||||
@@ -143,7 +143,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
|
||||
infof(data, "Failed to set TCP_KEEPINTVL on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPALIVE
|
||||
@@ -152,7 +152,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
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\n", sockfd);
|
||||
infof(data, "Failed to set TCP_KEEPALIVE on fd %d", sockfd);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -331,7 +331,7 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
||||
/*
|
||||
* We now have the numerical IP address in the 'myhost' buffer
|
||||
*/
|
||||
infof(data, "Local Interface %s is ip %s using address family %i\n",
|
||||
infof(data, "Local Interface %s is ip %s using address family %i",
|
||||
dev, myhost, af);
|
||||
done = 1;
|
||||
break;
|
||||
@@ -364,7 +364,7 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
||||
if(h) {
|
||||
/* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
|
||||
Curl_printable_address(h->addr, myhost, sizeof(myhost));
|
||||
infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
|
||||
infof(data, "Name '%s' family %i resolved to '%s' family %i",
|
||||
dev, af, myhost, h->addr->ai_family);
|
||||
Curl_resolv_unlock(data, h);
|
||||
if(af != h->addr->ai_family) {
|
||||
@@ -458,13 +458,13 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
infof(data, "Local port: %hu\n", port);
|
||||
infof(data, "Local port: %hu", port);
|
||||
conn->bits.bound = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(--portnum > 0) {
|
||||
infof(data, "Bind to local port %hu failed, trying next\n", port);
|
||||
infof(data, "Bind to local port %hu failed, trying next", port);
|
||||
port++; /* try next port */
|
||||
/* We re-use/clobber the port variable here below */
|
||||
if(sock->sa_family == AF_INET)
|
||||
@@ -589,12 +589,10 @@ static CURLcode trynextip(struct Curl_easy *data,
|
||||
struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
|
||||
|
||||
while(ai) {
|
||||
if(ai) {
|
||||
result = singleipconnect(data, conn, ai, tempindex);
|
||||
if(result == CURLE_COULDNT_CONNECT) {
|
||||
ai = ainext(conn, tempindex, TRUE);
|
||||
continue;
|
||||
}
|
||||
result = singleipconnect(data, conn, ai, tempindex);
|
||||
if(result == CURLE_COULDNT_CONNECT) {
|
||||
ai = ainext(conn, tempindex, TRUE);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -753,10 +751,9 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
|
||||
int local_port = -1;
|
||||
|
||||
if(conn->transport == TRNSPRT_TCP) {
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
|
||||
Curl_conninfo_remote(data, conn, sockfd);
|
||||
Curl_conninfo_local(data, sockfd, local_ip, &local_port);
|
||||
}
|
||||
Curl_conninfo_local(data, sockfd, local_ip, &local_port);
|
||||
} /* end of TCP-only section */
|
||||
|
||||
/* persist connection info in session handle */
|
||||
@@ -872,15 +869,6 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
|
||||
now = Curl_now();
|
||||
|
||||
/* figure out how long time we have left to connect */
|
||||
allow = Curl_timeleft(data, &now, TRUE);
|
||||
|
||||
if(allow < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
failf(data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(SOCKS_STATE(conn->cnnct.state)) {
|
||||
/* still doing SOCKS */
|
||||
result = connect_SOCKS(data, sockindex, connected);
|
||||
@@ -930,7 +918,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
if(Curl_timediff(now, conn->connecttime) >=
|
||||
conn->timeoutms_per_addr[i]) {
|
||||
infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
|
||||
"ms connect time, move on!\n", conn->timeoutms_per_addr[i]);
|
||||
"ms connect time, move on!", conn->timeoutms_per_addr[i]);
|
||||
error = ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -989,11 +977,12 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
char buffer[STRERROR_LEN];
|
||||
Curl_printable_address(conn->tempaddr[i], ipaddress,
|
||||
sizeof(ipaddress));
|
||||
infof(data, "connect to %s port %ld failed: %s\n",
|
||||
infof(data, "connect to %s port %u failed: %s",
|
||||
ipaddress, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
#endif
|
||||
|
||||
allow = Curl_timeleft(data, &now, TRUE);
|
||||
conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
|
||||
allow : allow / 2;
|
||||
ainext(conn, i, TRUE);
|
||||
@@ -1006,6 +995,21 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we've checked whether we are connected, check whether we've
|
||||
* already timed out.
|
||||
*
|
||||
* First figure out how long time we have left to connect */
|
||||
|
||||
allow = Curl_timeleft(data, &now, TRUE);
|
||||
|
||||
if(allow < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
failf(data, "Connection timeout after %ld ms",
|
||||
Curl_timediff(now, data->progress.t_startsingle));
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(result &&
|
||||
(conn->tempsock[0] == CURL_SOCKET_BAD) &&
|
||||
(conn->tempsock[1] == CURL_SOCKET_BAD)) {
|
||||
@@ -1031,9 +1035,11 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
failf(data, "Failed to connect to %s port %ld: %s",
|
||||
hostname, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
failf(data, "Failed to connect to %s port %u after "
|
||||
"%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
|
||||
hostname, conn->port,
|
||||
Curl_timediff(now, data->progress.t_startsingle),
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
Curl_quic_disconnect(data, conn, 0);
|
||||
Curl_quic_disconnect(data, conn, 1);
|
||||
@@ -1065,7 +1071,7 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
|
||||
sizeof(onoff)) < 0)
|
||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||
infof(data, "Could not set TCP_NODELAY: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#else
|
||||
(void)data;
|
||||
@@ -1084,9 +1090,11 @@ static void nosigpipe(struct Curl_easy *data,
|
||||
int onoff = 1;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0) {
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
|
||||
infof(data, "Could not set SO_NOSIGPIPE: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -1180,7 +1188,7 @@ static CURLcode singleipconnect(struct Curl_easy *data,
|
||||
Curl_closesocket(data, conn, sockfd);
|
||||
return CURLE_OK;
|
||||
}
|
||||
infof(data, " Trying %s:%d...\n", ipaddress, port);
|
||||
infof(data, " Trying %s:%d...", ipaddress, port);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
|
||||
@@ -1271,7 +1279,7 @@ static CURLcode singleipconnect(struct Curl_easy *data,
|
||||
#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
|
||||
(void *)&optval, sizeof(optval)) < 0)
|
||||
infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
|
||||
infof(data, "Failed to enable TCP Fast Open on fd %d", sockfd);
|
||||
|
||||
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
|
||||
#elif defined(MSG_FASTOPEN) /* old Linux */
|
||||
@@ -1321,7 +1329,7 @@ static CURLcode singleipconnect(struct Curl_easy *data,
|
||||
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
infof(data, "Immediate connect fail for %s: %s\n",
|
||||
infof(data, "Immediate connect fail for %s: %s",
|
||||
ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
data->state.os_errno = error;
|
||||
|
||||
@@ -1394,7 +1402,7 @@ CURLcode Curl_connecthost(struct Curl_easy *data,
|
||||
|
||||
ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
|
||||
|
||||
DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
|
||||
DEBUGF(infof(data, "family0 == %s, family1 == %s",
|
||||
conn->tempfamily[0] == AF_INET ? "v4" : "v6",
|
||||
conn->tempfamily[1] == AF_INET ? "v4" : "v6"));
|
||||
|
||||
|
||||
+48
-39
@@ -95,7 +95,6 @@ Example set of cookies:
|
||||
#include "strcase.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
#include "parsedate.h"
|
||||
#include "rand.h"
|
||||
#include "rename.h"
|
||||
@@ -146,31 +145,6 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* isip
|
||||
*
|
||||
* Returns true if the given string is an IPv4 or IPv6 address (if IPv6 has
|
||||
* been enabled while building libcurl, and false otherwise.
|
||||
*/
|
||||
static bool isip(const char *domain)
|
||||
{
|
||||
struct in_addr addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
|
||||
if(Curl_inet_pton(AF_INET, domain, &addr)
|
||||
#ifdef ENABLE_IPV6
|
||||
|| Curl_inet_pton(AF_INET6, domain, &addr6)
|
||||
#endif
|
||||
) {
|
||||
/* domain name given as IP address */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* matching cookie path and url path
|
||||
* RFC6265 5.1.4 Paths and Path-Match
|
||||
@@ -303,7 +277,7 @@ static size_t cookiehash(const char * const domain)
|
||||
const char *top;
|
||||
size_t len;
|
||||
|
||||
if(!domain || isip(domain))
|
||||
if(!domain || Curl_host_is_ipnum(domain))
|
||||
return 0;
|
||||
|
||||
top = get_top_domain(domain, &len);
|
||||
@@ -366,7 +340,7 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
|
||||
* Failure may be due to OOM or a bad cookie; both are ignored
|
||||
* but only the first should be
|
||||
*/
|
||||
infof(data, "ignoring failed cookie_init for %s\n", list->data);
|
||||
infof(data, "ignoring failed cookie_init for %s", list->data);
|
||||
else
|
||||
data->cookies = newcookies;
|
||||
list = list->next;
|
||||
@@ -397,7 +371,9 @@ static void strstore(char **str, const char *newstr)
|
||||
*
|
||||
* Remove expired cookies from the hash by inspecting the expires timestamp on
|
||||
* each cookie in the hash, freeing and deleting any where the timestamp is in
|
||||
* the past.
|
||||
* the past. If the cookiejar has recorded the next timestamp at which one or
|
||||
* more cookies expire, then processing will exit early in case this timestamp
|
||||
* is in the future.
|
||||
*/
|
||||
static void remove_expired(struct CookieInfo *cookies)
|
||||
{
|
||||
@@ -405,6 +381,20 @@ static void remove_expired(struct CookieInfo *cookies)
|
||||
curl_off_t now = (curl_off_t)time(NULL);
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* If the earliest expiration timestamp in the jar is in the future we can
|
||||
* skip scanning the whole jar and instead exit early as there won't be any
|
||||
* cookies to evict. If we need to evict however, reset the next_expiration
|
||||
* counter in order to track the next one. In case the recorded first
|
||||
* expiration is the max offset, then perform the safe fallback of checking
|
||||
* all cookies.
|
||||
*/
|
||||
if(now < cookies->next_expiration &&
|
||||
cookies->next_expiration != CURL_OFF_T_MAX)
|
||||
return;
|
||||
else
|
||||
cookies->next_expiration = CURL_OFF_T_MAX;
|
||||
|
||||
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
|
||||
struct Cookie *pv = NULL;
|
||||
co = cookies->cookies[i];
|
||||
@@ -421,6 +411,12 @@ static void remove_expired(struct CookieInfo *cookies)
|
||||
freecookie(co);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If this cookie has an expiration timestamp earlier than what we've
|
||||
* seen so far then record it for the next round of expirations.
|
||||
*/
|
||||
if(co->expires && co->expires < cookies->next_expiration)
|
||||
cookies->next_expiration = co->expires;
|
||||
pv = co;
|
||||
}
|
||||
co = nx;
|
||||
@@ -524,7 +520,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) ||
|
||||
((nlen + len) > MAX_NAME)) {
|
||||
freecookie(co);
|
||||
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n",
|
||||
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes",
|
||||
nlen, len);
|
||||
return NULL;
|
||||
}
|
||||
@@ -645,7 +641,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
domain = ":";
|
||||
#endif
|
||||
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
is_ip = Curl_host_is_ipnum(domain ? domain : whatptr);
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strcmp(whatptr, domain))
|
||||
@@ -665,7 +661,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
* not a domain to which the current host belongs. Mark as bad.
|
||||
*/
|
||||
badcookie = TRUE;
|
||||
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
|
||||
infof(data, "skipped cookie with bad tailmatch domain: %s",
|
||||
whatptr);
|
||||
}
|
||||
}
|
||||
@@ -996,7 +992,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
* must also check that the data handle isn't NULL since the psl code will
|
||||
* dereference it.
|
||||
*/
|
||||
if(data && (domain && co->domain && !isip(co->domain))) {
|
||||
if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) {
|
||||
const psl_ctx_t *psl = Curl_psl_use(data);
|
||||
int acceptable;
|
||||
|
||||
@@ -1009,7 +1005,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
|
||||
if(!acceptable) {
|
||||
infof(data, "cookie '%s' dropped, domain '%s' must not "
|
||||
"set cookies for '%s'\n", co->name, domain, co->domain);
|
||||
"set cookies for '%s'", co->name, domain, co->domain);
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1121,7 +1117,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(c->running)
|
||||
/* Only show this when NOT reading the cookies from a file */
|
||||
infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
|
||||
"expire %" CURL_FORMAT_CURL_OFF_T "\n",
|
||||
"expire %" CURL_FORMAT_CURL_OFF_T,
|
||||
replace_old?"Replaced":"Added", co->name, co->value,
|
||||
co->domain, co->path, co->expires);
|
||||
|
||||
@@ -1134,6 +1130,13 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
c->numcookies++; /* one more cookie in the jar */
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we've added a new cookie to the jar, update the expiration
|
||||
* tracker in case it is the next one to expire.
|
||||
*/
|
||||
if(co->expires && (co->expires < c->next_expiration))
|
||||
c->next_expiration = co->expires;
|
||||
|
||||
return co;
|
||||
}
|
||||
|
||||
@@ -1169,6 +1172,11 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
c->filename = strdup(file?file:"none"); /* copy the name just in case */
|
||||
if(!c->filename)
|
||||
goto fail; /* failed to get memory */
|
||||
/*
|
||||
* Initialize the next_expiration time to signal that we don't have enough
|
||||
* information yet.
|
||||
*/
|
||||
c->next_expiration = CURL_OFF_T_MAX;
|
||||
}
|
||||
else {
|
||||
/* we got an already existing one, use that */
|
||||
@@ -1215,7 +1223,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
|
||||
/*
|
||||
* Remove expired cookies from the hash. We must make sure to run this
|
||||
* after reading the file, and not not on every cookie.
|
||||
* after reading the file, and not on every cookie.
|
||||
*/
|
||||
remove_expired(c);
|
||||
|
||||
@@ -1247,7 +1255,8 @@ fail:
|
||||
*
|
||||
* Helper function to sort cookies such that the longest path gets before the
|
||||
* shorter path. Path, domain and name lengths are considered in that order,
|
||||
* with tge creationtime as the tiebreaker.
|
||||
* with the creationtime as the tiebreaker. The creationtime is guaranteed to
|
||||
* be unique per cookie, so we know we will get an ordering at that point.
|
||||
*/
|
||||
static int cookie_sort(const void *p1, const void *p2)
|
||||
{
|
||||
@@ -1355,7 +1364,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
remove_expired(c);
|
||||
|
||||
/* check if host is an IP(v4|v6) address */
|
||||
is_ip = isip(host);
|
||||
is_ip = Curl_host_is_ipnum(host);
|
||||
|
||||
co = c->cookies[myhash];
|
||||
|
||||
@@ -1734,7 +1743,7 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
|
||||
/* if we have a destination file for all the cookies to get dumped to */
|
||||
res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]);
|
||||
if(res)
|
||||
infof(data, "WARNING: failed to save cookies in %s: %s\n",
|
||||
infof(data, "WARNING: failed to save cookies in %s: %s",
|
||||
data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -65,6 +65,7 @@ struct CookieInfo {
|
||||
bool running; /* state info, for cookie adding information */
|
||||
bool newsession; /* new session, discard session cookies on load */
|
||||
int lastct; /* last creation-time used in the jar */
|
||||
curl_off_t next_expiration; /* the next time at which expiration happens */
|
||||
};
|
||||
|
||||
/* This is the maximum line length we accept for a cookie line. RFC 2109
|
||||
|
||||
@@ -50,12 +50,6 @@
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#if defined(USE_UNIX_SOCKETS) && defined(WINAPI_FAMILY) && \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
/* Required for sockaddr_un type */
|
||||
# include <afunix.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
+50
-89
@@ -33,61 +33,91 @@
|
||||
/* Location of default ca path */
|
||||
#cmakedefine CURL_CA_PATH "${CURL_CA_PATH}"
|
||||
|
||||
/* to disable cookies support */
|
||||
/* disables alt-svc */
|
||||
#cmakedefine CURL_DISABLE_ALTSVC 1
|
||||
|
||||
/* disables cookies support */
|
||||
#cmakedefine CURL_DISABLE_COOKIES 1
|
||||
|
||||
/* to disable cryptographic authentication */
|
||||
/* disables cryptographic authentication */
|
||||
#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1
|
||||
|
||||
/* to disable DICT */
|
||||
/* disables DICT */
|
||||
#cmakedefine CURL_DISABLE_DICT 1
|
||||
|
||||
/* to disable FILE */
|
||||
/* disables DNS-over-HTTPS */
|
||||
#cmakedefine CURL_DISABLE_DOH 1
|
||||
|
||||
/* disables FILE */
|
||||
#cmakedefine CURL_DISABLE_FILE 1
|
||||
|
||||
/* to disable FTP */
|
||||
/* disables FTP */
|
||||
#cmakedefine CURL_DISABLE_FTP 1
|
||||
|
||||
/* to disable GOPHER */
|
||||
/* disables GOPHER */
|
||||
#cmakedefine CURL_DISABLE_GOPHER 1
|
||||
|
||||
/* to disable IMAP */
|
||||
#cmakedefine CURL_DISABLE_IMAP 1
|
||||
/* disables HSTS support */
|
||||
#cmakedefine CURL_DISABLE_HSTS 1
|
||||
|
||||
/* to disable HTTP */
|
||||
/* disables HTTP */
|
||||
#cmakedefine CURL_DISABLE_HTTP 1
|
||||
|
||||
/* to disable LDAP */
|
||||
/* disables IMAP */
|
||||
#cmakedefine CURL_DISABLE_IMAP 1
|
||||
|
||||
/* disables LDAP */
|
||||
#cmakedefine CURL_DISABLE_LDAP 1
|
||||
|
||||
/* to disable LDAPS */
|
||||
/* disables LDAPS */
|
||||
#cmakedefine CURL_DISABLE_LDAPS 1
|
||||
|
||||
/* to disable MQTT */
|
||||
/* disables --libcurl option from the curl tool */
|
||||
#cmakedefine CURL_DISABLE_LIBCURL_OPTION 1
|
||||
|
||||
/* disables MIME support */
|
||||
#cmakedefine CURL_DISABLE_MIME 1
|
||||
|
||||
/* disables MQTT */
|
||||
#cmakedefine CURL_DISABLE_MQTT 1
|
||||
|
||||
/* to disable POP3 */
|
||||
/* disables netrc parser */
|
||||
#cmakedefine CURL_DISABLE_NETRC 1
|
||||
|
||||
/* disables NTLM support */
|
||||
#cmakedefine CURL_DISABLE_NTLM 1
|
||||
|
||||
/* disables date parsing */
|
||||
#cmakedefine CURL_DISABLE_PARSEDATE 1
|
||||
|
||||
/* disables POP3 */
|
||||
#cmakedefine CURL_DISABLE_POP3 1
|
||||
|
||||
/* to disable proxies */
|
||||
/* disables built-in progress meter */
|
||||
#cmakedefine CURL_DISABLE_PROGRESS_METER 1
|
||||
|
||||
/* disables proxies */
|
||||
#cmakedefine CURL_DISABLE_PROXY 1
|
||||
|
||||
/* to disable RTSP */
|
||||
/* disables RTSP */
|
||||
#cmakedefine CURL_DISABLE_RTSP 1
|
||||
|
||||
/* to disable SMB */
|
||||
/* disables SMB */
|
||||
#cmakedefine CURL_DISABLE_SMB 1
|
||||
|
||||
/* to disable SMTP */
|
||||
/* disables SMTP */
|
||||
#cmakedefine CURL_DISABLE_SMTP 1
|
||||
|
||||
/* to disable TELNET */
|
||||
/* disables use of socketpair for curl_multi_poll */
|
||||
#cmakedefine CURL_DISABLE_SOCKETPAIR 1
|
||||
|
||||
/* disables TELNET */
|
||||
#cmakedefine CURL_DISABLE_TELNET 1
|
||||
|
||||
/* to disable TFTP */
|
||||
/* disables TFTP */
|
||||
#cmakedefine CURL_DISABLE_TFTP 1
|
||||
|
||||
/* to disable verbose strings */
|
||||
/* disables verbose strings */
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
/* to make a symbol visible */
|
||||
@@ -112,12 +142,6 @@
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#cmakedefine ENABLE_IPV6 1
|
||||
|
||||
/* Specifies the number of arguments to getservbyport_r */
|
||||
#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS}
|
||||
|
||||
/* Specifies the size of the buffer to pass to getservbyport_r */
|
||||
#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE}
|
||||
|
||||
/* Define to 1 if you have the alarm function. */
|
||||
#cmakedefine HAVE_ALARM 1
|
||||
|
||||
@@ -151,18 +175,12 @@
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
#cmakedefine HAVE_CRYPTO_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#cmakedefine HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#cmakedefine HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the fcntl function. */
|
||||
#cmakedefine HAVE_FCNTL 1
|
||||
|
||||
@@ -172,18 +190,9 @@
|
||||
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
|
||||
#cmakedefine HAVE_FCNTL_O_NONBLOCK 1
|
||||
|
||||
/* Define to 1 if you have the fdopen function. */
|
||||
#cmakedefine HAVE_FDOPEN 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#cmakedefine HAVE_FORK 1
|
||||
|
||||
/* Define to 1 if you have the freeaddrinfo function. */
|
||||
#cmakedefine HAVE_FREEADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the freeifaddrs function. */
|
||||
#cmakedefine HAVE_FREEIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the ftruncate function. */
|
||||
#cmakedefine HAVE_FTRUNCATE 1
|
||||
|
||||
@@ -196,21 +205,6 @@
|
||||
/* Define to 1 if you have the `getppid' function. */
|
||||
#cmakedefine HAVE_GETPPID 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyaddr function. */
|
||||
#cmakedefine HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyaddr_r function. */
|
||||
#cmakedefine HAVE_GETHOSTBYADDR_R 1
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
#cmakedefine HAVE_GETHOSTBYADDR_R_5 1
|
||||
|
||||
/* gethostbyaddr_r() takes 7 args */
|
||||
#cmakedefine HAVE_GETHOSTBYADDR_R_7 1
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#cmakedefine HAVE_GETHOSTBYADDR_R_8 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyname function. */
|
||||
#cmakedefine HAVE_GETHOSTBYNAME 1
|
||||
|
||||
@@ -259,9 +253,6 @@
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#cmakedefine HAVE_GETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the getservbyport_r function. */
|
||||
#cmakedefine HAVE_GETSERVBYPORT_R 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#cmakedefine HAVE_GETTIMEOFDAY 1
|
||||
|
||||
@@ -395,21 +386,6 @@
|
||||
/* Define to 1 if you have the `ssh2' library (-lssh2). */
|
||||
#cmakedefine HAVE_LIBSSH2 1
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_version'. */
|
||||
#cmakedefine HAVE_LIBSSH2_VERSION 1
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_init'. */
|
||||
#cmakedefine HAVE_LIBSSH2_INIT 1
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_exit'. */
|
||||
#cmakedefine HAVE_LIBSSH2_EXIT 1
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
|
||||
#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
|
||||
#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1
|
||||
|
||||
/* Define to 1 if you have the <libssh2.h> header file. */
|
||||
#cmakedefine HAVE_LIBSSH2_H 1
|
||||
|
||||
@@ -527,9 +503,6 @@
|
||||
/* Define to 1 if you have the recvfrom function. */
|
||||
#cmakedefine HAVE_RECVFROM 1
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
#cmakedefine HAVE_RSA_H 1
|
||||
|
||||
/* Define to 1 if you have the select function. */
|
||||
#cmakedefine HAVE_SELECT 1
|
||||
|
||||
@@ -563,9 +536,6 @@
|
||||
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
|
||||
#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#cmakedefine HAVE_SGTTY_H 1
|
||||
|
||||
/* Define to 1 if you have the sigaction function. */
|
||||
#cmakedefine HAVE_SIGACTION 1
|
||||
|
||||
@@ -581,12 +551,6 @@
|
||||
/* Define to 1 if you have the sigsetjmp function or macro. */
|
||||
#cmakedefine HAVE_SIGSETJMP 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is an available typedef. */
|
||||
#cmakedefine HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is already defined as volatile. */
|
||||
#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1
|
||||
|
||||
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
@@ -991,9 +955,6 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
/* to disable alt-svc */
|
||||
#cmakedefine CURL_DISABLE_ALTSVC 1
|
||||
|
||||
/* Define to 1 if you are building a Windows target with large file support. */
|
||||
#cmakedefine USE_WIN32_LARGE_FILES 1
|
||||
|
||||
|
||||
@@ -80,45 +80,3 @@ unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
||||
((unsigned short)buf[1]));
|
||||
}
|
||||
|
||||
#if (SIZEOF_CURL_OFF_T > 4)
|
||||
/*
|
||||
* write32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 32-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
static void write32_le(const int value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x000000FF);
|
||||
buffer[1] = (char)((value & 0x0000FF00) >> 8);
|
||||
buffer[2] = (char)((value & 0x00FF0000) >> 16);
|
||||
buffer[3] = (char)((value & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_write64_le()
|
||||
*
|
||||
* This function converts a 64-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 64-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
void Curl_write64_le(const long long value, unsigned char *buffer)
|
||||
#else
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer)
|
||||
#endif
|
||||
{
|
||||
write32_le((int)value, buffer);
|
||||
write32_le((int)(value >> 32), buffer + 4);
|
||||
}
|
||||
#endif /* SIZEOF_CURL_OFF_T > 4 */
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
||||
#else
|
||||
infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
"compiled in\n");
|
||||
"compiled in");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
|
||||
display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
|
||||
|
||||
infof(data, "%s%s\n", prefix, buf);
|
||||
infof(data, "%s%s", prefix, buf);
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)data;
|
||||
(void)prefix;
|
||||
|
||||
+30
-24
@@ -102,14 +102,16 @@ int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
va_end(param);
|
||||
|
||||
#ifdef _UNICODE
|
||||
if(filename_w)
|
||||
if(filename_w) {
|
||||
result = _wopen(filename_w, oflag, pmode);
|
||||
free(filename_w);
|
||||
if(result != -1)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
free(filename_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
return result;
|
||||
#else
|
||||
return (_open)(filename, oflag, pmode);
|
||||
#endif
|
||||
}
|
||||
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
@@ -120,19 +122,20 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w)
|
||||
result = _wfopen(filename_w, mode_w);
|
||||
else
|
||||
errno = EINVAL;
|
||||
free(filename_w);
|
||||
free(mode_w);
|
||||
if(result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
#else
|
||||
return (fopen)(filename, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
int result = -1;
|
||||
#ifdef _UNICODE
|
||||
int result = -1;
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
@@ -141,31 +144,34 @@ int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
result = _wstati64(path_w, buffer);
|
||||
#endif
|
||||
free(path_w);
|
||||
if(result != -1)
|
||||
return result;
|
||||
}
|
||||
#endif /* _UNICODE */
|
||||
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
result = _stat(path, buffer);
|
||||
#else
|
||||
result = _stati64(path, buffer);
|
||||
#endif
|
||||
else
|
||||
errno = EINVAL;
|
||||
return result;
|
||||
#else
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
return _stat(path, buffer);
|
||||
#else
|
||||
return _stati64(path, buffer);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int curlx_win32_access(const char *path, int mode)
|
||||
{
|
||||
#if defined(_UNICODE)
|
||||
int result = -1;
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
int result = _waccess(path_w, mode);
|
||||
result = _waccess(path_w, mode);
|
||||
free(path_w);
|
||||
if(result != -1)
|
||||
return result;
|
||||
}
|
||||
#endif /* _UNICODE */
|
||||
else
|
||||
errno = EINVAL;
|
||||
return result;
|
||||
#else
|
||||
return _access(path, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|
||||
|
||||
+6
-10
@@ -86,7 +86,6 @@
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
# include <mbedtls/des.h>
|
||||
# include "curl_md4.h"
|
||||
|
||||
#elif defined(USE_SECTRANSP)
|
||||
|
||||
@@ -498,17 +497,14 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
* network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, len * 2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Create NT hashed password. */
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
|
||||
if(!result) {
|
||||
/* Create NT hashed password. */
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
free(pw);
|
||||
|
||||
return CURLE_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
+5
-4
@@ -355,17 +355,17 @@ CURLcode Curl_input_ntlm_wb(struct Curl_easy *data,
|
||||
}
|
||||
else {
|
||||
if(*state == NTLMSTATE_LAST) {
|
||||
infof(data, "NTLM auth restarted\n");
|
||||
infof(data, "NTLM auth restarted");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
}
|
||||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(data, "NTLM handshake rejected\n");
|
||||
infof(data, "NTLM handshake rejected");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(*state >= NTLMSTATE_TYPE1) {
|
||||
infof(data, "NTLM handshake failure (internal error)\n");
|
||||
infof(data, "NTLM handshake failure (internal error)");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@@ -426,7 +426,8 @@ CURLcode Curl_output_ntlm_wb(struct Curl_easy *data, struct connectdata *conn,
|
||||
/* Use Samba's 'winbind' daemon to support NTLM authentication,
|
||||
* by delegating the NTLM challenge/response protocol to a helper
|
||||
* in ntlm_auth.
|
||||
* http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
|
||||
* https://web.archive.org/web/20190925164737
|
||||
* /devel.squid-cache.org/ntlm/squid_helper_protocol.html
|
||||
* https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
|
||||
* https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
|
||||
* Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
|
||||
|
||||
+4
-4
@@ -53,14 +53,14 @@ CURLcode Curl_range(struct Curl_easy *data)
|
||||
if((to_t == CURL_OFFT_INVAL) && !from_t) {
|
||||
/* X - */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
|
||||
DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file",
|
||||
from));
|
||||
}
|
||||
else if((from_t == CURL_OFFT_INVAL) && !to_t) {
|
||||
/* -Y */
|
||||
data->req.maxdownload = to;
|
||||
data->state.resume_from = -to;
|
||||
DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
to));
|
||||
}
|
||||
else {
|
||||
@@ -78,12 +78,12 @@ CURLcode Curl_range(struct Curl_easy *data)
|
||||
data->req.maxdownload = totalsize + 1; /* include last byte */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
|
||||
" getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
" getting %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
from, data->req.maxdownload));
|
||||
}
|
||||
DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
|
||||
" to %" CURL_FORMAT_CURL_OFF_T ", totally %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
from, to, data->req.maxdownload));
|
||||
}
|
||||
else
|
||||
|
||||
+7
-3
@@ -234,7 +234,7 @@ static void state(struct SASL *sasl, struct Curl_easy *data,
|
||||
};
|
||||
|
||||
if(sasl->state != newstate)
|
||||
infof(data, "SASL %p state change from %s to %s\n",
|
||||
infof(data, "SASL %p state change from %s to %s",
|
||||
(void *)sasl, names[sasl->state], names[newstate]);
|
||||
#else
|
||||
(void) data;
|
||||
@@ -630,7 +630,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
}
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_auth_create_gssapi_security_message(data, &serverdata,
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
}
|
||||
@@ -639,7 +641,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_gssapi_security_message(data, &serverdata,
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
break;
|
||||
|
||||
+63
-40
@@ -166,42 +166,48 @@
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# ifndef CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_TFTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_TELNET
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_DICT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FILE
|
||||
# define CURL_DISABLE_FILE
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# ifndef CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAPS
|
||||
# define CURL_DISABLE_LDAPS
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_MQTT
|
||||
# define CURL_DISABLE_MQTT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMB
|
||||
# define CURL_DISABLE_SMB
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_TELNET
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_TFTP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -456,6 +462,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SSIZE_T_MAX
|
||||
/* some limits.h headers have this defined, some don't */
|
||||
#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
|
||||
#define SSIZE_T_MAX 9223372036854775807
|
||||
#else
|
||||
#define SSIZE_T_MAX 2147483647
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Arg 2 type for gethostname in case it hasn't been defined in config file.
|
||||
*/
|
||||
@@ -644,24 +659,16 @@ int netware_init(void);
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
#if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
|
||||
|
||||
#define USE_CURL_NTLM_CORE
|
||||
|
||||
# if defined(USE_MBEDTLS)
|
||||
/* Get definition of MBEDTLS_MD4_C */
|
||||
# include <mbedtls/md4.h>
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(CURL_DISABLE_NTLM)
|
||||
# if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
|
||||
# define USE_CURL_NTLM_CORE
|
||||
# endif
|
||||
# if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)
|
||||
# define USE_NTLM
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)
|
||||
#define USE_NTLM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_WANTS_CA_BUNDLE_ENV
|
||||
@@ -819,4 +826,20 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
#define ENABLE_QUIC
|
||||
#endif
|
||||
|
||||
#if defined(USE_UNIX_SOCKETS) && defined(WIN32)
|
||||
# if defined(__MINGW32__) && !defined(LUP_SECURE)
|
||||
typedef u_short ADDRESS_FAMILY; /* Classic mingw, 11y+ old mingw-w64 */
|
||||
# endif
|
||||
# if !defined(UNIX_PATH_MAX)
|
||||
/* Replicating logic present in afunix.h
|
||||
(distributed with newer Windows 10 SDK versions only) */
|
||||
# define UNIX_PATH_MAX 108
|
||||
/* !checksrc! disable TYPEDEFSTRUCT 1 */
|
||||
typedef struct sockaddr_un {
|
||||
ADDRESS_FAMILY sun_family;
|
||||
char sun_path[UNIX_PATH_MAX];
|
||||
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
@@ -323,26 +323,6 @@ struct timeval {
|
||||
|
||||
#include "curl_ctype.h"
|
||||
|
||||
/*
|
||||
* Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_SIG_ATOMIC_T
|
||||
typedef int sig_atomic_t;
|
||||
#define HAVE_SIG_ATOMIC_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Convenience SIG_ATOMIC_T definition
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
|
||||
#define SIG_ATOMIC_T static sig_atomic_t
|
||||
#else
|
||||
#define SIG_ATOMIC_T static volatile sig_atomic_t
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macro used to include code only in debug builds.
|
||||
|
||||
+2
-2
@@ -216,7 +216,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
if(!word || (*word == (char)0)) {
|
||||
infof(data, "lookup word is missing\n");
|
||||
infof(data, "lookup word is missing");
|
||||
word = (char *)"default";
|
||||
}
|
||||
if(!database || (*database == (char)0)) {
|
||||
@@ -267,7 +267,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
}
|
||||
|
||||
if(!word || (*word == (char)0)) {
|
||||
infof(data, "lookup word is missing\n");
|
||||
infof(data, "lookup word is missing");
|
||||
word = (char *)"default";
|
||||
}
|
||||
if(!database || (*database == (char)0)) {
|
||||
|
||||
@@ -186,19 +186,19 @@ doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
|
||||
return realsize;
|
||||
}
|
||||
|
||||
/* called from multi.c when this DOH transfer is complete */
|
||||
/* called from multi.c when this DoH transfer is complete */
|
||||
static int doh_done(struct Curl_easy *doh, CURLcode result)
|
||||
{
|
||||
struct Curl_easy *data = doh->set.dohfor;
|
||||
struct dohdata *dohp = data->req.doh;
|
||||
/* so one of the DOH request done for the 'data' transfer is now complete! */
|
||||
/* so one of the DoH request done for the 'data' transfer is now complete! */
|
||||
dohp->pending--;
|
||||
infof(data, "a DOH request is completed, %u to go\n", dohp->pending);
|
||||
infof(data, "a DoH request is completed, %u to go", dohp->pending);
|
||||
if(result)
|
||||
infof(data, "DOH request %s\n", curl_easy_strerror(result));
|
||||
infof(data, "DoH request %s", curl_easy_strerror(result));
|
||||
|
||||
if(!dohp->pending) {
|
||||
/* DOH completed */
|
||||
/* DoH completed */
|
||||
curl_slist_free_all(dohp->headers);
|
||||
dohp->headers = NULL;
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||
@@ -228,7 +228,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
DOHcode d = doh_encode(host, dnstype, p->dohbuffer, sizeof(p->dohbuffer),
|
||||
&p->dohlen);
|
||||
if(d) {
|
||||
failf(data, "Failed to encode DOH packet [%d]", d);
|
||||
failf(data, "Failed to encode DoH packet [%d]", d);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
/* Inherit *some* SSL options from the user's transfer. This is a
|
||||
best-guess as to which options are needed for compatibility. #3661
|
||||
|
||||
Note DOH does not inherit the user's proxy server so proxy SSL settings
|
||||
Note DoH does not inherit the user's proxy server so proxy SSL settings
|
||||
have no effect and are not inherited. If that changes then two new
|
||||
options should be added to check doh proxy insecure separately,
|
||||
CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER.
|
||||
@@ -359,17 +359,17 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
(data->set.ssl.auto_client_cert ?
|
||||
CURLSSLOPT_AUTO_CLIENT_CERT : 0);
|
||||
|
||||
curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask);
|
||||
(void)curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask);
|
||||
}
|
||||
|
||||
doh->set.fmultidone = doh_done;
|
||||
doh->set.dohfor = data; /* identify for which transfer this is done */
|
||||
p->easy = doh;
|
||||
|
||||
/* DOH private_data must be null because the user must have a way to
|
||||
distinguish their transfer's handle from DOH handles in user
|
||||
/* DoH private_data must be null because the user must have a way to
|
||||
distinguish their transfer's handle from DoH handles in user
|
||||
callbacks (ie SSL CTX callback). */
|
||||
DEBUGASSERT(!data->set.private_data);
|
||||
DEBUGASSERT(!doh->set.private_data);
|
||||
|
||||
if(curl_multi_add_handle(multi, doh))
|
||||
goto error;
|
||||
@@ -386,7 +386,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_doh() resolves a name using DOH. It resolves a name and returns a
|
||||
* Curl_doh() resolves a name using DoH. It resolves a name and returns a
|
||||
* 'Curl_addrinfo *' with the address information.
|
||||
*/
|
||||
|
||||
@@ -420,7 +420,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
if(!dohp->headers)
|
||||
goto error;
|
||||
|
||||
/* create IPv4 DOH request */
|
||||
/* create IPv4 DoH request */
|
||||
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4],
|
||||
DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
|
||||
data->multi, dohp->headers);
|
||||
@@ -429,7 +429,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
dohp->pending++;
|
||||
|
||||
if(Curl_ipv6works(data)) {
|
||||
/* create IPv6 DOH request */
|
||||
/* create IPv6 DoH request */
|
||||
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
|
||||
DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
|
||||
data->multi, dohp->headers);
|
||||
@@ -764,11 +764,11 @@ static void showdoh(struct Curl_easy *data,
|
||||
const struct dohentry *d)
|
||||
{
|
||||
int i;
|
||||
infof(data, "TTL: %u seconds\n", d->ttl);
|
||||
infof(data, "TTL: %u seconds", d->ttl);
|
||||
for(i = 0; i < d->numaddr; i++) {
|
||||
const struct dohaddr *a = &d->addr[i];
|
||||
if(a->type == DNS_TYPE_A) {
|
||||
infof(data, "DOH A: %u.%u.%u.%u\n",
|
||||
infof(data, "DoH A: %u.%u.%u.%u",
|
||||
a->ip.v4[0], a->ip.v4[1],
|
||||
a->ip.v4[2], a->ip.v4[3]);
|
||||
}
|
||||
@@ -777,7 +777,7 @@ static void showdoh(struct Curl_easy *data,
|
||||
char buffer[128];
|
||||
char *ptr;
|
||||
size_t len;
|
||||
msnprintf(buffer, 128, "DOH AAAA: ");
|
||||
msnprintf(buffer, 128, "DoH AAAA: ");
|
||||
ptr = &buffer[10];
|
||||
len = 118;
|
||||
for(j = 0; j < 16; j += 2) {
|
||||
@@ -788,11 +788,11 @@ static void showdoh(struct Curl_easy *data,
|
||||
len -= l;
|
||||
ptr += l;
|
||||
}
|
||||
infof(data, "%s\n", buffer);
|
||||
infof(data, "%s", buffer);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < d->numcname; i++) {
|
||||
infof(data, "CNAME: %s\n", Curl_dyn_ptr(&d->cname[i]));
|
||||
infof(data, "CNAME: %s", Curl_dyn_ptr(&d->cname[i]));
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -803,7 +803,7 @@ static void showdoh(struct Curl_easy *data,
|
||||
* doh2ai()
|
||||
*
|
||||
* This function returns a pointer to the first element of a newly allocated
|
||||
* Curl_addrinfo struct linked list filled with the data from a set of DOH
|
||||
* Curl_addrinfo struct linked list filled with the data from a set of DoH
|
||||
* lookups. Curl_addrinfo is meant to work like the addrinfo struct does for
|
||||
* a IPv6 stack, but usable also for IPv4, all hosts and environments.
|
||||
*
|
||||
@@ -931,7 +931,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);
|
||||
failf(data, "Could not DoH-resolve: %s", data->state.async.hostname);
|
||||
return data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
@@ -941,7 +941,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
};
|
||||
struct dohentry de;
|
||||
int slot;
|
||||
/* remove DOH handles from multi handle and close them */
|
||||
/* remove DoH handles from multi handle and close them */
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
curl_multi_remove_handle(data->multi, dohp->probe[slot].easy);
|
||||
Curl_close(&dohp->probe[slot].easy);
|
||||
@@ -958,7 +958,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
&de);
|
||||
Curl_dyn_free(&p->serverdoh);
|
||||
if(rc[slot]) {
|
||||
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
|
||||
infof(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]),
|
||||
type2name(p->dnstype), dohp->host);
|
||||
}
|
||||
} /* next slot */
|
||||
@@ -969,7 +969,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
struct Curl_dns_entry *dns;
|
||||
struct Curl_addrinfo *ai;
|
||||
|
||||
infof(data, "DOH Host name: %s\n", dohp->host);
|
||||
infof(data, "DoH Host name: %s", dohp->host);
|
||||
showdoh(data, &de);
|
||||
|
||||
ai = doh2ai(&de, dohp->host, dohp->port);
|
||||
@@ -1007,7 +1007,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
|
||||
} /* !dohp->pending */
|
||||
|
||||
/* else wait for pending DOH transactions to complete */
|
||||
/* else wait for pending DoH transactions to complete */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ void de_init(struct dohentry *d);
|
||||
void de_cleanup(struct dohentry *d);
|
||||
#endif
|
||||
|
||||
#else /* if DOH is disabled */
|
||||
#else /* if DoH is disabled */
|
||||
#define Curl_doh(a,b,c,d) NULL
|
||||
#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#endif
|
||||
|
||||
+14
-7
@@ -117,7 +117,7 @@ curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
|
||||
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
|
||||
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
|
||||
curl_wcsdup_callback Curl_cwcsdup = Curl_wcsdup;
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
|
||||
@@ -417,13 +417,13 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
ev->list = nxt;
|
||||
free(m);
|
||||
m = nxt;
|
||||
infof(easy, "socket cb: socket %d REMOVED\n", s);
|
||||
infof(easy, "socket cb: socket %d REMOVED", s);
|
||||
}
|
||||
else {
|
||||
/* The socket 's' is already being monitored, update the activity
|
||||
mask. Convert from libcurl bitmask to the poll one. */
|
||||
m->socket.events = socketcb2poll(what);
|
||||
infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
|
||||
infof(easy, "socket cb: socket %d UPDATED as %s%s", s,
|
||||
(what&CURL_POLL_IN)?"IN":"",
|
||||
(what&CURL_POLL_OUT)?"OUT":"");
|
||||
}
|
||||
@@ -447,7 +447,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
m->socket.events = socketcb2poll(what);
|
||||
m->socket.revents = 0;
|
||||
ev->list = m;
|
||||
infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
|
||||
infof(easy, "socket cb: socket %d ADDED as %s%s", s,
|
||||
(what&CURL_POLL_IN)?"IN":"",
|
||||
(what&CURL_POLL_OUT)?"OUT":"");
|
||||
}
|
||||
@@ -532,7 +532,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
if(fds[i].revents) {
|
||||
/* socket activity, tell libcurl */
|
||||
int act = poll2cselect(fds[i].revents); /* convert */
|
||||
infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n",
|
||||
infof(multi->easyp, "call curl_multi_socket_action(socket %d)",
|
||||
fds[i].fd);
|
||||
mcode = curl_multi_socket_action(multi, fds[i].fd, act,
|
||||
&ev->running_handles);
|
||||
@@ -1027,7 +1027,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
|
||||
if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) {
|
||||
/* Not changing any pause state, return */
|
||||
DEBUGF(infof(data, "pause: no change, early return\n"));
|
||||
DEBUGF(infof(data, "pause: no change, early return"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -1213,9 +1213,16 @@ static int conn_upkeep(struct Curl_easy *data,
|
||||
/* Param is unused. */
|
||||
(void)param;
|
||||
|
||||
if(conn->handler->connection_check)
|
||||
if(conn->handler->connection_check) {
|
||||
/* briefly attach the connection to this transfer for the purpose of
|
||||
checking it */
|
||||
Curl_attach_connnection(data, conn);
|
||||
|
||||
/* Do a protocol-specific keepalive check on the connection. */
|
||||
conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
|
||||
/* detach the connection again */
|
||||
Curl_detach_connnection(data);
|
||||
}
|
||||
|
||||
return 0; /* continue iteration */
|
||||
}
|
||||
|
||||
+11
-5
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -865,8 +865,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
|
||||
if(post->flags & CURL_HTTPPOST_LARGE)
|
||||
clen = post->contentlen;
|
||||
if(!clen)
|
||||
clen = -1;
|
||||
|
||||
if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
|
||||
if(!strcmp(file->contents, "-")) {
|
||||
@@ -888,13 +886,21 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
else if(post->flags & HTTPPOST_BUFFER)
|
||||
result = curl_mime_data(part, post->buffer,
|
||||
post->bufferlength? post->bufferlength: -1);
|
||||
else if(post->flags & HTTPPOST_CALLBACK)
|
||||
else if(post->flags & HTTPPOST_CALLBACK) {
|
||||
/* the contents should be read with the callback and the size is set
|
||||
with the contentslength */
|
||||
if(!clen)
|
||||
clen = -1;
|
||||
result = curl_mime_data_cb(part, clen,
|
||||
fread_func, NULL, NULL, post->userp);
|
||||
}
|
||||
else {
|
||||
result = curl_mime_data(part, post->contents, (ssize_t) clen);
|
||||
size_t uclen;
|
||||
if(!clen)
|
||||
uclen = CURL_ZERO_TERMINATED;
|
||||
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)
|
||||
|
||||
@@ -289,7 +289,7 @@ static CURLcode AcceptServerConnect(struct Curl_easy *data)
|
||||
failf(data, "Error accept()ing server connect");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
infof(data, "Connection accepted from server\n");
|
||||
infof(data, "Connection accepted from server");
|
||||
/* when this happens within the DO state it is important that we mark us as
|
||||
not needing DO_MORE anymore */
|
||||
conn->bits.do_more = FALSE;
|
||||
@@ -380,7 +380,7 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
|
||||
*received = FALSE;
|
||||
|
||||
timeout_ms = ftp_timeleft_accept(data);
|
||||
infof(data, "Checking for server connect\n");
|
||||
infof(data, "Checking for server connect");
|
||||
if(timeout_ms < 0) {
|
||||
/* if a timeout was already reached, bail out */
|
||||
failf(data, "Accept timeout occurred while waiting server connect");
|
||||
@@ -390,7 +390,7 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
|
||||
/* First check whether there is a cached response from server */
|
||||
if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
|
||||
/* Data connection could not be established, let's return */
|
||||
infof(data, "There is negative response in cache while serv connect\n");
|
||||
infof(data, "There is negative response in cache while serv connect");
|
||||
(void)Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
@@ -408,11 +408,11 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
|
||||
default:
|
||||
|
||||
if(result & CURL_CSELECT_IN2) {
|
||||
infof(data, "Ready to accept data connection from server\n");
|
||||
infof(data, "Ready to accept data connection from server");
|
||||
*received = TRUE;
|
||||
}
|
||||
else if(result & CURL_CSELECT_IN) {
|
||||
infof(data, "Ctrl conn has data while waiting for data conn\n");
|
||||
infof(data, "Ctrl conn has data while waiting for data conn");
|
||||
(void)Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
|
||||
if(ftpcode/100 > 3)
|
||||
@@ -444,7 +444,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
|
||||
if(conn->bits.ftp_use_data_ssl) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
* do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream");
|
||||
result = Curl_ssl_connect(data, conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -487,7 +487,7 @@ static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected)
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*connected = FALSE;
|
||||
infof(data, "Preparing for accepting server on data port\n");
|
||||
infof(data, "Preparing for accepting server on data port");
|
||||
|
||||
/* Save the time we start accepting server connect */
|
||||
Curl_pgrsTime(data, TIMER_STARTACCEPT);
|
||||
@@ -592,7 +592,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!\n");
|
||||
infof(data, "We got a 421 - timeout!");
|
||||
state(data, FTP_STOP);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
@@ -768,7 +768,7 @@ static void _state(struct Curl_easy *data,
|
||||
(void) lineno;
|
||||
#else
|
||||
if(ftpc->state != newstate)
|
||||
infof(data, "FTP %p (line %d) state change from %s to %s\n",
|
||||
infof(data, "FTP %p (line %d) state change from %s to %s",
|
||||
(void *)ftpc, lineno, ftp_state_names[ftpc->state],
|
||||
ftp_state_names[newstate]);
|
||||
#endif
|
||||
@@ -1139,7 +1139,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
/* The requested bind address is not local. Use the address used for
|
||||
* the control connection instead and restart the port loop
|
||||
*/
|
||||
infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
|
||||
infof(data, "bind(port=%hu) on non-local address failed: %s", port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
sslen = sizeof(ss);
|
||||
@@ -1341,7 +1341,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
|
||||
if(!result) {
|
||||
ftpc->count1 = modeoff;
|
||||
state(data, FTP_PASV);
|
||||
infof(data, "Connect data stream passively\n");
|
||||
infof(data, "Connect data stream passively");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1648,7 +1648,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
|
||||
data->state.infilesize -= data->state.resume_from;
|
||||
|
||||
if(data->state.infilesize <= 0) {
|
||||
infof(data, "File already completely uploaded\n");
|
||||
infof(data, "File already completely uploaded");
|
||||
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
@@ -1802,7 +1802,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
infof(data, "Failed EPSV attempt. Disabling EPSV\n");
|
||||
infof(data, "Failed EPSV attempt. Disabling EPSV");
|
||||
/* disable it for next transfer */
|
||||
conn->bits.ftp_use_epsv = FALSE;
|
||||
data->state.errorbuf = FALSE; /* allow error message to get
|
||||
@@ -1921,7 +1921,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
if(data->set.ftp_skip_ip) {
|
||||
/* told to ignore the remotely given IP but instead use the host we used
|
||||
for the control connection */
|
||||
infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead\n",
|
||||
infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead",
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
conn->host.name);
|
||||
ftpc->newhost = strdup(control_address(conn));
|
||||
@@ -2044,7 +2044,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
|
||||
/* the command failed */
|
||||
|
||||
if(EPRT == fcmd) {
|
||||
infof(data, "disabling EPRT usage\n");
|
||||
infof(data, "disabling EPRT usage");
|
||||
conn->bits.ftp_use_eprt = FALSE;
|
||||
}
|
||||
fcmd++;
|
||||
@@ -2058,7 +2058,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
|
||||
result = ftp_state_use_port(data, fcmd);
|
||||
}
|
||||
else {
|
||||
infof(data, "Connect data stream actively\n");
|
||||
infof(data, "Connect data stream actively");
|
||||
state(data, FTP_STOP); /* end of DO phase */
|
||||
result = ftp_dophase_done(data, FALSE);
|
||||
}
|
||||
@@ -2128,7 +2128,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
infof(data, "unsupported MDTM reply format\n");
|
||||
infof(data, "unsupported MDTM reply format");
|
||||
break;
|
||||
case 550: /* "No such file or directory" */
|
||||
failf(data, "Given file does not exist");
|
||||
@@ -2142,7 +2142,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
case CURL_TIMECOND_IFMODSINCE:
|
||||
default:
|
||||
if(data->info.filetime <= data->set.timevalue) {
|
||||
infof(data, "The requested document is not new enough\n");
|
||||
infof(data, "The requested document is not new enough");
|
||||
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
||||
data->info.timecond = TRUE;
|
||||
state(data, FTP_STOP);
|
||||
@@ -2151,7 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
break;
|
||||
case CURL_TIMECOND_IFUNMODSINCE:
|
||||
if(data->info.filetime > data->set.timevalue) {
|
||||
infof(data, "The requested document is not old enough\n");
|
||||
infof(data, "The requested document is not old enough");
|
||||
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
||||
data->info.timecond = TRUE;
|
||||
state(data, FTP_STOP);
|
||||
@@ -2161,7 +2161,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
} /* switch */
|
||||
}
|
||||
else {
|
||||
infof(data, "Skipping time comparison\n");
|
||||
infof(data, "Skipping time comparison");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2186,7 +2186,7 @@ static CURLcode ftp_state_type_resp(struct Curl_easy *data,
|
||||
return CURLE_FTP_COULDNT_SET_TYPE;
|
||||
}
|
||||
if(ftpcode != 200)
|
||||
infof(data, "Got a %03d response code instead of the assumed 200\n",
|
||||
infof(data, "Got a %03d response code instead of the assumed 200",
|
||||
ftpcode);
|
||||
|
||||
if(instate == FTP_TYPE)
|
||||
@@ -2219,7 +2219,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
|
||||
/* We always (attempt to) get the size of downloads, so it is done before
|
||||
this even when not doing resumes. */
|
||||
if(filesize == -1) {
|
||||
infof(data, "ftp server doesn't support SIZE\n");
|
||||
infof(data, "ftp server doesn't support SIZE");
|
||||
/* We couldn't get the size and therefore we can't know if there really
|
||||
is a part of the file left to get, although the server will just
|
||||
close the connection when we start the connection so it won't cause
|
||||
@@ -2256,7 +2256,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
|
||||
if(ftp->downloadsize == 0) {
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
infof(data, "File already completely downloaded\n");
|
||||
infof(data, "File already completely downloaded");
|
||||
|
||||
/* Set ->transfer so that we won't get any error in ftp_done()
|
||||
* because we didn't transfer the any file */
|
||||
@@ -2267,7 +2267,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
|
||||
|
||||
/* Set resume file transfer offset */
|
||||
infof(data, "Instructs server to resume from offset %"
|
||||
CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
|
||||
CURL_FORMAT_CURL_OFF_T, data->state.resume_from);
|
||||
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
|
||||
data->state.resume_from);
|
||||
@@ -2413,7 +2413,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
|
||||
|
||||
if(!connected) {
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
infof(data, "Data conn was not available immediately\n");
|
||||
infof(data, "Data conn was not available immediately");
|
||||
ftpc->wait_data_conn = TRUE;
|
||||
}
|
||||
|
||||
@@ -2506,11 +2506,11 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||
else if((instate != FTP_LIST) && (data->state.prefer_ascii))
|
||||
size = -1; /* kludge for servers that understate ASCII mode file size */
|
||||
|
||||
infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n",
|
||||
infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T,
|
||||
data->req.maxdownload);
|
||||
|
||||
if(instate != FTP_LIST)
|
||||
infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n",
|
||||
infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T,
|
||||
size);
|
||||
|
||||
/* FTP download: */
|
||||
@@ -2526,7 +2526,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||
|
||||
if(!connected) {
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
infof(data, "Data conn was not available immediately\n");
|
||||
infof(data, "Data conn was not available immediately");
|
||||
state(data, FTP_STOP);
|
||||
ftpc->wait_data_conn = TRUE;
|
||||
}
|
||||
@@ -2681,9 +2681,12 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
/* we have now received a full FTP server response */
|
||||
switch(ftpc->state) {
|
||||
case FTP_WAIT220:
|
||||
if(ftpcode == 230)
|
||||
/* 230 User logged in - already! */
|
||||
return ftp_state_user_resp(data, ftpcode, ftpc->state);
|
||||
if(ftpcode == 230) {
|
||||
/* 230 User logged in - already! Take as 220 if TLS required. */
|
||||
if(data->set.use_ssl <= CURLUSESSL_TRY ||
|
||||
conn->bits.ftp_use_control_ssl)
|
||||
return ftp_state_user_resp(data, ftpcode, ftpc->state);
|
||||
}
|
||||
else if(ftpcode != 220) {
|
||||
failf(data, "Got a %03d ftp-server response when 220 was expected",
|
||||
ftpcode);
|
||||
@@ -2702,9 +2705,9 @@ 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!\n");
|
||||
infof(data, "Logging in with password in cleartext!");
|
||||
else
|
||||
infof(data, "Authentication successful\n");
|
||||
infof(data, "Authentication successful");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2740,6 +2743,9 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
case FTP_AUTH:
|
||||
/* we have gotten the response to a previous AUTH command */
|
||||
|
||||
if(pp->cache_size)
|
||||
return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */
|
||||
|
||||
/* RFC2228 (page 5) says:
|
||||
*
|
||||
* If the server is willing to accept the named security mechanism,
|
||||
@@ -2895,7 +2901,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
}
|
||||
Curl_safefree(ftpc->entrypath);
|
||||
ftpc->entrypath = dir; /* remember this */
|
||||
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
|
||||
infof(data, "Entry path is '%s'", ftpc->entrypath);
|
||||
/* also save it where getinfo can access it: */
|
||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||
state(data, FTP_SYST);
|
||||
@@ -2904,18 +2910,18 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
|
||||
Curl_safefree(ftpc->entrypath);
|
||||
ftpc->entrypath = dir; /* remember this */
|
||||
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
|
||||
infof(data, "Entry path is '%s'", ftpc->entrypath);
|
||||
/* also save it where getinfo can access it: */
|
||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||
}
|
||||
else {
|
||||
/* couldn't get the path */
|
||||
free(dir);
|
||||
infof(data, "Failed to figure out path\n");
|
||||
infof(data, "Failed to figure out path");
|
||||
}
|
||||
}
|
||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||
DEBUGF(infof(data, "protocol connect phase DONE\n"));
|
||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||
break;
|
||||
|
||||
case FTP_SYST:
|
||||
@@ -2962,7 +2968,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||
DEBUGF(infof(data, "protocol connect phase DONE\n"));
|
||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||
break;
|
||||
|
||||
case FTP_NAMEFMT:
|
||||
@@ -2973,7 +2979,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||
DEBUGF(infof(data, "protocol connect phase DONE\n"));
|
||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||
break;
|
||||
|
||||
case FTP_QUOTE:
|
||||
@@ -3272,7 +3278,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
}
|
||||
|
||||
if(ftpc->prevpath)
|
||||
infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
|
||||
infof(data, "Remembering we are in dir \"%s\"", ftpc->prevpath);
|
||||
}
|
||||
|
||||
/* free the dir tree and file parts */
|
||||
@@ -3338,7 +3344,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
if(ftpc->dont_check && data->req.maxdownload > 0) {
|
||||
/* we have just sent ABOR and there is no reliable way to check if it was
|
||||
* successful or not; we have to close the connection now */
|
||||
infof(data, "partial download completed, closing connection\n");
|
||||
infof(data, "partial download completed, closing connection");
|
||||
connclose(conn, "Partial download with no ability to check");
|
||||
return result;
|
||||
}
|
||||
@@ -3529,7 +3535,7 @@ ftp_pasv_verbose(struct Curl_easy *data,
|
||||
{
|
||||
char buf[256];
|
||||
Curl_printable_address(ai, buf, sizeof(buf));
|
||||
infof(data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
|
||||
infof(data, "Connecting to %s (%s) port %d", newhost, buf, port);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3569,7 +3575,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
|
||||
/* Ready to do more? */
|
||||
if(connected) {
|
||||
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
|
||||
DEBUGF(infof(data, "DO-MORE connected phase starts"));
|
||||
}
|
||||
else {
|
||||
if(result && (ftpc->count1 == 0)) {
|
||||
@@ -3644,8 +3650,13 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
return result;
|
||||
|
||||
result = ftp_multi_statemach(data, &complete);
|
||||
/* ftpc->wait_data_conn is always false here */
|
||||
*completep = (int)complete;
|
||||
if(ftpc->wait_data_conn)
|
||||
/* if we reach the end of the FTP state machine here, *complete will be
|
||||
TRUE but so is ftpc->wait_data_conn, which says we need to wait for
|
||||
the data connection and therefore we're not actually complete */
|
||||
*completep = 0;
|
||||
else
|
||||
*completep = (int)complete;
|
||||
}
|
||||
else {
|
||||
/* download */
|
||||
@@ -3692,7 +3703,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
if(!ftpc->wait_data_conn) {
|
||||
/* no waiting for the data connection so this is now complete */
|
||||
*completep = 1;
|
||||
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
|
||||
DEBUGF(infof(data, "DO-MORE phase ends with %d", (int)result));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -3717,7 +3728,7 @@ CURLcode ftp_perform(struct Curl_easy *data,
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts"));
|
||||
|
||||
if(data->set.opt_no_body) {
|
||||
/* requested no body means no transfer... */
|
||||
@@ -3737,10 +3748,10 @@ CURLcode ftp_perform(struct Curl_easy *data,
|
||||
|
||||
*connected = conn->bits.tcpconnect[SECONDARYSOCKET];
|
||||
|
||||
infof(data, "ftp_perform ends with SECONDARY: %d\n", *connected);
|
||||
infof(data, "ftp_perform ends with SECONDARY: %d", *connected);
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(data, "DO phase is complete1\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete1"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3834,7 +3845,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
|
||||
/* let the writefunc callback know the transfer */
|
||||
data->set.out = data;
|
||||
|
||||
infof(data, "Wildcard - Parsing started\n");
|
||||
infof(data, "Wildcard - Parsing started");
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
@@ -3901,7 +3912,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
|
||||
free(ftp->pathalloc);
|
||||
ftp->pathalloc = ftp->path = tmp_path;
|
||||
|
||||
infof(data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||
infof(data, "Wildcard - START of \"%s\"", finfo->filename);
|
||||
if(data->set.chunk_bgn) {
|
||||
long userresponse;
|
||||
Curl_set_in_callback(data, true);
|
||||
@@ -3910,7 +3921,7 @@ static CURLcode wc_statemach(struct Curl_easy *data)
|
||||
Curl_set_in_callback(data, false);
|
||||
switch(userresponse) {
|
||||
case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||
infof(data, "Wildcard - \"%s\" skipped by user\n",
|
||||
infof(data, "Wildcard - \"%s\" skipped by user",
|
||||
finfo->filename);
|
||||
wildcard->state = CURLWC_SKIP;
|
||||
continue;
|
||||
@@ -4233,7 +4244,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||
n -= ftpc->file?strlen(ftpc->file):0;
|
||||
|
||||
if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
|
||||
infof(data, "Request has same path as previous transfer\n");
|
||||
infof(data, "Request has same path as previous transfer");
|
||||
ftpc->cwddone = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -4279,11 +4290,11 @@ static CURLcode ftp_doing(struct Curl_easy *data,
|
||||
CURLcode result = ftp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(result)
|
||||
DEBUGF(infof(data, "DO phase failed\n"));
|
||||
DEBUGF(infof(data, "DO phase failed"));
|
||||
else if(*dophase_done) {
|
||||
result = ftp_dophase_done(data, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(data, "DO phase is complete2\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete2"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
|
||||
+2
-10
@@ -36,7 +36,7 @@
|
||||
|
||||
#include "hostcheck.h"
|
||||
#include "strcase.h"
|
||||
#include "inet_pton.h"
|
||||
#include "hostip.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@@ -67,10 +67,6 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
|
||||
int wildcard_enabled;
|
||||
size_t prefixlen, suffixlen;
|
||||
struct in_addr ignored;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 si6;
|
||||
#endif
|
||||
|
||||
/* normalize pattern and hostname by stripping off trailing dots */
|
||||
size_t len = strlen(hostname);
|
||||
@@ -86,12 +82,8 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* detect IP address as hostname and fail the match if so */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
|
||||
if(Curl_host_is_ipnum(hostname))
|
||||
return CURL_HOST_NOMATCH;
|
||||
#ifdef ENABLE_IPV6
|
||||
if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
|
||||
return CURL_HOST_NOMATCH;
|
||||
#endif
|
||||
|
||||
/* We require at least 2 dots in pattern to avoid too wide wildcard
|
||||
match. */
|
||||
|
||||
+156
-29
@@ -56,13 +56,13 @@
|
||||
#include "hash.h"
|
||||
#include "rand.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "inet_ntop.h"
|
||||
#include "inet_pton.h"
|
||||
#include "multiif.h"
|
||||
#include "doh.h"
|
||||
#include "warnless.h"
|
||||
#include "strcase.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -289,7 +289,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
|
||||
user.cache_timeout = data->set.dns_cache_timeout;
|
||||
|
||||
if(hostcache_timestamp_remove(&user, dns)) {
|
||||
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||
infof(data, "Hostname in DNS cache was stale, zapped");
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
|
||||
}
|
||||
@@ -460,6 +460,127 @@ Curl_cache_addr(struct Curl_easy *data,
|
||||
return dns;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/* return a static IPv6 resolve for 'localhost' */
|
||||
static struct Curl_addrinfo *get_localhost6(int port)
|
||||
{
|
||||
struct Curl_addrinfo *ca;
|
||||
const size_t ss_size = sizeof(struct sockaddr_in6);
|
||||
const size_t hostlen = strlen("localhost");
|
||||
struct sockaddr_in6 sa6;
|
||||
unsigned char ipv6[16];
|
||||
unsigned short port16 = (unsigned short)(port & 0xffff);
|
||||
ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
|
||||
if(!ca)
|
||||
return NULL;
|
||||
|
||||
sa6.sin6_family = AF_INET6;
|
||||
sa6.sin6_port = htons(port16);
|
||||
sa6.sin6_flowinfo = 0;
|
||||
sa6.sin6_scope_id = 0;
|
||||
if(Curl_inet_pton(AF_INET6, "::1", ipv6) < 1)
|
||||
return NULL;
|
||||
memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6));
|
||||
|
||||
ca->ai_flags = 0;
|
||||
ca->ai_family = AF_INET6;
|
||||
ca->ai_socktype = SOCK_STREAM;
|
||||
ca->ai_protocol = IPPROTO_TCP;
|
||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||
ca->ai_next = NULL;
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, &sa6, ss_size);
|
||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||
strcpy(ca->ai_canonname, "localhost");
|
||||
return ca;
|
||||
}
|
||||
#else
|
||||
#define get_localhost6(x) NULL
|
||||
#endif
|
||||
|
||||
/* return a static IPv4 resolve for 'localhost' */
|
||||
static struct Curl_addrinfo *get_localhost(int port)
|
||||
{
|
||||
struct Curl_addrinfo *ca;
|
||||
const size_t ss_size = sizeof(struct sockaddr_in);
|
||||
const size_t hostlen = strlen("localhost");
|
||||
struct sockaddr_in sa;
|
||||
unsigned int ipv4;
|
||||
unsigned short port16 = (unsigned short)(port & 0xffff);
|
||||
ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
|
||||
if(!ca)
|
||||
return NULL;
|
||||
|
||||
/* memset to clear the sa.sin_zero field */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(port16);
|
||||
if(Curl_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4) < 1)
|
||||
return NULL;
|
||||
memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4));
|
||||
|
||||
ca->ai_flags = 0;
|
||||
ca->ai_family = AF_INET;
|
||||
ca->ai_socktype = SOCK_STREAM;
|
||||
ca->ai_protocol = IPPROTO_TCP;
|
||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, &sa, ss_size);
|
||||
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||
strcpy(ca->ai_canonname, "localhost");
|
||||
ca->ai_next = get_localhost6(port);
|
||||
return ca;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(struct Curl_easy *data)
|
||||
{
|
||||
if(data) {
|
||||
/* the nature of most system is that IPv6 status doesn't come and go
|
||||
during a program's lifetime so we only probe the first time and then we
|
||||
have the info kept for fast re-use */
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
return data->multi->ipv6_works;
|
||||
}
|
||||
else {
|
||||
int ipv6_works = -1;
|
||||
/* probe to see if we have a working IPv6 stack */
|
||||
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if(s == CURL_SOCKET_BAD)
|
||||
/* an IPv6 address was requested but we can't get/use one */
|
||||
ipv6_works = 0;
|
||||
else {
|
||||
ipv6_works = 1;
|
||||
sclose(s);
|
||||
}
|
||||
return (ipv6_works>0)?TRUE:FALSE;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
/*
|
||||
* Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4
|
||||
* (or IPv6 if supported) address.
|
||||
*/
|
||||
bool Curl_host_is_ipnum(const char *hostname)
|
||||
{
|
||||
struct in_addr in;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr in6;
|
||||
#endif
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0
|
||||
#ifdef ENABLE_IPV6
|
||||
|| Curl_inet_pton(AF_INET6, hostname, &in6) > 0
|
||||
#endif
|
||||
)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolv() is the main name resolve function within libcurl. It resolves
|
||||
* a name and returns a pointer to the entry in the 'entry' argument (if one
|
||||
@@ -487,7 +608,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||
CURLcode result;
|
||||
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
*entry = NULL;
|
||||
conn->bits.doh = FALSE; /* default is not */
|
||||
|
||||
@@ -497,7 +617,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||
dns = fetch_addr(data, hostname, port);
|
||||
|
||||
if(dns) {
|
||||
infof(data, "Hostname %s was found in DNS cache\n", hostname);
|
||||
infof(data, "Hostname %s was found in DNS cache", hostname);
|
||||
dns->inuse++; /* we use it! */
|
||||
rc = CURLRESOLV_RESOLVED;
|
||||
}
|
||||
@@ -534,16 +654,20 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
|
||||
/*
|
||||
* The automagic conversion from IPv4 literals to IPv6 literals only works
|
||||
* if the SCDynamicStoreCopyProxies system function gets called first. As
|
||||
* Curl currently doesn't support system-wide HTTP proxies, we therefore
|
||||
* don't use any value this function might return.
|
||||
*
|
||||
* This function is only available on a macOS and is not needed for
|
||||
* IPv4-only builds, hence the conditions above.
|
||||
*/
|
||||
SCDynamicStoreCopyProxies(NULL);
|
||||
{
|
||||
/*
|
||||
* The automagic conversion from IPv4 literals to IPv6 literals only
|
||||
* works if the SCDynamicStoreCopyProxies system function gets called
|
||||
* first. As Curl currently doesn't support system-wide HTTP proxies, we
|
||||
* therefore don't use any value this function might return.
|
||||
*
|
||||
* This function is only available on a macOS and is not needed for
|
||||
* IPv4-only builds, hence the conditions above.
|
||||
*/
|
||||
CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
|
||||
if(dict)
|
||||
CFRelease(dict);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
@@ -579,15 +703,18 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||
#endif /* !USE_RESOLVE_ON_IPS */
|
||||
|
||||
if(!addr) {
|
||||
/* Check what IP specifics the app has requested and if we can provide
|
||||
* it. If not, bail out. */
|
||||
if(!Curl_ipvalid(data, conn))
|
||||
if(conn->ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data))
|
||||
return CURLRESOLV_ERROR;
|
||||
|
||||
if(allowDOH && data->set.doh && !ipnum) {
|
||||
if(strcasecompare(hostname, "localhost"))
|
||||
addr = get_localhost(port);
|
||||
else if(allowDOH && data->set.doh && !ipnum)
|
||||
addr = Curl_doh(data, hostname, port, &respwait);
|
||||
}
|
||||
else {
|
||||
/* Check what IP specifics the app has requested and if we can provide
|
||||
* it. If not, bail out. */
|
||||
if(!Curl_ipvalid(data, conn))
|
||||
return CURLRESOLV_ERROR;
|
||||
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
|
||||
non-zero value indicating that we need to wait for the response to
|
||||
the resolve call */
|
||||
@@ -757,7 +884,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
|
||||
#else
|
||||
#ifndef CURLRES_ASYNCH
|
||||
if(timeoutms)
|
||||
infof(data, "timeout on name lookup is not supported\n");
|
||||
infof(data, "timeout on name lookup is not supported");
|
||||
#else
|
||||
(void)timeoutms; /* timeoutms not used with an async resolver */
|
||||
#endif
|
||||
@@ -895,7 +1022,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
size_t entry_len;
|
||||
|
||||
if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
|
||||
infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
|
||||
infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'",
|
||||
hostp->data);
|
||||
continue;
|
||||
}
|
||||
@@ -984,7 +1111,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
if(strchr(address, ':')) {
|
||||
infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n",
|
||||
infof(data, "Ignoring resolve address '%s', missing IPv6 support.",
|
||||
address);
|
||||
continue;
|
||||
}
|
||||
@@ -992,7 +1119,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
ai = Curl_str2addr(address, port);
|
||||
if(!ai) {
|
||||
infof(data, "Resolve address '%s' found illegal!\n", address);
|
||||
infof(data, "Resolve address '%s' found illegal!", address);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -1011,10 +1138,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
error = false;
|
||||
err:
|
||||
if(error) {
|
||||
infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
|
||||
failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!",
|
||||
hostp->data);
|
||||
Curl_freeaddrinfo(head);
|
||||
continue;
|
||||
return CURLE_SETOPT_OPTION_SYNTAX;
|
||||
}
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
@@ -1028,7 +1155,7 @@ 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!\n",
|
||||
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.
|
||||
@@ -1061,12 +1188,12 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
Curl_freeaddrinfo(head);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
infof(data, "Added %s:%d:%s to DNS cache%s\n",
|
||||
infof(data, "Added %s:%d:%s to DNS cache%s",
|
||||
hostname, port, addresses, permanent ? "" : " (non-permanent)");
|
||||
|
||||
/* Wildcard hostname */
|
||||
if(hostname[0] == '*' && hostname[1] == '\0') {
|
||||
infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n",
|
||||
infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks",
|
||||
hostname, port);
|
||||
data->state.wildcard_resolve = true;
|
||||
}
|
||||
@@ -1094,7 +1221,7 @@ int Curl_resolv_getsock(struct Curl_easy *data,
|
||||
{
|
||||
#ifdef CURLRES_ASYNCH
|
||||
if(data->conn->bits.doh)
|
||||
/* nothing to wait for during DOH resolve, those handles have their own
|
||||
/* nothing to wait for during DoH resolve, those handles have their own
|
||||
sockets */
|
||||
return GETSOCK_BLANK;
|
||||
return Curl_resolver_getsock(data, socks);
|
||||
|
||||
+3
-1
@@ -71,6 +71,8 @@ struct Curl_dns_entry {
|
||||
long inuse;
|
||||
};
|
||||
|
||||
bool Curl_host_is_ipnum(const char *hostname);
|
||||
|
||||
/*
|
||||
* Curl_resolv() returns an entry with the info for the specified host
|
||||
* and port.
|
||||
@@ -95,7 +97,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
|
||||
struct Curl_dns_entry **dnsentry,
|
||||
timediff_t timeoutms);
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
|
||||
+1
-2
@@ -50,7 +50,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -104,7 +103,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||
|
||||
ai = Curl_ipv4_resolve_r(hostname, port);
|
||||
if(!ai)
|
||||
infof(data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
|
||||
infof(data, "Curl_ipv4_resolve_r failed for %s", hostname);
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
+1
-30
@@ -50,7 +50,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "inet_pton.h"
|
||||
#include "connect.h"
|
||||
@@ -59,34 +58,6 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(struct Curl_easy *data)
|
||||
{
|
||||
if(data) {
|
||||
/* the nature of most system is that IPv6 status doesn't come and go
|
||||
during a program's lifetime so we only probe the first time and then we
|
||||
have the info kept for fast re-use */
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
return data->multi->ipv6_works;
|
||||
}
|
||||
else {
|
||||
int ipv6_works = -1;
|
||||
/* probe to see if we have a working IPv6 stack */
|
||||
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if(s == CURL_SOCKET_BAD)
|
||||
/* an IPv6 address was requested but we can't get/use one */
|
||||
ipv6_works = 0;
|
||||
else {
|
||||
ipv6_works = 1;
|
||||
sclose(s);
|
||||
}
|
||||
return (ipv6_works>0)?TRUE:FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
@@ -172,7 +143,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||
|
||||
error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
|
||||
if(error) {
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d", hostname, port);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
|
||||
+8
-1
@@ -138,6 +138,11 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
struct stsentry *sts;
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(Curl_host_is_ipnum(hostname))
|
||||
/* "explicit IP address identification of all forms is excluded."
|
||||
/ RFC 6797 */
|
||||
return CURLE_OK;
|
||||
|
||||
do {
|
||||
while(*p && ISSPACE(*p))
|
||||
p++;
|
||||
@@ -521,7 +526,9 @@ CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
|
||||
*/
|
||||
CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
|
||||
{
|
||||
return hsts_pull(data, h);
|
||||
if(h)
|
||||
return hsts_pull(data, h);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
|
||||
|
||||
+158
-123
@@ -504,7 +504,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
infof(data, "Rewind stream after send");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -515,7 +515,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
|
||||
infof(data, "NTLM send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
@@ -532,7 +532,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
infof(data, "Rewind stream after send");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -543,7 +543,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
|
||||
infof(data, "NEGOTIATE send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
@@ -756,14 +756,14 @@ output_auth_headers(struct Curl_easy *data,
|
||||
|
||||
if(auth) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
infof(data, "%s auth using %s with user '%s'\n",
|
||||
infof(data, "%s auth using %s with user '%s'",
|
||||
proxy ? "Proxy" : "Server", auth,
|
||||
proxy ? (data->state.aptr.proxyuser ?
|
||||
data->state.aptr.proxyuser : "") :
|
||||
(data->state.aptr.user ?
|
||||
data->state.aptr.user : ""));
|
||||
#else
|
||||
infof(data, "Server auth using %s with user '%s'\n",
|
||||
infof(data, "Server auth using %s with user '%s'",
|
||||
auth, data->state.aptr.user ?
|
||||
data->state.aptr.user : "");
|
||||
#endif
|
||||
@@ -850,7 +850,9 @@ Curl_http_output_auth(struct Curl_easy *data,
|
||||
/* 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 ||
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
conn->bits.netrc ||
|
||||
#endif
|
||||
!data->state.first_host ||
|
||||
data->set.allow_auth_to_other_hosts ||
|
||||
strcasecompare(data->state.first_host, conn->host.name)) {
|
||||
@@ -995,14 +997,14 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
|
||||
result = Curl_input_ntlm_wb(data, conn, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
infof(data, "Authentication problem. Ignoring this.");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
infof(data, "Authentication problem. Ignoring this.");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1013,7 +1015,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0)
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
infof(data, "Ignoring duplicate digest auth header.");
|
||||
else if(Curl_auth_is_digest_supported()) {
|
||||
CURLcode result;
|
||||
|
||||
@@ -1026,7 +1028,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
* Digest */
|
||||
result = Curl_input_digest(data, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
infof(data, "Authentication problem. Ignoring this.");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1042,7 +1044,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
anyway, which basically means our name+password isn't
|
||||
valid. */
|
||||
authp->avail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
infof(data, "Authentication problem. Ignoring this.");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1055,7 +1057,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
/* We asked for Bearer authentication but got a 40X back
|
||||
anyway, which basically means our token isn't valid. */
|
||||
authp->avail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
infof(data, "Authentication problem. Ignoring this.");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1177,6 +1179,7 @@ static size_t readmoredata(char *buffer,
|
||||
data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
|
||||
|
||||
if(data->set.max_send_speed &&
|
||||
(data->set.max_send_speed < (curl_off_t)fullsize) &&
|
||||
(data->set.max_send_speed < http->postsize))
|
||||
/* speed limit */
|
||||
fullsize = (size_t)data->set.max_send_speed;
|
||||
@@ -1537,38 +1540,35 @@ static int http_getsock_do(struct Curl_easy *data,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
|
||||
{
|
||||
char proxy_header[128];
|
||||
struct dynbuf req;
|
||||
CURLcode result;
|
||||
char tcp_version[5];
|
||||
const char *tcp_version;
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
if(data->conn->bits.ipv6) {
|
||||
strcpy(tcp_version, "TCP6");
|
||||
}
|
||||
else {
|
||||
strcpy(tcp_version, "TCP4");
|
||||
}
|
||||
|
||||
msnprintf(proxy_header,
|
||||
sizeof(proxy_header),
|
||||
"PROXY %s %s %s %i %i\r\n",
|
||||
tcp_version,
|
||||
data->info.conn_local_ip,
|
||||
data->info.conn_primary_ip,
|
||||
data->info.conn_local_port,
|
||||
data->info.conn_primary_port);
|
||||
|
||||
Curl_dyn_init(&req, DYN_HAXPROXY);
|
||||
|
||||
result = Curl_dyn_add(&req, proxy_header);
|
||||
if(result)
|
||||
return result;
|
||||
#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");
|
||||
else {
|
||||
#endif
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
tcp_version = data->conn->bits.ipv6 ? "TCP6" : "TCP4";
|
||||
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size,
|
||||
0, FIRSTSOCKET);
|
||||
result = Curl_dyn_addf(&req, "PROXY %s %s %s %i %i\r\n",
|
||||
tcp_version,
|
||||
data->info.conn_local_ip,
|
||||
data->info.conn_primary_ip,
|
||||
data->info.conn_local_port,
|
||||
data->info.conn_primary_port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!result)
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size,
|
||||
0, FIRSTSOCKET);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@@ -1588,7 +1588,7 @@ static CURLcode https_connecting(struct Curl_easy *data, bool *done)
|
||||
#endif
|
||||
|
||||
/* perform SSL initialization for this socket */
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, done);
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, done);
|
||||
if(result)
|
||||
connclose(conn, "Failed HTTPS connection");
|
||||
|
||||
@@ -1669,8 +1669,8 @@ CURLcode Curl_http_done(struct Curl_easy *data,
|
||||
* - if any server previously contacted to handle this request only supports
|
||||
* 1.0.
|
||||
*/
|
||||
static bool use_http_1_1plus(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
bool Curl_use_http_1_1plus(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
if((data->state.httpversion == 10) || (conn->httpversion == 10))
|
||||
return FALSE;
|
||||
@@ -1696,7 +1696,7 @@ static const char *get_http_string(const struct Curl_easy *data,
|
||||
return "2";
|
||||
#endif
|
||||
|
||||
if(use_http_1_1plus(data, conn))
|
||||
if(Curl_use_http_1_1plus(data, conn))
|
||||
return "1.1";
|
||||
|
||||
return "1.0";
|
||||
@@ -1711,7 +1711,7 @@ static CURLcode expect100(struct Curl_easy *data,
|
||||
CURLcode result = CURLE_OK;
|
||||
data->state.expect100header = FALSE; /* default to false unless it is set
|
||||
to TRUE below */
|
||||
if(!data->state.disableexpect && use_http_1_1plus(data, conn) &&
|
||||
if(!data->state.disableexpect && Curl_use_http_1_1plus(data, conn) &&
|
||||
(conn->httpversion < 20)) {
|
||||
/* 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
|
||||
@@ -2348,7 +2348,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
if(conn->bits.authneg)
|
||||
/* don't enable chunked during auth neg */
|
||||
;
|
||||
else if(use_http_1_1plus(data, conn)) {
|
||||
else if(Curl_use_http_1_1plus(data, conn)) {
|
||||
if(conn->httpversion < 20)
|
||||
/* HTTP, upload, unknown file size and not HTTP 1.0 */
|
||||
data->req.upload_chunky = TRUE;
|
||||
@@ -2711,14 +2711,16 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
int count = 0;
|
||||
|
||||
if(data->cookies && data->state.cookie_engine) {
|
||||
const char *host = data->state.aptr.cookiehost ?
|
||||
data->state.aptr.cookiehost : conn->host.name;
|
||||
const bool secure_context =
|
||||
conn->handler->protocol&CURLPROTO_HTTPS ||
|
||||
strcasecompare("localhost", host) ||
|
||||
!strcmp(host, "127.0.0.1") ||
|
||||
!strcmp(host, "[::1]") ? TRUE : FALSE;
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
co = Curl_cookie_getlist(data->cookies,
|
||||
data->state.aptr.cookiehost?
|
||||
data->state.aptr.cookiehost:
|
||||
conn->host.name,
|
||||
data->state.up.path,
|
||||
(conn->handler->protocol&CURLPROTO_HTTPS)?
|
||||
TRUE:FALSE);
|
||||
co = Curl_cookie_getlist(data->cookies, host, data->state.up.path,
|
||||
secure_context);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
if(co) {
|
||||
@@ -2901,6 +2903,20 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
DEBUGASSERT(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP));
|
||||
if(data->req.ignore_cl) {
|
||||
k->size = k->maxdownload = -1;
|
||||
}
|
||||
else if(k->size != -1) {
|
||||
/* We wait until after all headers have been received to set this so that
|
||||
we know for sure Content-Length is valid. */
|
||||
if(data->set.max_filesize &&
|
||||
k->size > data->set.max_filesize) {
|
||||
failf(data, "Maximum file size exceeded");
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
}
|
||||
Curl_pgrsSetDownloadSize(data, k->size);
|
||||
}
|
||||
|
||||
if(data->req.newurl) {
|
||||
if(conn->bits.close) {
|
||||
/* Abort after the headers if "follow Location" is set
|
||||
@@ -2912,7 +2928,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
/* We have a new url to load, but since we want to be able to re-use this
|
||||
connection properly, we read the full response in "ignore more" */
|
||||
k->ignorebody = TRUE;
|
||||
infof(data, "Ignoring the response-body\n");
|
||||
infof(data, "Ignoring the response-body");
|
||||
}
|
||||
if(data->state.resume_from && !k->content_range &&
|
||||
(data->state.httpreq == HTTPREQ_GET) &&
|
||||
@@ -2947,7 +2963,7 @@ 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!\n");
|
||||
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");
|
||||
@@ -2958,6 +2974,39 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
CURLcode Curl_transferencode(struct Curl_easy *data)
|
||||
{
|
||||
if(!Curl_checkheaders(data, "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");
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(data->state.aptr.te);
|
||||
|
||||
if(cptr) {
|
||||
cptr = Curl_copy_header_value(cptr);
|
||||
if(!cptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Create the (updated) Connection: header */
|
||||
data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
|
||||
cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
|
||||
|
||||
free(cptr);
|
||||
if(!data->state.aptr.te)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_HYPER
|
||||
/*
|
||||
* Curl_http() gets called from the generic multi_do() function when a HTTP
|
||||
@@ -3004,11 +3053,11 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
/* We don't support HTTP/2 proxies yet. Also it's debatable
|
||||
whether or not this setting should apply to HTTP/2 proxies. */
|
||||
infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
|
||||
infof(data, "Ignoring HTTP/2 prior knowledge due to proxy");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
|
||||
DEBUGF(infof(data, "HTTP/2 over clean TCP"));
|
||||
conn->httpversion = 20;
|
||||
|
||||
result = Curl_http2_switched(data, NULL, 0);
|
||||
@@ -3074,33 +3123,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
/* we only consider transfer-encoding magic if libz support is built-in */
|
||||
|
||||
if(!Curl_checkheaders(data, "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");
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(data->state.aptr.te);
|
||||
|
||||
if(cptr) {
|
||||
cptr = Curl_copy_header_value(cptr);
|
||||
if(!cptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Create the (updated) Connection: header */
|
||||
data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
|
||||
cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
|
||||
|
||||
free(cptr);
|
||||
if(!data->state.aptr.te)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_transferencode(data);
|
||||
if(result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
result = Curl_http_body(data, conn, httpreq, &te);
|
||||
@@ -3253,7 +3278,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
/* already sent the entire request body, mark the "upload" as
|
||||
complete */
|
||||
infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
|
||||
" out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
" out of %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
data->req.writebytecount, http->postsize);
|
||||
data->req.upload_done = TRUE;
|
||||
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
||||
@@ -3392,17 +3417,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
NULL, 10, &contentlength);
|
||||
|
||||
if(offt == CURL_OFFT_OK) {
|
||||
if(data->set.max_filesize &&
|
||||
contentlength > data->set.max_filesize) {
|
||||
failf(data, "Maximum file size exceeded");
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
}
|
||||
k->size = contentlength;
|
||||
k->maxdownload = k->size;
|
||||
/* we set the progress download size already at this point
|
||||
just to make it easier for apps/callbacks to extract this
|
||||
info as soon as possible */
|
||||
Curl_pgrsSetDownloadSize(data, k->size);
|
||||
}
|
||||
else if(offt == CURL_OFFT_FLOW) {
|
||||
/* out of range */
|
||||
@@ -3411,7 +3427,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!\n");
|
||||
infof(data, "Overflow Content-Length: value!");
|
||||
}
|
||||
else {
|
||||
/* negative or just rubbish - bad HTTP */
|
||||
@@ -3443,7 +3459,7 @@ 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!\n");
|
||||
infof(data, "HTTP/1.0 proxy connection set to keep alive!");
|
||||
}
|
||||
else if((conn->httpversion == 11) &&
|
||||
conn->bits.httpproxy &&
|
||||
@@ -3453,7 +3469,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
* close down after this transfer.
|
||||
*/
|
||||
connclose(conn, "Proxy-Connection: asked to close after done");
|
||||
infof(data, "HTTP/1.1 proxy connection set close!\n");
|
||||
infof(data, "HTTP/1.1 proxy connection set close!");
|
||||
}
|
||||
#endif
|
||||
else if((conn->httpversion == 10) &&
|
||||
@@ -3465,7 +3481,7 @@ 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!\n");
|
||||
infof(data, "HTTP/1.0 connection set to keep alive!");
|
||||
}
|
||||
else if(Curl_compareheader(headp, "Connection:", "close")) {
|
||||
/*
|
||||
@@ -3493,6 +3509,12 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
if(!k->chunk) {
|
||||
/* if this isn't chunked, only close can signal the end of this transfer
|
||||
as Content-Length is said not to be trusted for transfer-encoding! */
|
||||
connclose(conn, "HTTP/1.1 transfer-encoding without chunks");
|
||||
k->ignore_cl = TRUE;
|
||||
}
|
||||
}
|
||||
else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
@@ -3555,18 +3577,21 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
else if(data->cookies && data->state.cookie_engine &&
|
||||
checkprefix("Set-Cookie:", headp)) {
|
||||
/* If there is a custom-set Host: name, use it here, or else use real peer
|
||||
host name. */
|
||||
const char *host = data->state.aptr.cookiehost?
|
||||
data->state.aptr.cookiehost:conn->host.name;
|
||||
const bool secure_context =
|
||||
conn->handler->protocol&CURLPROTO_HTTPS ||
|
||||
strcasecompare("localhost", host) ||
|
||||
!strcmp(host, "127.0.0.1") ||
|
||||
!strcmp(host, "[::1]") ? TRUE : FALSE;
|
||||
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
|
||||
CURL_LOCK_ACCESS_SINGLE);
|
||||
Curl_cookie_add(data,
|
||||
data->cookies, TRUE, FALSE,
|
||||
headp + strlen("Set-Cookie:"),
|
||||
/* If there is a custom-set Host: name, use it
|
||||
here, or else use real peer host name. */
|
||||
data->state.aptr.cookiehost?
|
||||
data->state.aptr.cookiehost:conn->host.name,
|
||||
data->state.up.path,
|
||||
(conn->handler->protocol&CURLPROTO_HTTPS)?
|
||||
TRUE:FALSE);
|
||||
Curl_cookie_add(data, data->cookies, TRUE, FALSE,
|
||||
headp + strlen("Set-Cookie:"), host,
|
||||
data->state.up.path, secure_context);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
#endif
|
||||
@@ -3646,10 +3671,10 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
Curl_hsts_parse(data->hsts, data->state.up.hostname,
|
||||
headp + strlen("Strict-Transport-Security:"));
|
||||
if(check)
|
||||
infof(data, "Illegal STS header skipped\n");
|
||||
infof(data, "Illegal STS header skipped");
|
||||
#ifdef DEBUGBUILD
|
||||
else
|
||||
infof(data, "Parsed STS header fine (%zu entries)\n",
|
||||
infof(data, "Parsed STS header fine (%zu entries)",
|
||||
data->hsts->list.size);
|
||||
#endif
|
||||
}
|
||||
@@ -3719,12 +3744,12 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
|
||||
/* Default action for HTTP/1.0 must be to close, unless
|
||||
we get one of those fancy headers that tell us the
|
||||
server keeps it open for us! */
|
||||
infof(data, "HTTP 1.0, assume close after body\n");
|
||||
infof(data, "HTTP 1.0, assume close after body");
|
||||
connclose(conn, "HTTP/1.0 close after body");
|
||||
}
|
||||
else if(conn->httpversion == 20 ||
|
||||
(k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
|
||||
DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
|
||||
DEBUGF(infof(data, "HTTP/2 found, allow multiplexing"));
|
||||
/* HTTP/2 cannot avoid multiplexing since it is a core functionality
|
||||
of the protocol */
|
||||
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
||||
@@ -3733,7 +3758,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
|
||||
!conn->bits.close) {
|
||||
/* If HTTP version is >= 1.1 and connection is persistent */
|
||||
DEBUGF(infof(data,
|
||||
"HTTP 1.1 or later with persistent connection\n"));
|
||||
"HTTP 1.1 or later with persistent connection"));
|
||||
}
|
||||
|
||||
k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200;
|
||||
@@ -3911,7 +3936,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
/* Switching Protocols */
|
||||
if(k->upgr101 == UPGR101_REQUESTED) {
|
||||
/* Switching to HTTP/2 */
|
||||
infof(data, "Received 101\n");
|
||||
infof(data, "Received 101");
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
|
||||
/* we'll get more headers (HTTP/2 response) */
|
||||
@@ -3951,7 +3976,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
assume that the server will close the connection to
|
||||
signal the end of the document. */
|
||||
infof(data, "no chunk, no close, no size. Assume close to "
|
||||
"signal end\n");
|
||||
"signal end");
|
||||
streamclose(conn, "HTTP: No end-of-message indicator");
|
||||
}
|
||||
}
|
||||
@@ -3964,7 +3989,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
#endif
|
||||
@@ -3974,7 +3999,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
(conn->http_negotiate_state == GSS_AUTHRECV)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
if((conn->http_negotiate_state == GSS_AUTHDONE) &&
|
||||
@@ -4054,21 +4079,21 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if((k->httpcode == 417) && data->state.expect100header) {
|
||||
/* 417 Expectation Failed - try again without the Expect
|
||||
header */
|
||||
infof(data, "Got 417 while waiting for a 100\n");
|
||||
infof(data, "Got 417 while waiting for a 100");
|
||||
data->state.disableexpect = TRUE;
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->state.url);
|
||||
Curl_done_sending(data, k);
|
||||
}
|
||||
else if(data->set.http_keep_sending_on_error) {
|
||||
infof(data, "HTTP error before end of send, keep sending\n");
|
||||
infof(data, "HTTP error before end of send, keep sending");
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
infof(data, "HTTP error before end of send, stop sending");
|
||||
streamclose(conn, "Stop sending data before everything sent");
|
||||
result = Curl_done_sending(data, k);
|
||||
if(result)
|
||||
@@ -4088,7 +4113,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!\n");
|
||||
infof(data, "Keep sending data to get tossed away!");
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
}
|
||||
@@ -4201,18 +4226,20 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* https://tools.ietf.org/html/rfc7230#section-3.1.2
|
||||
*
|
||||
* The response code is always a three-digit number in HTTP as the spec
|
||||
* says. We try to allow any number here, but we cannot make
|
||||
* says. We allow any three-digit number here, but we cannot make
|
||||
* guarantees on future behaviors since it isn't within the protocol.
|
||||
*/
|
||||
char separator;
|
||||
char twoorthree[2];
|
||||
int httpversion = 0;
|
||||
int digit4 = -1; /* should remain untouched to be good */
|
||||
nc = sscanf(HEADER1,
|
||||
" HTTP/%1d.%1d%c%3d",
|
||||
" HTTP/%1d.%1d%c%3d%1d",
|
||||
&httpversion_major,
|
||||
&httpversion,
|
||||
&separator,
|
||||
&k->httpcode);
|
||||
&k->httpcode,
|
||||
&digit4);
|
||||
|
||||
if(nc == 1 && httpversion_major >= 2 &&
|
||||
2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
|
||||
@@ -4221,6 +4248,14 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
separator = ' ';
|
||||
}
|
||||
|
||||
/* There can only be a 4th response code digit stored in 'digit4' if
|
||||
all the other fields were parsed and stored first, so nc is 5 when
|
||||
digit4 is not -1 */
|
||||
else if(digit4 != -1) {
|
||||
failf(data, "Unsupported response code in HTTP response");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
if((nc == 4) && (' ' == separator)) {
|
||||
httpversion += 10 * httpversion_major;
|
||||
switch(httpversion) {
|
||||
@@ -4243,11 +4278,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(k->upgr101 == UPGR101_RECEIVED) {
|
||||
/* supposedly upgraded to http2 now */
|
||||
if(conn->httpversion != 20)
|
||||
infof(data, "Lying server, not serving HTTP/2\n");
|
||||
infof(data, "Lying server, not serving HTTP/2");
|
||||
}
|
||||
if(conn->httpversion < 20) {
|
||||
conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
|
||||
infof(data, "Mark bundle as not supporting multiuse\n");
|
||||
infof(data, "Mark bundle as not supporting multiuse");
|
||||
}
|
||||
}
|
||||
else if(!nc) {
|
||||
|
||||
@@ -93,11 +93,14 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
char *headp);
|
||||
CURLcode Curl_transferencode(struct Curl_easy *data);
|
||||
CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
Curl_HttpReq httpreq,
|
||||
const char **teep);
|
||||
CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
struct dynbuf *r, Curl_HttpReq httpreq);
|
||||
bool Curl_use_http_1_1plus(const struct Curl_easy *data,
|
||||
const struct connectdata *conn);
|
||||
#ifndef CURL_DISABLE_COOKIES
|
||||
CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
|
||||
+96
-99
@@ -146,12 +146,12 @@ static CURLcode http2_disconnect(struct Curl_easy *data,
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT done\n"));
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT done"));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -196,11 +196,13 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
|
||||
data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
||||
if(nread != -1) {
|
||||
infof(data,
|
||||
"%d bytes stray data read before trying h2 connection\n",
|
||||
"%d bytes stray data read before trying h2 connection",
|
||||
(int)nread);
|
||||
httpc->nread_inbuf = 0;
|
||||
httpc->inbuflen = nread;
|
||||
(void)h2_process_pending_input(data, httpc, &result);
|
||||
if(h2_process_pending_input(data, httpc, &result) < 0)
|
||||
/* immediate error, considered dead */
|
||||
dead = TRUE;
|
||||
}
|
||||
else
|
||||
/* the read failed so let's say this is dead anyway */
|
||||
@@ -350,13 +352,12 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Store nghttp2 version info in this buffer, Prefix with a space. Return
|
||||
* total length written.
|
||||
* Store nghttp2 version info in this buffer.
|
||||
*/
|
||||
int Curl_http2_ver(char *p, size_t len)
|
||||
void Curl_http2_ver(char *p, size_t len)
|
||||
{
|
||||
nghttp2_info *h2 = nghttp2_version(0);
|
||||
return msnprintf(p, len, "nghttp2/%s", h2->version_str);
|
||||
(void)msnprintf(p, len, "nghttp2/%s", h2->version_str);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -551,7 +552,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!\n",
|
||||
H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!",
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
struct HTTP *stream;
|
||||
@@ -563,7 +564,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
/* clone the parent */
|
||||
struct Curl_easy *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
infof(data, "failed to duplicate handle");
|
||||
rv = CURL_PUSH_DENY; /* FAIL HARD */
|
||||
goto fail;
|
||||
}
|
||||
@@ -571,7 +572,7 @@ 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!\n"));
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!"));
|
||||
|
||||
stream = data->req.p.http;
|
||||
if(!stream) {
|
||||
@@ -619,7 +620,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
state with the given connection !*/
|
||||
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
||||
if(rc) {
|
||||
infof(data, "failed to add handle to multi\n");
|
||||
infof(data, "failed to add handle to multi");
|
||||
http2_stream_free(newhandle->req.p.http);
|
||||
newhandle->req.p.http = NULL;
|
||||
Curl_close(&newhandle);
|
||||
@@ -632,15 +633,17 @@ static int push_promise(struct Curl_easy *data,
|
||||
frame->promised_stream_id,
|
||||
newhandle);
|
||||
if(rv) {
|
||||
infof(data, "failed to set user_data for stream %d\n",
|
||||
infof(data, "failed to set user_data for stream %d",
|
||||
frame->promised_stream_id);
|
||||
DEBUGASSERT(0);
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
Curl_dyn_init(&newstream->header_recvbuf, DYN_H2_HEADERS);
|
||||
Curl_dyn_init(&newstream->trailer_recvbuf, DYN_H2_TRAILERS);
|
||||
}
|
||||
else {
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!"));
|
||||
rv = CURL_PUSH_DENY;
|
||||
}
|
||||
fail:
|
||||
@@ -676,21 +679,21 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
/* stream ID zero is for connection-oriented stuff */
|
||||
if(frame->hd.type == NGHTTP2_SETTINGS) {
|
||||
uint32_t max_conn = httpc->settings.max_concurrent_streams;
|
||||
H2BUGF(infof(data, "Got SETTINGS\n"));
|
||||
H2BUGF(infof(data, "Got SETTINGS"));
|
||||
httpc->settings.max_concurrent_streams =
|
||||
nghttp2_session_get_remote_settings(
|
||||
session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
|
||||
httpc->settings.enable_push =
|
||||
nghttp2_session_get_remote_settings(
|
||||
session, NGHTTP2_SETTINGS_ENABLE_PUSH);
|
||||
H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d\n",
|
||||
H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d",
|
||||
httpc->settings.max_concurrent_streams));
|
||||
H2BUGF(infof(data, "ENABLE_PUSH == %s\n",
|
||||
H2BUGF(infof(data, "ENABLE_PUSH == %s",
|
||||
httpc->settings.enable_push?"TRUE":"false"));
|
||||
if(max_conn != httpc->settings.max_concurrent_streams) {
|
||||
/* only signal change if the value actually changed */
|
||||
infof(data,
|
||||
"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
|
||||
"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!",
|
||||
httpc->settings.max_concurrent_streams);
|
||||
multi_connchanged(data->multi);
|
||||
}
|
||||
@@ -700,19 +703,19 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s) {
|
||||
H2BUGF(infof(data,
|
||||
"No Curl_easy associated with stream: %x\n",
|
||||
"No Curl_easy associated with stream: %x",
|
||||
stream_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream = data_s->req.p.http;
|
||||
if(!stream) {
|
||||
H2BUGF(infof(data_s, "No proto pointer for stream: %x\n",
|
||||
H2BUGF(infof(data_s, "No proto pointer for stream: %x",
|
||||
stream_id));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
|
||||
H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x",
|
||||
frame->hd.type, stream_id));
|
||||
|
||||
switch(frame->hd.type) {
|
||||
@@ -760,7 +763,8 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
ncopy);
|
||||
stream->nread_header_recvbuf += ncopy;
|
||||
|
||||
H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
|
||||
DEBUGASSERT(stream->mem);
|
||||
H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p",
|
||||
ncopy, stream_id, stream->mem));
|
||||
|
||||
stream->len -= ncopy;
|
||||
@@ -782,13 +786,13 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(nghttp2_is_fatal(h2))
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(rv == CURL_PUSH_ERROROUT) {
|
||||
DEBUGF(infof(data_s, "Fail the parent stream (too)\n"));
|
||||
DEBUGF(infof(data_s, "Fail the parent stream (too)"));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
H2BUGF(infof(data_s, "Got frame type %x for stream %u!\n",
|
||||
H2BUGF(infof(data_s, "Got frame type %x for stream %u!",
|
||||
frame->hd.type, stream_id));
|
||||
break;
|
||||
}
|
||||
@@ -833,7 +837,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||
|
||||
H2BUGF(infof(data_s, "%zu data received for stream %u "
|
||||
"(%zu left in buffer %p, total %zu)\n",
|
||||
"(%zu left in buffer %p, total %zu)",
|
||||
nread, stream_id,
|
||||
stream->len, stream->mem,
|
||||
stream->memlen));
|
||||
@@ -842,7 +846,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
stream->pausedata = mem + nread;
|
||||
stream->pauselen = len - nread;
|
||||
H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
|
||||
", stream %u\n",
|
||||
", stream %u",
|
||||
len - nread, stream_id));
|
||||
data_s->conn->proto.httpc.pause_stream_id = stream_id;
|
||||
|
||||
@@ -880,7 +884,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
decided to reject stream (e.g., PUSH_PROMISE). */
|
||||
return 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
|
||||
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u",
|
||||
nghttp2_http2_strerror(error_code), error_code, stream_id));
|
||||
stream = data_s->req.p.http;
|
||||
if(!stream)
|
||||
@@ -895,15 +899,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!\n",
|
||||
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!\n"));
|
||||
H2BUGF(infof(data_s, "Stopped the pause stream!"));
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
|
||||
H2BUGF(infof(data_s, "Removed stream %u hash!", stream_id));
|
||||
stream->stream_id = 0; /* cleared */
|
||||
}
|
||||
return 0;
|
||||
@@ -921,7 +925,7 @@ static int on_begin_headers(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
H2BUGF(infof(data_s, "on_begin_headers() was called\n"));
|
||||
H2BUGF(infof(data_s, "on_begin_headers() was called"));
|
||||
|
||||
if(frame->hd.type != NGHTTP2_HEADERS) {
|
||||
return 0;
|
||||
@@ -1049,7 +1053,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
if(stream->bodystarted) {
|
||||
/* This is a trailer */
|
||||
H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s", namelen, name, valuelen,
|
||||
value));
|
||||
result = Curl_dyn_addf(&stream->trailer_recvbuf,
|
||||
"%.*s: %.*s\r\n", namelen, name,
|
||||
@@ -1082,7 +1086,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(get_transfer(httpc) != data_s)
|
||||
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||
|
||||
H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
||||
H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)",
|
||||
stream->status_code, data_s));
|
||||
return 0;
|
||||
}
|
||||
@@ -1106,7 +1110,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(get_transfer(httpc) != data_s)
|
||||
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||
|
||||
H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
H2BUGF(infof(data_s, "h2 header: %.*s: %.*s", namelen, name, valuelen,
|
||||
value));
|
||||
|
||||
return 0; /* 0 is successful */
|
||||
@@ -1156,7 +1160,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
return NGHTTP2_ERR_DEFERRED;
|
||||
|
||||
H2BUGF(infof(data_s, "data_source_read_callback: "
|
||||
"returns %zu bytes stream %u\n",
|
||||
"returns %zu bytes stream %u",
|
||||
nread, stream_id));
|
||||
|
||||
return nread;
|
||||
@@ -1223,7 +1227,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
(void)nghttp2_session_send(httpc->h2);
|
||||
|
||||
if(http->stream_id == httpc->pause_stream_id) {
|
||||
infof(data, "stopped the pause stream!\n");
|
||||
infof(data, "stopped the pause stream!");
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
}
|
||||
@@ -1236,7 +1240,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!\n",
|
||||
infof(data, "http/2: failed to clear user_data for stream %d!",
|
||||
http->stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
@@ -1383,7 +1387,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
||||
if(nread == rv) {
|
||||
H2BUGF(infof(data,
|
||||
"h2_process_pending_input: All data in connection buffer "
|
||||
"processed\n"));
|
||||
"processed"));
|
||||
httpc->inbuflen = 0;
|
||||
httpc->nread_inbuf = 0;
|
||||
}
|
||||
@@ -1391,7 +1395,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
||||
httpc->nread_inbuf += rv;
|
||||
H2BUGF(infof(data,
|
||||
"h2_process_pending_input: %zu bytes left in connection "
|
||||
"buffer\n",
|
||||
"buffer",
|
||||
httpc->inbuflen - httpc->nread_inbuf));
|
||||
}
|
||||
|
||||
@@ -1412,7 +1416,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
||||
if(should_close_session(httpc)) {
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
H2BUGF(infof(data,
|
||||
"h2_process_pending_input: nothing to do in this session\n"));
|
||||
"h2_process_pending_input: nothing to do in this session"));
|
||||
if(stream->error)
|
||||
*err = CURLE_HTTP2;
|
||||
else {
|
||||
@@ -1456,7 +1460,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data,
|
||||
struct SingleRequest *k = &data->req;
|
||||
int rv;
|
||||
|
||||
H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data));
|
||||
H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)", data));
|
||||
|
||||
/* and attempt to send the pending frames */
|
||||
rv = h2_session_send(data, h2);
|
||||
@@ -1495,7 +1499,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!\n",
|
||||
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;
|
||||
@@ -1544,7 +1548,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
|
||||
stream->close_handled = TRUE;
|
||||
|
||||
H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
||||
H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1587,7 +1591,7 @@ static int h2_session_send(struct Curl_easy *data,
|
||||
|
||||
h2_pri_spec(data, &pri_spec);
|
||||
|
||||
H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
|
||||
H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)",
|
||||
stream->stream_id, data));
|
||||
DEBUGASSERT(stream->stream_id != -1);
|
||||
rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
|
||||
@@ -1611,7 +1615,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(data,
|
||||
"http2_recv: nothing to do in this session\n"));
|
||||
"http2_recv: nothing to do in this session"));
|
||||
if(conn->bits.close) {
|
||||
/* already marked for closure, return OK and we're done */
|
||||
*err = CURLE_OK;
|
||||
@@ -1621,10 +1625,6 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(stream->closed)
|
||||
/* closed overrides paused */
|
||||
return http2_handle_stream_close(conn, data, stream, err);
|
||||
|
||||
/* Nullify here because we call nghttp2_session_send() and they
|
||||
might refer to the old buffer. */
|
||||
stream->upload_mem = NULL;
|
||||
@@ -1645,12 +1645,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
stream->nread_header_recvbuf, ncopy);
|
||||
stream->nread_header_recvbuf += ncopy;
|
||||
|
||||
H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
|
||||
H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf",
|
||||
(int)ncopy));
|
||||
return ncopy;
|
||||
}
|
||||
|
||||
H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u\n",
|
||||
H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u",
|
||||
data, stream->stream_id,
|
||||
nghttp2_session_get_local_window_size(httpc->h2),
|
||||
nghttp2_session_get_stream_local_window_size(httpc->h2,
|
||||
@@ -1658,7 +1658,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)\n",
|
||||
H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)",
|
||||
stream->memlen, stream->stream_id,
|
||||
stream->mem, mem));
|
||||
if(mem != stream->mem) {
|
||||
@@ -1686,7 +1686,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
stream->pauselen -= nread;
|
||||
|
||||
if(stream->pauselen == 0) {
|
||||
H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
|
||||
H2BUGF(infof(data, "Unpaused by stream %u", stream->stream_id));
|
||||
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
|
||||
httpc->pause_stream_id = 0;
|
||||
|
||||
@@ -1704,7 +1704,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
|
||||
H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u",
|
||||
nread, stream->stream_id));
|
||||
return nread;
|
||||
}
|
||||
@@ -1720,7 +1720,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
if(stream->closed)
|
||||
/* closed overrides paused */
|
||||
return 0;
|
||||
H2BUGF(infof(data, "stream %x is paused, pause id: %x\n",
|
||||
H2BUGF(infof(data, "stream %x is paused, pause id: %x",
|
||||
stream->stream_id, httpc->pause_stream_id));
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
@@ -1758,12 +1758,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
return -1;
|
||||
}
|
||||
|
||||
H2BUGF(infof(data, "end of stream\n"));
|
||||
H2BUGF(infof(data, "end of stream"));
|
||||
*err = CURLE_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
H2BUGF(infof(data, "nread=%zd\n", nread));
|
||||
H2BUGF(infof(data, "nread=%zd", nread));
|
||||
|
||||
httpc->inbuflen = nread;
|
||||
|
||||
@@ -1772,7 +1772,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
else {
|
||||
nread = httpc->inbuflen - httpc->nread_inbuf;
|
||||
(void)nread; /* silence warning, used in debug */
|
||||
H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
|
||||
H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd",
|
||||
nread));
|
||||
}
|
||||
|
||||
@@ -1781,14 +1781,14 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
}
|
||||
if(stream->memlen) {
|
||||
ssize_t retlen = stream->memlen;
|
||||
H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
|
||||
H2BUGF(infof(data, "http2_recv: returns %zd for stream %u",
|
||||
retlen, stream->stream_id));
|
||||
stream->memlen = 0;
|
||||
|
||||
if(httpc->pause_stream_id == stream->stream_id) {
|
||||
/* data for this stream is returned now, but this stream caused a pause
|
||||
already so we need it called again asap */
|
||||
H2BUGF(infof(data, "Data returned for PAUSED stream %u\n",
|
||||
H2BUGF(infof(data, "Data returned for PAUSED stream %u",
|
||||
stream->stream_id));
|
||||
}
|
||||
else if(!stream->closed) {
|
||||
@@ -1803,7 +1803,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
if(stream->closed)
|
||||
return http2_handle_stream_close(conn, data, stream, err);
|
||||
*err = CURLE_AGAIN;
|
||||
H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
|
||||
H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u",
|
||||
stream->stream_id));
|
||||
return -1;
|
||||
}
|
||||
@@ -1907,11 +1907,11 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
|
||||
(void)sockindex;
|
||||
|
||||
H2BUGF(infof(data, "http2_send len=%zu\n", len));
|
||||
H2BUGF(infof(data, "http2_send len=%zu", len));
|
||||
|
||||
if(stream->stream_id != -1) {
|
||||
if(stream->close_handled) {
|
||||
infof(data, "stream %d closed\n", stream->stream_id);
|
||||
infof(data, "stream %d closed", stream->stream_id);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
}
|
||||
@@ -1940,7 +1940,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
stream->upload_len = 0;
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session"));
|
||||
*err = CURLE_HTTP2;
|
||||
return -1;
|
||||
}
|
||||
@@ -1953,7 +1953,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
}
|
||||
|
||||
H2BUGF(infof(data, "http2_send returns %zu for stream %u\n", len,
|
||||
H2BUGF(infof(data, "http2_send returns %zu for stream %u", len,
|
||||
stream->stream_id));
|
||||
return len;
|
||||
}
|
||||
@@ -2116,7 +2116,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
H2BUGF(infof(data, "h2 header: %.*s:%.*s\n",
|
||||
H2BUGF(infof(data, "h2 header: %.*s:%.*s",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
@@ -2124,13 +2124,13 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
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.\n", MAX_ACC);
|
||||
"stream to be rejected.", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
h2_pri_spec(data, &pri_spec);
|
||||
|
||||
H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)\n",
|
||||
H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)",
|
||||
nghttp2_session_check_request_allowed(h2), (void *)data));
|
||||
|
||||
switch(data->state.httpreq) {
|
||||
@@ -2158,20 +2158,20 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
|
||||
if(stream_id < 0) {
|
||||
H2BUGF(infof(data,
|
||||
"http2_send() nghttp2_submit_request error (%s)%d\n",
|
||||
"http2_send() nghttp2_submit_request error (%s)%d",
|
||||
nghttp2_strerror(stream_id), stream_id));
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
infof(data, "Using Stream ID: %x (easy handle %p)\n",
|
||||
infof(data, "Using Stream ID: %x (easy handle %p)",
|
||||
stream_id, (void *)data);
|
||||
stream->stream_id = stream_id;
|
||||
|
||||
rv = h2_session_send(data, h2);
|
||||
if(rv) {
|
||||
H2BUGF(infof(data,
|
||||
"http2_send() nghttp2_session_send error (%s)%d\n",
|
||||
"http2_send() nghttp2_session_send error (%s)%d",
|
||||
nghttp2_strerror(rv), rv));
|
||||
|
||||
*err = CURLE_SEND_ERROR;
|
||||
@@ -2179,7 +2179,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
}
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session"));
|
||||
*err = CURLE_HTTP2;
|
||||
return -1;
|
||||
}
|
||||
@@ -2215,6 +2215,22 @@ CURLcode Curl_http2_setup(struct Curl_easy *data,
|
||||
Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
|
||||
Curl_dyn_init(&stream->trailer_recvbuf, DYN_H2_TRAILERS);
|
||||
|
||||
stream->upload_left = 0;
|
||||
stream->upload_mem = NULL;
|
||||
stream->upload_len = 0;
|
||||
stream->mem = data->state.buffer;
|
||||
stream->len = data->set.buffer_size;
|
||||
|
||||
httpc->inbuflen = 0;
|
||||
httpc->nread_inbuf = 0;
|
||||
|
||||
httpc->pause_stream_id = 0;
|
||||
httpc->drain_total = 0;
|
||||
|
||||
multi_connchanged(data->multi);
|
||||
/* below this point only connection related inits are done, which only needs
|
||||
to be done once per connection */
|
||||
|
||||
if((conn->handler == &Curl_handler_http2_ssl) ||
|
||||
(conn->handler == &Curl_handler_http2))
|
||||
return CURLE_OK; /* already done */
|
||||
@@ -2230,25 +2246,13 @@ CURLcode Curl_http2_setup(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
infof(data, "Using HTTP2, server supports multi-use\n");
|
||||
stream->upload_left = 0;
|
||||
stream->upload_mem = NULL;
|
||||
stream->upload_len = 0;
|
||||
stream->mem = data->state.buffer;
|
||||
stream->len = data->set.buffer_size;
|
||||
|
||||
httpc->inbuflen = 0;
|
||||
httpc->nread_inbuf = 0;
|
||||
|
||||
httpc->pause_stream_id = 0;
|
||||
httpc->drain_total = 0;
|
||||
infof(data, "Using HTTP2, server supports multiplexing");
|
||||
|
||||
conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
|
||||
conn->httpversion = 20;
|
||||
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
||||
|
||||
infof(data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
multi_connchanged(data->multi);
|
||||
infof(data, "Connection state changed (HTTP/2 confirmed)");
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -2287,7 +2291,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!\n",
|
||||
infof(data, "http/2: failed to set user_data for stream %d!",
|
||||
stream->stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
@@ -2327,7 +2331,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
infof(data, "Copying HTTP/2 data in stream buffer to connection buffer"
|
||||
" after upgrade: len=%zu\n",
|
||||
" after upgrade: len=%zu",
|
||||
nread);
|
||||
|
||||
if(nread)
|
||||
@@ -2337,15 +2341,8 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
||||
|
||||
DEBUGASSERT(httpc->nread_inbuf == 0);
|
||||
|
||||
/* Good enough to call it an end once the remaining payload is copied to the
|
||||
* connection buffer.
|
||||
* Some servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
|
||||
* following the protocol switch other than waiting for the client-side
|
||||
* connection preface. If h2_process_pending_input is invoked here to parse
|
||||
* the remaining payload, stream 1 would be marked as closed too early and
|
||||
* thus ignored in http2_recv (following 252790c53).
|
||||
* The logic in lib/http.c and lib/transfer.c guarantees a following
|
||||
* http2_recv would be invoked very soon. */
|
||||
if(-1 == h2_process_pending_input(data, httpc, &result))
|
||||
return CURLE_HTTP2;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -2378,7 +2375,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
|
||||
if(rv)
|
||||
return CURLE_SEND_ERROR;
|
||||
|
||||
DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u\n",
|
||||
DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u",
|
||||
window, stream->stream_id));
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
@@ -2387,7 +2384,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
|
||||
uint32_t window2 =
|
||||
nghttp2_session_get_stream_local_window_size(httpc->h2,
|
||||
stream->stream_id);
|
||||
DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u\n",
|
||||
DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u",
|
||||
window2, stream->stream_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-3
@@ -32,10 +32,9 @@
|
||||
#define DEFAULT_MAX_CONCURRENT_STREAMS 100
|
||||
|
||||
/*
|
||||
* Store nghttp2 version info in this buffer, Prefix with a space. Return
|
||||
* total length written.
|
||||
* Store nghttp2 version info in this buffer.
|
||||
*/
|
||||
int Curl_http2_ver(char *p, size_t len);
|
||||
void Curl_http2_ver(char *p, size_t len);
|
||||
|
||||
const char *Curl_http2_strerror(uint32_t err);
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
tmp1 = strchr(tmp0, ':');
|
||||
len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
||||
if(len < 1) {
|
||||
infof(data, "first provider can't be empty\n");
|
||||
infof(data, "first provider can't be empty");
|
||||
ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto fail;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
tmp1 = strchr(tmp0, ':');
|
||||
len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
||||
if(len < 1) {
|
||||
infof(data, "second provider can't be empty\n");
|
||||
infof(data, "second provider can't be empty");
|
||||
ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto fail;
|
||||
}
|
||||
@@ -165,7 +165,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
tmp1 = strchr(tmp0, ':');
|
||||
len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
||||
if(len < 1) {
|
||||
infof(data, "region can't be empty\n");
|
||||
infof(data, "region can't be empty");
|
||||
ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto fail;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
goto fail;
|
||||
}
|
||||
if(strlen(service) < 1) {
|
||||
infof(data, "service can't be empty\n");
|
||||
infof(data, "service can't be empty");
|
||||
ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto fail;
|
||||
}
|
||||
@@ -203,7 +203,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
tmp1 = strchr(tmp0, '.');
|
||||
len = tmp1 - tmp0;
|
||||
if(!tmp1 || len < 1) {
|
||||
infof(data, "service missing in parameters or hostname\n");
|
||||
infof(data, "service missing in parameters or hostname");
|
||||
ret = CURLE_URL_MALFORMAT;
|
||||
goto fail;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
|
||||
tmp1 = strchr(tmp0, '.');
|
||||
len = tmp1 - tmp0;
|
||||
if(!tmp1 || len < 1) {
|
||||
infof(data, "region missing in parameters or hostname\n");
|
||||
infof(data, "region missing in parameters or hostname");
|
||||
ret = CURLE_URL_MALFORMAT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+2
-1
@@ -146,7 +146,8 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
||||
tmp = strchr((char *)uripath, '?');
|
||||
if(tmp) {
|
||||
size_t urilen = tmp - (char *)uripath;
|
||||
path = (unsigned char *) aprintf("%.*s", urilen, uripath);
|
||||
/* typecast is fine here since the value is always less than 32 bits */
|
||||
path = (unsigned char *) aprintf("%.*s", (int)urilen, uripath);
|
||||
}
|
||||
}
|
||||
if(!tmp)
|
||||
|
||||
@@ -89,7 +89,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
||||
neg_ctx->havenegdata = len != 0;
|
||||
if(!len) {
|
||||
if(state == GSS_AUTHSUCC) {
|
||||
infof(data, "Negotiate auth restarted\n");
|
||||
infof(data, "Negotiate auth restarted");
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
}
|
||||
else if(state != GSS_AUTHNONE) {
|
||||
@@ -142,11 +142,11 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if(neg_ctx->noauthpersist ||
|
||||
(*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) {
|
||||
(*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) {
|
||||
|
||||
if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) {
|
||||
infof(data, "Curl_output_negotiate, "
|
||||
"no persistent authentication: cleanup existing context");
|
||||
"no persistent authentication: cleanup existing context");
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
}
|
||||
if(!neg_ctx->context) {
|
||||
|
||||
+3
-3
@@ -100,17 +100,17 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data,
|
||||
}
|
||||
else {
|
||||
if(*state == NTLMSTATE_LAST) {
|
||||
infof(data, "NTLM auth restarted\n");
|
||||
infof(data, "NTLM auth restarted");
|
||||
Curl_http_auth_cleanup_ntlm(conn);
|
||||
}
|
||||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(data, "NTLM handshake rejected\n");
|
||||
infof(data, "NTLM handshake rejected");
|
||||
Curl_http_auth_cleanup_ntlm(conn);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(*state >= NTLMSTATE_TYPE1) {
|
||||
infof(data, "NTLM handshake failure (internal error)\n");
|
||||
infof(data, "NTLM handshake failure (internal error)");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
||||
+85
-45
@@ -61,7 +61,7 @@ static CURLcode https_proxy_connect(struct Curl_easy *data, int sockindex)
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex]) {
|
||||
/* perform SSL initialization for this socket */
|
||||
result =
|
||||
Curl_ssl_connect_nonblocking(data, conn, sockindex,
|
||||
Curl_ssl_connect_nonblocking(data, conn, TRUE, sockindex,
|
||||
&conn->bits.proxy_ssl_connected[sockindex]);
|
||||
if(result)
|
||||
/* a failed connection is marked for closure to prevent (bad) re-use or
|
||||
@@ -129,13 +129,13 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex)
|
||||
bool Curl_connect_complete(struct connectdata *conn)
|
||||
{
|
||||
return !conn->connect_state ||
|
||||
(conn->connect_state->tunnel_state == TUNNEL_COMPLETE);
|
||||
(conn->connect_state->tunnel_state >= TUNNEL_COMPLETE);
|
||||
}
|
||||
|
||||
bool Curl_connect_ongoing(struct connectdata *conn)
|
||||
{
|
||||
return conn->connect_state &&
|
||||
(conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
|
||||
(conn->connect_state->tunnel_state <= TUNNEL_COMPLETE);
|
||||
}
|
||||
|
||||
/* when we've sent a CONNECT to a proxy, we should rather either wait for the
|
||||
@@ -148,7 +148,7 @@ int Curl_connect_getsock(struct connectdata *conn)
|
||||
DEBUGASSERT(conn->connect_state);
|
||||
http = &conn->connect_state->http_proxy;
|
||||
|
||||
if(http->sending)
|
||||
if(http->sending == HTTPSEND_REQUEST)
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
|
||||
return GETSOCK_READSOCK(0);
|
||||
@@ -169,7 +169,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!\n");
|
||||
infof(data, "allocate connect buffer!");
|
||||
conn->connect_state = s;
|
||||
Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
|
||||
|
||||
@@ -202,13 +202,16 @@ static void connect_done(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct http_connect_state *s = conn->connect_state;
|
||||
s->tunnel_state = TUNNEL_COMPLETE;
|
||||
Curl_dyn_free(&s->rcvbuf);
|
||||
Curl_dyn_free(&s->req);
|
||||
if(s->tunnel_state != TUNNEL_EXIT) {
|
||||
s->tunnel_state = TUNNEL_EXIT;
|
||||
Curl_dyn_free(&s->rcvbuf);
|
||||
Curl_dyn_free(&s->req);
|
||||
|
||||
/* retore the protocol pointer */
|
||||
data->req.p.http = s->prot_save;
|
||||
infof(data, "CONNECT phase completed!\n");
|
||||
/* retore the protocol pointer */
|
||||
data->req.p.http = s->prot_save;
|
||||
s->prot_save = NULL;
|
||||
infof(data, "CONNECT phase completed!");
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode CONNECT_host(struct Curl_easy *data,
|
||||
@@ -243,11 +246,11 @@ static CURLcode CONNECT_host(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifndef USE_HYPER
|
||||
static CURLcode CONNECT(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const char *hostname,
|
||||
int remote_port)
|
||||
#ifndef USE_HYPER
|
||||
{
|
||||
int subversion = 0;
|
||||
struct SingleRequest *k = &data->req;
|
||||
@@ -275,7 +278,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
char *hostheader = NULL;
|
||||
char *host = NULL;
|
||||
|
||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
|
||||
infof(data, "Establish HTTP proxy tunnel to %s:%d",
|
||||
hostname, remote_port);
|
||||
|
||||
/* This only happens if we've looped here due to authentication
|
||||
@@ -297,32 +300,27 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
hostheader, TRUE);
|
||||
|
||||
if(!result) {
|
||||
const char *proxyconn = "";
|
||||
const char *useragent = "";
|
||||
const char *httpv =
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = data->state.aptr.uagent;
|
||||
|
||||
result =
|
||||
Curl_dyn_addf(req,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
"%s", /* Proxy-Authorization */
|
||||
hostheader,
|
||||
httpv,
|
||||
host?host:"",
|
||||
data->state.aptr.proxyuserpwd?
|
||||
data->state.aptr.proxyuserpwd:"",
|
||||
useragent,
|
||||
proxyconn);
|
||||
data->state.aptr.proxyuserpwd:"");
|
||||
|
||||
if(!result && !Curl_checkProxyheaders(data, conn, "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)
|
||||
result = Curl_add_custom_headers(data, TRUE, req);
|
||||
@@ -387,6 +385,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
k->upload_fromhere += bytes_written;
|
||||
return result;
|
||||
}
|
||||
http->sending = HTTPSEND_NADA;
|
||||
/* if nothing left to send, continue */
|
||||
}
|
||||
{ /* READING RESPONSE PHASE */
|
||||
@@ -416,7 +415,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
/* proxy auth was requested and there was proxy auth available,
|
||||
then deem this as "mere" proxy disconnect */
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Proxy CONNECT connection closed\n");
|
||||
infof(data, "Proxy CONNECT connection closed");
|
||||
}
|
||||
else {
|
||||
error = SELECT_ERROR;
|
||||
@@ -451,7 +450,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
infof(data, "chunk reading DONE\n");
|
||||
infof(data, "chunk reading DONE");
|
||||
s->keepon = KEEPON_DONE;
|
||||
/* we did the full CONNECT treatment, go COMPLETE */
|
||||
s->tunnel_state = TUNNEL_COMPLETE;
|
||||
@@ -510,13 +509,13 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
|
||||
if(s->cl) {
|
||||
infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes of response-body\n", s->cl);
|
||||
" bytes of response-body", s->cl);
|
||||
}
|
||||
else if(s->chunked_encoding) {
|
||||
CHUNKcode r;
|
||||
CURLcode extra;
|
||||
|
||||
infof(data, "Ignore chunked response-body\n");
|
||||
infof(data, "Ignore chunked response-body");
|
||||
|
||||
/* We set ignorebody true here since the chunked decoder
|
||||
function will acknowledge that. Pay attention so that this is
|
||||
@@ -533,7 +532,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
&extra);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
infof(data, "chunk reading DONE\n");
|
||||
infof(data, "chunk reading DONE");
|
||||
s->keepon = KEEPON_DONE;
|
||||
/* we did the full CONNECT treatment, go to COMPLETE */
|
||||
s->tunnel_state = TUNNEL_COMPLETE;
|
||||
@@ -579,7 +578,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
|
||||
infof(data, "Ignoring Content-Length in CONNECT %03d response",
|
||||
k->httpcode);
|
||||
}
|
||||
else {
|
||||
@@ -595,11 +594,11 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
infof(data, "Ignoring Transfer-Encoding in "
|
||||
"CONNECT %03d response\n", k->httpcode);
|
||||
"CONNECT %03d response", k->httpcode);
|
||||
}
|
||||
else if(Curl_compareheader(linep,
|
||||
"Transfer-Encoding:", "chunked")) {
|
||||
infof(data, "CONNECT responded chunked\n");
|
||||
infof(data, "CONNECT responded chunked");
|
||||
s->chunked_encoding = TRUE;
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(data);
|
||||
@@ -657,7 +656,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
if(data->info.httpproxycode/100 != 2) {
|
||||
if(s->close_connection && data->req.newurl) {
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Connect me again please\n");
|
||||
infof(data, "Connect me again please");
|
||||
connect_done(data);
|
||||
}
|
||||
else {
|
||||
@@ -692,7 +691,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
data->state.authproxy.done = TRUE;
|
||||
data->state.authproxy.multipass = FALSE;
|
||||
|
||||
infof(data, "Proxy replied %d to CONNECT request\n",
|
||||
infof(data, "Proxy replied %d to CONNECT request",
|
||||
data->info.httpproxycode);
|
||||
data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
|
||||
conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
|
||||
@@ -702,6 +701,10 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
}
|
||||
#else
|
||||
/* The Hyper version of CONNECT */
|
||||
static CURLcode CONNECT(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const char *hostname,
|
||||
int remote_port)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct hyptransfer *h = &data->hyp;
|
||||
@@ -740,6 +743,8 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
hyper_io_set_write(io, Curl_hyper_send);
|
||||
conn->sockfd = tunnelsocket;
|
||||
|
||||
data->state.hconnect = TRUE;
|
||||
|
||||
/* create an executor to poll futures */
|
||||
if(!h->exec) {
|
||||
h->exec = hyper_executor_new();
|
||||
@@ -830,16 +835,26 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
Curl_hyper_header(data, headers, data->state.aptr.proxyuserpwd))
|
||||
goto error;
|
||||
|
||||
if(data->set.str[STRING_USERAGENT] &&
|
||||
*data->set.str[STRING_USERAGENT] &&
|
||||
data->state.aptr.uagent &&
|
||||
Curl_hyper_header(data, headers, data->state.aptr.uagent))
|
||||
goto error;
|
||||
if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
struct dynbuf ua;
|
||||
Curl_dyn_init(&ua, DYN_HTTP_REQUEST);
|
||||
result = Curl_dyn_addf(&ua, "User-Agent: %s\r\n",
|
||||
data->set.str[STRING_USERAGENT]);
|
||||
if(result)
|
||||
goto error;
|
||||
if(Curl_hyper_header(data, headers, Curl_dyn_ptr(&ua)))
|
||||
goto error;
|
||||
Curl_dyn_free(&ua);
|
||||
}
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection") &&
|
||||
Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
|
||||
goto error;
|
||||
|
||||
if(Curl_add_custom_headers(data, TRUE, headers))
|
||||
goto error;
|
||||
|
||||
sendtask = hyper_clientconn_send(client, req);
|
||||
if(!sendtask) {
|
||||
failf(data, "hyper_clientconn_send");
|
||||
@@ -875,7 +890,6 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
goto error;
|
||||
if(!done)
|
||||
break;
|
||||
fprintf(stderr, "done\n");
|
||||
s->tunnel_state = TUNNEL_COMPLETE;
|
||||
if(h->exec) {
|
||||
hyper_executor_free(h->exec);
|
||||
@@ -897,6 +911,33 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
} while(data->req.newurl);
|
||||
|
||||
result = CURLE_OK;
|
||||
if(s->tunnel_state == TUNNEL_COMPLETE) {
|
||||
data->info.httpproxycode = data->req.httpcode;
|
||||
if(data->info.httpproxycode/100 != 2) {
|
||||
if(conn->bits.close && data->req.newurl) {
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Connect me again please");
|
||||
connect_done(data);
|
||||
}
|
||||
else {
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
/* failure, close this connection to avoid re-use */
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(data, conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/* to back to init state */
|
||||
s->tunnel_state = TUNNEL_INIT;
|
||||
|
||||
if(!conn->bits.proxy_connect_closed) {
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
free(host);
|
||||
free(hostheader);
|
||||
@@ -917,7 +958,6 @@ static CURLcode CONNECT(struct Curl_easy *data,
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Curl_connect_free(struct Curl_easy *data)
|
||||
|
||||
+4
-3
@@ -65,9 +65,10 @@ struct http_connect_state {
|
||||
} keepon;
|
||||
curl_off_t cl; /* size of content to read and ignore */
|
||||
enum {
|
||||
TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
TUNNEL_CONNECT, /* CONNECT has been sent off */
|
||||
TUNNEL_COMPLETE /* CONNECT response received completely */
|
||||
TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
TUNNEL_CONNECT, /* CONNECT has been sent off */
|
||||
TUNNEL_COMPLETE, /* CONNECT response received completely */
|
||||
TUNNEL_EXIT
|
||||
} tunnel_state;
|
||||
BIT(chunked_encoding);
|
||||
BIT(close_connection);
|
||||
|
||||
+27
-28
@@ -74,7 +74,6 @@
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
@@ -414,7 +413,7 @@ static void state(struct Curl_easy *data, imapstate newstate)
|
||||
};
|
||||
|
||||
if(imapc->state != newstate)
|
||||
infof(data, "IMAP %p state change from %s to %s\n",
|
||||
infof(data, "IMAP %p state change from %s to %s",
|
||||
(void *)imapc, names[imapc->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@@ -475,8 +474,8 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
|
||||
{
|
||||
/* Start the SSL connection */
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET,
|
||||
&imapc->ssldone);
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &imapc->ssldone);
|
||||
|
||||
if(!result) {
|
||||
if(imapc->state != IMAP_UPGRADETLS)
|
||||
@@ -606,7 +605,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!\n");
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -861,7 +860,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!\n");
|
||||
infof(data, "PREAUTH connection, already authenticated!");
|
||||
}
|
||||
else if(imapcode != IMAP_RESP_OK) {
|
||||
failf(data, "Got unexpected imap-server response");
|
||||
@@ -935,22 +934,18 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data,
|
||||
line += wordlen;
|
||||
}
|
||||
}
|
||||
else if(imapcode == IMAP_RESP_OK) {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested */
|
||||
if(imapc->tls_supported)
|
||||
/* Switch to TLS connection now */
|
||||
result = imap_perform_starttls(data, conn);
|
||||
else if(data->set.use_ssl == CURLUSESSL_TRY)
|
||||
/* Fallback and carry on with authentication */
|
||||
result = imap_perform_authentication(data, conn);
|
||||
else {
|
||||
failf(data, "STARTTLS not supported.");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* PREAUTH is not compatible with STARTTLS. */
|
||||
if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) {
|
||||
/* Switch to TLS connection now */
|
||||
result = imap_perform_starttls(data, conn);
|
||||
}
|
||||
else
|
||||
else if(data->set.use_ssl <= CURLUSESSL_TRY)
|
||||
result = imap_perform_authentication(data, conn);
|
||||
else {
|
||||
failf(data, "STARTTLS not available.");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = imap_perform_authentication(data, conn);
|
||||
@@ -968,6 +963,10 @@ static CURLcode imap_state_starttls_resp(struct Curl_easy *data,
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
/* Pipelining in response is forbidden. */
|
||||
if(data->conn->proto.imapc.pp.cache_size)
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
if(imapcode != IMAP_RESP_OK) {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied");
|
||||
@@ -1143,7 +1142,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if(parsed) {
|
||||
infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n",
|
||||
infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download",
|
||||
size);
|
||||
Curl_pgrsSetDownloadSize(data, size);
|
||||
|
||||
@@ -1169,7 +1168,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
|
||||
data->req.bytecount += chunk;
|
||||
|
||||
infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU
|
||||
" bytes are left for transfer\n", chunk, size - chunk);
|
||||
" bytes are left for transfer", chunk, size - chunk);
|
||||
|
||||
/* Have we used the entire cache or just part of it?*/
|
||||
if(pp->cache_size > chunk) {
|
||||
@@ -1369,7 +1368,7 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
|
||||
result = Curl_ssl_connect_nonblocking(data, conn,
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &imapc->ssldone);
|
||||
if(result || !imapc->ssldone)
|
||||
return result;
|
||||
@@ -1543,7 +1542,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
bool selected = FALSE;
|
||||
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts"));
|
||||
|
||||
if(data->set.opt_no_body) {
|
||||
/* Requested no body means no transfer */
|
||||
@@ -1590,7 +1589,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1682,11 +1681,11 @@ static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
CURLcode result = imap_multi_statemach(data, dophase_done);
|
||||
|
||||
if(result)
|
||||
DEBUGF(infof(data, "DO phase failed\n"));
|
||||
DEBUGF(infof(data, "DO phase failed"));
|
||||
else if(*dophase_done) {
|
||||
result = imap_dophase_done(data, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2017,7 +2016,7 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'\n", name, value));
|
||||
DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'", name, value));
|
||||
|
||||
/* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and
|
||||
PARTIAL) stripping of the trailing slash character if it is present.
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
#define INT16SZ 2
|
||||
|
||||
/*
|
||||
* Format an IPv4 address, more or less like inet_ntoa().
|
||||
* Format an IPv4 address, more or less like inet_ntop().
|
||||
*
|
||||
* Returns `dst' (as a const)
|
||||
* Note:
|
||||
|
||||
+11
-12
@@ -263,7 +263,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
|
||||
}
|
||||
/* We pass NULL as |output_name_type| to avoid a leak. */
|
||||
gss_display_name(&min, gssname, &output_buffer, NULL);
|
||||
Curl_infof(data, "Trying against %s\n", output_buffer.value);
|
||||
infof(data, "Trying against %s", output_buffer.value);
|
||||
gssresp = GSS_C_NO_BUFFER;
|
||||
*context = GSS_C_NO_CONTEXT;
|
||||
|
||||
@@ -290,7 +290,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(GSS_ERROR(maj)) {
|
||||
Curl_infof(data, "Error creating security context\n");
|
||||
infof(data, "Error creating security context");
|
||||
ret = AUTH_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -301,8 +301,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
|
||||
result = Curl_base64_encode(data, (char *)output_buffer.value,
|
||||
output_buffer.length, &p, &base64_sz);
|
||||
if(result) {
|
||||
Curl_infof(data, "base64-encoding: %s\n",
|
||||
curl_easy_strerror(result));
|
||||
infof(data, "base64-encoding: %s", curl_easy_strerror(result));
|
||||
ret = AUTH_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -327,7 +326,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') {
|
||||
Curl_infof(data, "Server didn't accept auth data\n");
|
||||
infof(data, "Server didn't accept auth data");
|
||||
ret = AUTH_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -629,7 +628,7 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
||||
socket_write(data, fd, cmd_buffer, cmd_size);
|
||||
socket_write(data, fd, "\r\n", 2);
|
||||
infof(data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
|
||||
infof(data, "Send: %s%s", prot_level == PROT_PRIVATE?enc:mic,
|
||||
cmd_buffer);
|
||||
free(cmd_buffer);
|
||||
}
|
||||
@@ -738,7 +737,7 @@ static int sec_set_protection_level(struct Curl_easy *data)
|
||||
|
||||
if(!conn->sec_complete) {
|
||||
infof(data, "Trying to change the protection level after the"
|
||||
" completion of the data exchange.\n");
|
||||
" completion of the data exchange.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -815,13 +814,13 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn)
|
||||
if(mech->init) {
|
||||
ret = mech->init(conn->app_data);
|
||||
if(ret) {
|
||||
infof(data, "Failed initialization for %s. Skipping it.\n",
|
||||
infof(data, "Failed initialization for %s. Skipping it.",
|
||||
mech->name);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "Trying mechanism %s...\n", mech->name);
|
||||
infof(data, "Trying mechanism %s...", mech->name);
|
||||
ret = ftp_send_command(data, "AUTH %s", mech->name);
|
||||
if(ret < 0)
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
@@ -830,15 +829,15 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn)
|
||||
switch(ret) {
|
||||
case 504:
|
||||
infof(data, "Mechanism %s is not supported by the server (server "
|
||||
"returned ftp code: 504).\n", mech->name);
|
||||
"returned ftp code: 504).", mech->name);
|
||||
break;
|
||||
case 534:
|
||||
infof(data, "Mechanism %s was rejected by the server (server returned "
|
||||
"ftp code: 534).\n", mech->name);
|
||||
"ftp code: 534).", mech->name);
|
||||
break;
|
||||
default:
|
||||
if(ret/100 == 5) {
|
||||
infof(data, "server does not support the security extensions\n");
|
||||
infof(data, "server does not support the security extensions");
|
||||
return CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
break;
|
||||
|
||||
+10
-10
@@ -296,9 +296,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
char *passwd = NULL;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
|
||||
infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d",
|
||||
LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
|
||||
infof(data, "LDAP local: %s\n", data->state.url);
|
||||
infof(data, "LDAP local: %s", data->state.url);
|
||||
|
||||
#ifdef HAVE_LDAP_URL_PARSE
|
||||
rc = ldap_url_parse(data->state.url, &ludp);
|
||||
@@ -314,7 +314,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
/* Get the URL scheme (either ldap or ldaps) */
|
||||
if(conn->given->flags & PROTOPT_SSL)
|
||||
ldap_ssl = 1;
|
||||
infof(data, "LDAP local: trying to establish %s connection\n",
|
||||
infof(data, "LDAP local: trying to establish %s connection",
|
||||
ldap_ssl ? "encrypted" : "cleartext");
|
||||
|
||||
#if defined(USE_WIN32_LDAP)
|
||||
@@ -366,14 +366,14 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
infof(data, "LDAP local: using %s CA cert '%s'\n",
|
||||
(cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
|
||||
ldap_ca);
|
||||
infof(data, "LDAP local: using %s CA cert '%s'",
|
||||
(cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
|
||||
ldap_ca);
|
||||
rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: ERROR setting %s CA cert: %s",
|
||||
(cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
|
||||
ldap_err2string(rc));
|
||||
(cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
|
||||
ldap_err2string(rc));
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
|
||||
infof(data, "LDAP local: using PEM CA cert: %s", ldap_ca);
|
||||
rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
|
||||
@@ -718,7 +718,7 @@ quit:
|
||||
LDAP_TRACE(("Received %d entries\n", num));
|
||||
}
|
||||
if(rc == LDAP_SIZELIMIT_EXCEEDED)
|
||||
infof(data, "There are more than %d entries\n", num);
|
||||
infof(data, "There are more than %d entries", num);
|
||||
if(ludp)
|
||||
ldap_free_urldesc(ludp);
|
||||
if(server)
|
||||
|
||||
@@ -36,8 +36,12 @@
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
#ifdef USE_MBEDTLS
|
||||
#include <mbedtls/config.h>
|
||||
#include <mbedtls/version.h>
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
#include <mbedtls/mbedtls_config.h>
|
||||
#else
|
||||
#include <mbedtls/config.h>
|
||||
#endif
|
||||
|
||||
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
|
||||
#define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
#ifdef USE_MBEDTLS
|
||||
#include <mbedtls/version.h>
|
||||
|
||||
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
|
||||
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
|
||||
(MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
#define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
|
||||
#endif
|
||||
#endif /* USE_MBEDTLS */
|
||||
@@ -85,7 +86,7 @@ typedef mbedtls_md5_context MD5_CTX;
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_md5_starts(ctx);
|
||||
(void) mbedtls_md5_starts(ctx);
|
||||
#else
|
||||
(void) mbedtls_md5_starts_ret(ctx);
|
||||
#endif
|
||||
@@ -96,7 +97,7 @@ static void MD5_Update(MD5_CTX *ctx,
|
||||
unsigned int length)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_md5_update(ctx, data, length);
|
||||
(void) mbedtls_md5_update(ctx, data, length);
|
||||
#else
|
||||
(void) mbedtls_md5_update_ret(ctx, data, length);
|
||||
#endif
|
||||
@@ -105,7 +106,7 @@ static void MD5_Update(MD5_CTX *ctx,
|
||||
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
{
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_md5_finish(ctx, digest);
|
||||
(void) mbedtls_md5_finish(ctx, digest);
|
||||
#else
|
||||
(void) mbedtls_md5_finish_ret(ctx, digest);
|
||||
#endif
|
||||
|
||||
+3
-1
@@ -1017,9 +1017,11 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
|
||||
retcode = dprintf_formatf(&info, addbyter, format, ap_save);
|
||||
if((retcode != -1) && info.max) {
|
||||
/* we terminate this with a zero byte */
|
||||
if(info.max == info.length)
|
||||
if(info.max == info.length) {
|
||||
/* we're at maximum, scrap the last letter */
|
||||
info.buffer[-1] = 0;
|
||||
retcode--; /* don't count the nul byte */
|
||||
}
|
||||
else
|
||||
info.buffer[0] = 0;
|
||||
}
|
||||
|
||||
+207
-51
@@ -128,6 +128,10 @@ static CURLcode mqtt_send(struct Curl_easy *data,
|
||||
mq->sendleftovers = sendleftovers;
|
||||
mq->nsend = nsend;
|
||||
}
|
||||
else {
|
||||
mq->sendleftovers = NULL;
|
||||
mq->nsend = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -143,32 +147,197 @@ static int mqtt_getsock(struct Curl_easy *data,
|
||||
return GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
}
|
||||
|
||||
static int mqtt_encode_len(char *buf, size_t len)
|
||||
{
|
||||
unsigned char encoded;
|
||||
int i;
|
||||
|
||||
for(i = 0; (len > 0) && (i<4); i++) {
|
||||
encoded = len % 0x80;
|
||||
len /= 0x80;
|
||||
if(len)
|
||||
encoded |= 0x80;
|
||||
buf[i] = encoded;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* add the passwd to the CONNECT packet */
|
||||
static int add_passwd(const char *passwd, const size_t plen,
|
||||
char *pkt, const size_t start, int remain_pos)
|
||||
{
|
||||
/* magic number that need to be set properly */
|
||||
const size_t conn_flags_pos = remain_pos + 8;
|
||||
if(plen > 0xffff)
|
||||
return 1;
|
||||
|
||||
/* set password flag */
|
||||
pkt[conn_flags_pos] |= 0x40;
|
||||
|
||||
/* length of password provided */
|
||||
pkt[start] = (char)((plen >> 8) & 0xFF);
|
||||
pkt[start + 1] = (char)(plen & 0xFF);
|
||||
memcpy(&pkt[start + 2], passwd, plen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add user to the CONN packet */
|
||||
static int add_user(const char *username, const size_t ulen,
|
||||
unsigned char *pkt, const size_t start, int remain_pos)
|
||||
{
|
||||
/* magic number that need to be set properly */
|
||||
const size_t conn_flags_pos = remain_pos + 8;
|
||||
if(ulen > 0xffff)
|
||||
return 1;
|
||||
|
||||
/* set username flag */
|
||||
pkt[conn_flags_pos] |= 0x80;
|
||||
/* length of username provided */
|
||||
pkt[start] = (unsigned char)((ulen >> 8) & 0xFF);
|
||||
pkt[start + 1] = (unsigned char)(ulen & 0xFF);
|
||||
memcpy(&pkt[start + 2], username, ulen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add client ID to the CONN packet */
|
||||
static int add_client_id(const char *client_id, const size_t client_id_len,
|
||||
char *pkt, const size_t start)
|
||||
{
|
||||
if(client_id_len != MQTT_CLIENTID_LEN)
|
||||
return 1;
|
||||
pkt[start] = 0x00;
|
||||
pkt[start + 1] = MQTT_CLIENTID_LEN;
|
||||
memcpy(&pkt[start + 2], client_id, MQTT_CLIENTID_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set initial values of CONN packet */
|
||||
static int init_connpack(char *packet, char *remain, int remain_pos)
|
||||
{
|
||||
/* Fixed header starts */
|
||||
/* packet type */
|
||||
packet[0] = MQTT_MSG_CONNECT;
|
||||
/* remaining length field */
|
||||
memcpy(&packet[1], remain, remain_pos);
|
||||
/* Fixed header ends */
|
||||
|
||||
/* Variable header starts */
|
||||
/* protocol length */
|
||||
packet[remain_pos + 1] = 0x00;
|
||||
packet[remain_pos + 2] = 0x04;
|
||||
/* protocol name */
|
||||
packet[remain_pos + 3] = 'M';
|
||||
packet[remain_pos + 4] = 'Q';
|
||||
packet[remain_pos + 5] = 'T';
|
||||
packet[remain_pos + 6] = 'T';
|
||||
/* protocol level */
|
||||
packet[remain_pos + 7] = 0x04;
|
||||
/* CONNECT flag: CleanSession */
|
||||
packet[remain_pos + 8] = 0x02;
|
||||
/* keep-alive 0 = disabled */
|
||||
packet[remain_pos + 9] = 0x00;
|
||||
packet[remain_pos + 10] = 0x3c;
|
||||
/*end of variable header*/
|
||||
return remain_pos + 10;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_connect(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const size_t client_id_offset = 14;
|
||||
const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN;
|
||||
int pos = 0;
|
||||
int rc = 0;
|
||||
/*remain length*/
|
||||
int remain_pos = 0;
|
||||
char remain[4] = {0};
|
||||
size_t packetlen = 0;
|
||||
size_t payloadlen = 0;
|
||||
size_t start_user = 0;
|
||||
size_t start_pwd = 0;
|
||||
char client_id[MQTT_CLIENTID_LEN + 1] = "curl";
|
||||
const size_t clen = strlen("curl");
|
||||
char packet[32] = {
|
||||
MQTT_MSG_CONNECT, /* packet type */
|
||||
0x00, /* remaining length */
|
||||
0x00, 0x04, /* protocol length */
|
||||
'M','Q','T','T', /* protocol name */
|
||||
0x04, /* protocol level */
|
||||
0x02, /* CONNECT flag: CleanSession */
|
||||
0x00, 0x3c, /* keep-alive 0 = disabled */
|
||||
0x00, 0x00 /* payload1 length */
|
||||
};
|
||||
packet[1] = (packetlen - 2) & 0x7f;
|
||||
packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
|
||||
char *packet = NULL;
|
||||
|
||||
/* extracting username from request */
|
||||
const char *username = data->state.aptr.user ?
|
||||
data->state.aptr.user : "";
|
||||
const size_t ulen = strlen(username);
|
||||
/* extracting password from request */
|
||||
const char *passwd = data->state.aptr.passwd ?
|
||||
data->state.aptr.passwd : "";
|
||||
const size_t plen = strlen(passwd);
|
||||
|
||||
payloadlen = ulen + plen + MQTT_CLIENTID_LEN + 2;
|
||||
/* The plus 2 are for the MSB and LSB describing the length of the string to
|
||||
* be added on the payload. Refer to spec 1.5.2 and 1.5.4 */
|
||||
if(ulen)
|
||||
payloadlen += 2;
|
||||
if(plen)
|
||||
payloadlen += 2;
|
||||
|
||||
/* getting how much occupy the remain length */
|
||||
remain_pos = mqtt_encode_len(remain, payloadlen + 10);
|
||||
|
||||
/* 10 length of variable header and 1 the first byte of the fixed header */
|
||||
packetlen = payloadlen + 10 + remain_pos + 1;
|
||||
|
||||
/* allocating packet */
|
||||
if(packetlen > 268435455)
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
packet = malloc(packetlen);
|
||||
if(!packet)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memset(packet, 0, packetlen);
|
||||
|
||||
/* set initial values for CONN pack */
|
||||
pos = init_connpack(packet, remain, remain_pos);
|
||||
|
||||
result = Curl_rand_hex(data, (unsigned char *)&client_id[clen],
|
||||
MQTT_CLIENTID_LEN - clen + 1);
|
||||
memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
|
||||
infof(data, "Using client id '%s'\n", client_id);
|
||||
/* add client id */
|
||||
rc = add_client_id(client_id, strlen(client_id), packet, pos + 1);
|
||||
if(rc) {
|
||||
failf(data, "Client ID length mismatched: [%lu]", strlen(client_id));
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
goto end;
|
||||
}
|
||||
infof(data, "Using client id '%s'", client_id);
|
||||
|
||||
/* position where starts the user payload */
|
||||
start_user = pos + 3 + MQTT_CLIENTID_LEN;
|
||||
/* position where starts the password payload */
|
||||
start_pwd = start_user + ulen;
|
||||
/* if user name was provided, add it to the packet */
|
||||
if(ulen) {
|
||||
start_pwd += 2;
|
||||
|
||||
rc = add_user(username, ulen,
|
||||
(unsigned char *)packet, start_user, remain_pos);
|
||||
if(rc) {
|
||||
failf(data, "Username is too large: [%lu]", ulen);
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* if passwd was provided, add it to the packet */
|
||||
if(plen) {
|
||||
rc = add_passwd(passwd, plen, packet, start_pwd, remain_pos);
|
||||
if(rc) {
|
||||
failf(data, "Password is too large: [%lu]", plen);
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if(!result)
|
||||
result = mqtt_send(data, packet, packetlen);
|
||||
|
||||
end:
|
||||
if(packet)
|
||||
free(packet);
|
||||
Curl_safefree(data->state.aptr.user);
|
||||
Curl_safefree(data->state.aptr.passwd);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -213,35 +382,12 @@ fail:
|
||||
static CURLcode mqtt_get_topic(struct Curl_easy *data,
|
||||
char **topic, size_t *topiclen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *path = data->state.up.path;
|
||||
|
||||
if(strlen(path) > 1) {
|
||||
result = Curl_urldecode(data, path + 1, 0, topic, topiclen,
|
||||
REJECT_NADA);
|
||||
}
|
||||
else {
|
||||
failf(data, "Error: No topic specified.");
|
||||
result = CURLE_URL_MALFORMAT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int mqtt_encode_len(char *buf, size_t len)
|
||||
{
|
||||
unsigned char encoded;
|
||||
int i;
|
||||
|
||||
for(i = 0; (len > 0) && (i<4); i++) {
|
||||
encoded = len % 0x80;
|
||||
len /= 0x80;
|
||||
if(len)
|
||||
encoded |= 0x80;
|
||||
buf[i] = encoded;
|
||||
}
|
||||
|
||||
return i;
|
||||
if(strlen(path) > 1)
|
||||
return Curl_urldecode(data, path + 1, 0, topic, topiclen,
|
||||
REJECT_NADA);
|
||||
failf(data, "No MQTT topic found. Forgot to URL encode it?");
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_subscribe(struct Curl_easy *data)
|
||||
@@ -418,7 +564,7 @@ static void mqstate(struct Curl_easy *data,
|
||||
struct connectdata *conn = data->conn;
|
||||
struct mqtt_conn *mqtt = &conn->proto.mqtt;
|
||||
#ifdef CURLDEBUG
|
||||
infof(data, "%s (from %s) (next is %s)\n",
|
||||
infof(data, "%s (from %s) (next is %s)",
|
||||
statenames[state],
|
||||
statenames[mqtt->state],
|
||||
(state == MQTT_FIRST)? statenames[nextstate] : "");
|
||||
@@ -465,7 +611,7 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done)
|
||||
goto MQTT_SUBACK_COMING;
|
||||
}
|
||||
else if(packet == MQTT_MSG_DISCONNECT) {
|
||||
infof(data, "Got DISCONNECT\n");
|
||||
infof(data, "Got DISCONNECT");
|
||||
*done = TRUE;
|
||||
goto end;
|
||||
}
|
||||
@@ -476,7 +622,13 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done)
|
||||
|
||||
/* -- switched state -- */
|
||||
remlen = mq->remaining_length;
|
||||
infof(data, "Remaining length: %zd bytes\n", remlen);
|
||||
infof(data, "Remaining length: %zd bytes", remlen);
|
||||
if(data->set.max_filesize &&
|
||||
(curl_off_t)remlen > data->set.max_filesize) {
|
||||
failf(data, "Maximum file size exceeded");
|
||||
result = CURLE_FILESIZE_EXCEEDED;
|
||||
goto end;
|
||||
}
|
||||
Curl_pgrsSetDownloadSize(data, remlen);
|
||||
data->req.bytecount = 0;
|
||||
data->req.size = remlen;
|
||||
@@ -491,12 +643,12 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done)
|
||||
result = Curl_read(data, sockfd, (char *)pkt, rest, &nread);
|
||||
if(result) {
|
||||
if(CURLE_AGAIN == result) {
|
||||
infof(data, "EEEE AAAAGAIN\n");
|
||||
infof(data, "EEEE AAAAGAIN");
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
if(!nread) {
|
||||
infof(data, "server disconnected\n");
|
||||
infof(data, "server disconnected");
|
||||
result = CURLE_PARTIAL_FILE;
|
||||
goto end;
|
||||
}
|
||||
@@ -562,7 +714,7 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
infof(data, "mqtt_doing: state [%d]\n", (int) mqtt->state);
|
||||
infof(data, "mqtt_doing: state [%d]", (int) mqtt->state);
|
||||
switch(mqtt->state) {
|
||||
case MQTT_FIRST:
|
||||
/* Read the initial byte only */
|
||||
@@ -582,6 +734,10 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
|
||||
pkt[mq->npacket++] = byte;
|
||||
} while((byte & 0x80) && (mq->npacket < 4));
|
||||
if(nread && (byte & 0x80))
|
||||
/* MQTT supports up to 127 * 128^0 + 127 * 128^1 + 127 * 128^2 +
|
||||
127 * 128^3 bytes. server tried to send more */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
if(result)
|
||||
break;
|
||||
mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL);
|
||||
@@ -593,7 +749,7 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
mqstate(data, MQTT_FIRST, MQTT_FIRST);
|
||||
|
||||
if(mq->firstbyte == MQTT_MSG_DISCONNECT) {
|
||||
infof(data, "Got DISCONNECT\n");
|
||||
infof(data, "Got DISCONNECT");
|
||||
*done = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
+97
-55
@@ -169,7 +169,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state
|
||||
connection_id = data->conn->connection_id;
|
||||
|
||||
infof(data,
|
||||
"STATE: %s => %s handle %p; line %d (connection #%ld)\n",
|
||||
"STATE: %s => %s handle %p; line %d (connection #%ld)",
|
||||
statename[oldstate], statename[data->mstate],
|
||||
(void *)data, lineno, connection_id);
|
||||
}
|
||||
@@ -562,7 +562,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
struct connectdata *conn = data->conn;
|
||||
unsigned int i;
|
||||
|
||||
DEBUGF(infof(data, "multi_done\n"));
|
||||
DEBUGF(infof(data, "multi_done"));
|
||||
|
||||
if(data->state.done)
|
||||
/* Stop if multi_done() has already been called */
|
||||
@@ -610,7 +610,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
/* Stop if still used. */
|
||||
CONNCACHE_UNLOCK(data);
|
||||
DEBUGF(infof(data, "Connection still in use %zu, "
|
||||
"no more multi_done now!\n",
|
||||
"no more multi_done now!",
|
||||
conn->easyq.size));
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -687,7 +687,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
if(Curl_conncache_return_conn(data, conn)) {
|
||||
/* remember the most recently used connection */
|
||||
data->state.lastconnect_id = conn->connection_id;
|
||||
infof(data, "%s\n", buffer);
|
||||
infof(data, "%s", buffer);
|
||||
}
|
||||
else
|
||||
data->state.lastconnect_id = -1;
|
||||
@@ -709,7 +709,6 @@ static int close_connect_only(struct Curl_easy *data,
|
||||
return 1;
|
||||
|
||||
connclose(conn, "Removing connect-only easy handle");
|
||||
conn->bits.connect_only = FALSE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1043,7 +1042,12 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
||||
|
||||
data = multi->easyp;
|
||||
while(data) {
|
||||
int bitmap = multi_getsock(data, sockbunch);
|
||||
int bitmap;
|
||||
#ifdef __clang_analyzer_
|
||||
/* to prevent "The left operand of '>=' is a garbage value" warnings */
|
||||
memset(sockbunch, 0, sizeof(sockbunch));
|
||||
#endif
|
||||
bitmap = multi_getsock(data, sockbunch);
|
||||
|
||||
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
@@ -1096,6 +1100,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
WSANETWORKEVENTS wsa_events;
|
||||
DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
|
||||
#endif
|
||||
#ifndef ENABLE_WAKEUP
|
||||
(void)use_wakeup;
|
||||
#endif
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@@ -1176,7 +1183,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
#ifdef USE_WINSOCK
|
||||
long mask = 0;
|
||||
#endif
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
|
||||
s = sockbunch[i];
|
||||
#ifdef USE_WINSOCK
|
||||
mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
|
||||
@@ -1185,7 +1192,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
ufds[nfds].events = POLLIN;
|
||||
++nfds;
|
||||
}
|
||||
if(bitmap & GETSOCK_WRITESOCK(i)) {
|
||||
if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
|
||||
s = sockbunch[i];
|
||||
#ifdef USE_WINSOCK
|
||||
mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
|
||||
@@ -1539,6 +1546,58 @@ static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether a timeout occurred, and handle it if it did
|
||||
*/
|
||||
static bool multi_handle_timeout(struct Curl_easy *data,
|
||||
struct curltime *now,
|
||||
bool *stream_error,
|
||||
CURLcode *result,
|
||||
bool connect_timeout)
|
||||
{
|
||||
timediff_t timeout_ms;
|
||||
timeout_ms = Curl_timeleft(data, now, connect_timeout);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* Handle timed out */
|
||||
if(data->mstate == MSTATE_RESOLVING)
|
||||
failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds",
|
||||
Curl_timediff(*now, data->progress.t_startsingle));
|
||||
else if(data->mstate == MSTATE_CONNECTING)
|
||||
failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds",
|
||||
Curl_timediff(*now, data->progress.t_startsingle));
|
||||
else {
|
||||
struct SingleRequest *k = &data->req;
|
||||
if(k->size != -1) {
|
||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes received",
|
||||
Curl_timediff(*now, data->progress.t_startsingle),
|
||||
k->bytecount, k->size);
|
||||
}
|
||||
else {
|
||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes received",
|
||||
Curl_timediff(*now, data->progress.t_startsingle),
|
||||
k->bytecount);
|
||||
}
|
||||
}
|
||||
|
||||
/* Force connection closed if the connection has indeed been used */
|
||||
if(data->mstate > MSTATE_DO) {
|
||||
streamclose(data->conn, "Disconnected with pending data");
|
||||
*stream_error = TRUE;
|
||||
}
|
||||
*result = CURLE_OPERATION_TIMEDOUT;
|
||||
(void)multi_done(data, *result, TRUE);
|
||||
}
|
||||
|
||||
return (timeout_ms < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are doing protocol-specific connecting and this is being called over and
|
||||
* over from the multi interface until the connection phase is done on
|
||||
@@ -1670,7 +1729,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
bool done = FALSE;
|
||||
CURLMcode rc;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout_ms;
|
||||
timediff_t recv_timeout_ms;
|
||||
timediff_t send_timeout_ms;
|
||||
int control;
|
||||
@@ -1685,7 +1743,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!\n"));
|
||||
DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!"));
|
||||
process_pending_handles(multi); /* multiplexed */
|
||||
}
|
||||
|
||||
@@ -1700,47 +1758,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
if(data->conn &&
|
||||
(data->mstate >= MSTATE_CONNECT) &&
|
||||
(data->mstate < MSTATE_COMPLETED)) {
|
||||
/* Check for overall operation timeout here but defer handling the
|
||||
* connection timeout to later, to allow for a connection to be set up
|
||||
* in the window since we last checked timeout. This prevents us
|
||||
* tearing down a completed connection in the case where we were slow
|
||||
* to check the timeout (e.g. process descheduled during this loop).
|
||||
* We set connect_timeout=FALSE to do this. */
|
||||
|
||||
/* we need to wait for the connect state as only then is the start time
|
||||
stored, but we must not check already completed handles */
|
||||
timeout_ms = Curl_timeleft(data, nowp,
|
||||
(data->mstate <= MSTATE_DO)?
|
||||
TRUE:FALSE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* Handle timed out */
|
||||
if(data->mstate == MSTATE_RESOLVING)
|
||||
failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds",
|
||||
Curl_timediff(*nowp, data->progress.t_startsingle));
|
||||
else if(data->mstate == MSTATE_CONNECTING)
|
||||
failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds",
|
||||
Curl_timediff(*nowp, data->progress.t_startsingle));
|
||||
else {
|
||||
struct SingleRequest *k = &data->req;
|
||||
if(k->size != -1) {
|
||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes received",
|
||||
Curl_timediff(*nowp, data->progress.t_startsingle),
|
||||
k->bytecount, k->size);
|
||||
}
|
||||
else {
|
||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes received",
|
||||
Curl_timediff(*nowp, data->progress.t_startsingle),
|
||||
k->bytecount);
|
||||
}
|
||||
}
|
||||
|
||||
/* Force connection closed if the connection has indeed been used */
|
||||
if(data->mstate > MSTATE_DO) {
|
||||
streamclose(data->conn, "Disconnected with pending data");
|
||||
stream_error = TRUE;
|
||||
}
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
(void)multi_done(data, result, TRUE);
|
||||
if(multi_handle_timeout(data, nowp, &stream_error, &result, FALSE)) {
|
||||
/* Skip the statemachine and go directly to error handling section. */
|
||||
goto statemachine_end;
|
||||
}
|
||||
@@ -1792,7 +1819,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
}
|
||||
else if(data->state.previouslypending) {
|
||||
/* this transfer comes from the pending queue so try move another */
|
||||
infof(data, "Transfer was pending, now try another\n");
|
||||
infof(data, "Transfer was pending, now try another");
|
||||
process_pending_handles(data->multi);
|
||||
}
|
||||
|
||||
@@ -1847,7 +1874,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
data->state.async.done = TRUE;
|
||||
#endif
|
||||
result = CURLE_OK;
|
||||
infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
|
||||
infof(data, "Hostname '%s' was found in DNS cache", hostname);
|
||||
}
|
||||
|
||||
if(!dns)
|
||||
@@ -2279,7 +2306,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!\n");
|
||||
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 */
|
||||
@@ -2418,6 +2445,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
default:
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if(data->conn &&
|
||||
data->mstate >= MSTATE_CONNECT &&
|
||||
data->mstate < MSTATE_DO &&
|
||||
rc != CURLM_CALL_MULTI_PERFORM &&
|
||||
!multi_ischanged(multi, false)) {
|
||||
/* We now handle stream timeouts if and only if this will be the last
|
||||
* loop iteration. We only check this on the last iteration to ensure
|
||||
* that if we know we have additional work to do immediately
|
||||
* (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before
|
||||
* declaring the connection timed out as we may almost have a completed
|
||||
* connection. */
|
||||
multi_handle_timeout(data, nowp, &stream_error, &result, TRUE);
|
||||
}
|
||||
|
||||
statemachine_end:
|
||||
|
||||
if(data->mstate < MSTATE_COMPLETED) {
|
||||
@@ -3339,7 +3381,7 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
|
||||
rc = Curl_splayremove(multi->timetree, &data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error removing splay node = %d\n", rc);
|
||||
infof(data, "Internal error removing splay node = %d", rc);
|
||||
}
|
||||
|
||||
/* Indicate that we are in the splay tree and insert the new timer expiry
|
||||
@@ -3386,7 +3428,7 @@ void Curl_expire_clear(struct Curl_easy *data)
|
||||
rc = Curl_splayremove(multi->timetree, &data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||
infof(data, "Internal error clearing splay node = %d", rc);
|
||||
|
||||
/* flush the timeout list too */
|
||||
while(list->size > 0) {
|
||||
@@ -3394,7 +3436,7 @@ void Curl_expire_clear(struct Curl_easy *data)
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared (transfer %p)\n", data);
|
||||
infof(data, "Expire cleared (transfer %p)", data);
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
|
||||
@@ -153,6 +153,9 @@ struct Curl_multi {
|
||||
bool recheckstate; /* see Curl_multi_connchanged */
|
||||
bool in_callback; /* true while executing a callback */
|
||||
bool ipv6_works;
|
||||
#ifdef USE_OPENSSL
|
||||
bool ssl_seeded;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* HEADER_CURL_MULTIHANDLE_H */
|
||||
|
||||
+21
-4
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -42,7 +42,8 @@
|
||||
enum host_lookup_state {
|
||||
NOTHING,
|
||||
HOSTFOUND, /* the 'machine' keyword was found */
|
||||
HOSTVALID /* this is "our" machine! */
|
||||
HOSTVALID, /* this is "our" machine! */
|
||||
MACDEF
|
||||
};
|
||||
|
||||
#define NETRC_FILE_MISSING 1
|
||||
@@ -84,12 +85,17 @@ static int parsenetrc(const char *host,
|
||||
int netrcbuffsize = (int)sizeof(netrcbuffer);
|
||||
|
||||
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
|
||||
if(state == MACDEF) {
|
||||
if((netrcbuffer[0] == '\n') || (netrcbuffer[0] == '\r'))
|
||||
state = NOTHING;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
tok = strtok_r(netrcbuffer, " \t\n", &tok_buf);
|
||||
if(tok && *tok == '#')
|
||||
/* treat an initial hash as a comment line */
|
||||
continue;
|
||||
while(tok) {
|
||||
|
||||
if((login && *login) && (password && *password)) {
|
||||
done = TRUE;
|
||||
break;
|
||||
@@ -97,7 +103,13 @@ static int parsenetrc(const char *host,
|
||||
|
||||
switch(state) {
|
||||
case NOTHING:
|
||||
if(strcasecompare("machine", tok)) {
|
||||
if(strcasecompare("macdef", tok)) {
|
||||
/* Define a macro. A macro is defined with the specified name; its
|
||||
contents begin with the next .netrc line and continue until a
|
||||
null line (consecutive new-line characters) is encountered. */
|
||||
state = MACDEF;
|
||||
}
|
||||
else if(strcasecompare("machine", tok)) {
|
||||
/* the next tok is the machine name, this is in itself the
|
||||
delimiter that starts the stuff entered for this machine,
|
||||
after this we need to search for 'login' and
|
||||
@@ -109,6 +121,11 @@ static int parsenetrc(const char *host,
|
||||
retcode = NETRC_SUCCESS; /* we did find our host */
|
||||
}
|
||||
break;
|
||||
case MACDEF:
|
||||
if(!strlen(tok)) {
|
||||
state = NOTHING;
|
||||
}
|
||||
break;
|
||||
case HOSTFOUND:
|
||||
if(strcasecompare(host, tok)) {
|
||||
/* and yes, this is our host! */
|
||||
|
||||
+10
-6
@@ -31,6 +31,7 @@
|
||||
#include "sendf.h"
|
||||
#include "urldata.h"
|
||||
#include "multiif.h"
|
||||
#include "strerror.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@@ -104,6 +105,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
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)
|
||||
@@ -116,7 +118,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +132,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"The Curl_convert_to_network iconv call failed with errno %i: %s",
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
@@ -170,6 +172,7 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
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)
|
||||
@@ -182,7 +185,7 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK,
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +199,7 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
#else
|
||||
@@ -237,6 +240,7 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
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)
|
||||
@@ -249,7 +253,7 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||
CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8,
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +267,7 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
|
||||
if((rc == ICONV_ERROR) || (in_bytes)) {
|
||||
failf(data,
|
||||
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
|
||||
errno, strerror(errno));
|
||||
errno, Curl_strerror(errno, ebuffer, sizeof(ebuffer)));
|
||||
return CURLE_CONV_FAILED;
|
||||
}
|
||||
if(output_ptr < input_ptr) {
|
||||
|
||||
+5
-4
@@ -247,7 +247,7 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
|
||||
#ifdef USE_SSL
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
CURLcode result;
|
||||
result = Curl_ssl_connect_nonblocking(data, conn,
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &li->ssldone);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -270,7 +270,8 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
/* Is the SSL handshake complete yet? */
|
||||
if(!li->ssldone) {
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET,
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET,
|
||||
&li->ssldone);
|
||||
if(result || !li->ssldone)
|
||||
return result;
|
||||
@@ -399,7 +400,7 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
connkeep(conn, "OpenLDAP do");
|
||||
|
||||
infof(data, "LDAP local: %s\n", data->state.url);
|
||||
infof(data, "LDAP local: %s", data->state.url);
|
||||
|
||||
rc = ldap_url_parse(data->state.url, &ludp);
|
||||
if(rc != LDAP_URL_SUCCESS) {
|
||||
@@ -509,7 +510,7 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
else {
|
||||
/* successful */
|
||||
if(code == LDAP_SIZELIMIT_EXCEEDED)
|
||||
infof(data, "There are more than %d entries\n", lr->nument);
|
||||
infof(data, "There are more than %d entries", lr->nument);
|
||||
data->req.size = data->req.bytecount;
|
||||
*err = CURLE_OK;
|
||||
ret = 0;
|
||||
|
||||
+2
-2
@@ -402,7 +402,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
clipamount = gotbytes - i;
|
||||
restart = TRUE;
|
||||
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
|
||||
"server response left\n",
|
||||
"server response left",
|
||||
(int)clipamount));
|
||||
}
|
||||
else if(keepon) {
|
||||
@@ -412,7 +412,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
with it. We keep the first bytes of the line then we throw
|
||||
away the rest. */
|
||||
infof(data, "Excessive server response line length received, "
|
||||
"%zd bytes. Stripping\n", gotbytes);
|
||||
"%zd bytes. Stripping", gotbytes);
|
||||
restart = TRUE;
|
||||
|
||||
/* we keep 40 bytes since all our pingpong protocols are only
|
||||
|
||||
+28
-29
@@ -75,7 +75,6 @@
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
@@ -308,7 +307,7 @@ static void state(struct Curl_easy *data, pop3state newstate)
|
||||
};
|
||||
|
||||
if(pop3c->state != newstate)
|
||||
infof(data, "POP3 %p state change from %s to %s\n",
|
||||
infof(data, "POP3 %p state change from %s to %s",
|
||||
(void *)pop3c, names[pop3c->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@@ -370,8 +369,9 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
|
||||
{
|
||||
/* Start the SSL connection */
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET,
|
||||
&pop3c->ssldone);
|
||||
CURLcode result =
|
||||
Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET,
|
||||
&pop3c->ssldone);
|
||||
|
||||
if(!result) {
|
||||
if(pop3c->state != POP3_UPGRADETLS)
|
||||
@@ -551,7 +551,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!\n");
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -740,28 +740,23 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pop3code == '+') {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested */
|
||||
if(pop3c->tls_supported)
|
||||
/* Switch to TLS connection now */
|
||||
result = pop3_perform_starttls(data, conn);
|
||||
else if(data->set.use_ssl == CURLUSESSL_TRY)
|
||||
/* Fallback and carry on with authentication */
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
else {
|
||||
failf(data, "STLS not supported.");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
}
|
||||
else {
|
||||
/* Clear text is supported when CAPA isn't recognised */
|
||||
pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
|
||||
if(pop3code != '+')
|
||||
pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
|
||||
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use)
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
else if(pop3code == '+' && pop3c->tls_supported)
|
||||
/* Switch to TLS connection now */
|
||||
result = pop3_perform_starttls(data, conn);
|
||||
else if(data->set.use_ssl <= CURLUSESSL_TRY)
|
||||
/* Fallback and carry on with authentication */
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
else {
|
||||
failf(data, "STLS not supported.");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -776,6 +771,10 @@ static CURLcode pop3_state_starttls_resp(struct Curl_easy *data,
|
||||
CURLcode result = CURLE_OK;
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
/* Pipelining in response is forbidden. */
|
||||
if(data->conn->proto.pop3c.pp.cache_size)
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
if(pop3code != '+') {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied");
|
||||
@@ -1031,7 +1030,7 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
|
||||
result = Curl_ssl_connect_nonblocking(data, conn,
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &pop3c->ssldone);
|
||||
if(result || !pop3c->ssldone)
|
||||
return result;
|
||||
@@ -1172,7 +1171,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
|
||||
struct connectdata *conn = data->conn;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts"));
|
||||
|
||||
if(data->set.opt_no_body) {
|
||||
/* Requested no body means no transfer */
|
||||
@@ -1191,7 +1190,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1274,11 +1273,11 @@ static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
CURLcode result = pop3_multi_statemach(data, dophase_done);
|
||||
|
||||
if(result)
|
||||
DEBUGF(infof(data, "DO phase failed\n"));
|
||||
DEBUGF(infof(data, "DO phase failed"));
|
||||
else if(*dophase_done) {
|
||||
result = pop3_dophase_done(data, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
+6
-1
@@ -377,7 +377,12 @@ static curl_off_t trspeed(curl_off_t size, /* number of bytes */
|
||||
{
|
||||
if(us < 1)
|
||||
return size * 1000000;
|
||||
return (curl_off_t)((long double)size/us * 1000000);
|
||||
else if(size < CURL_OFF_T_MAX/1000000)
|
||||
return (size * 1000000) / us;
|
||||
else if(us >= 1000000)
|
||||
return size / (us / 1000000);
|
||||
else
|
||||
return CURL_OFF_T_MAX;
|
||||
}
|
||||
|
||||
/* returns TRUE if it's time to show the progress meter */
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ CURLcode Curl_quic_is_connected(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected);
|
||||
int Curl_quic_ver(char *p, size_t len);
|
||||
void Curl_quic_ver(char *p, size_t len);
|
||||
CURLcode Curl_quic_done_sending(struct Curl_easy *data);
|
||||
void Curl_quic_done(struct Curl_easy *data, bool premature);
|
||||
bool Curl_quic_data_pending(const struct Curl_easy *data);
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -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\n");
|
||||
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;
|
||||
|
||||
+3
-3
@@ -231,7 +231,7 @@ static CURLcode rtsp_done(struct Curl_easy *data,
|
||||
}
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
(data->conn->proto.rtspc.rtp_channel == -1)) {
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +651,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
}
|
||||
/* We have the full RTP interleaved packet
|
||||
* Write out the header including the leading '$' */
|
||||
DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
|
||||
DEBUGF(infof(data, "RTP write channel %d rtp_length %d",
|
||||
rtspc->rtp_channel, rtp_length));
|
||||
result = rtp_client_write(data, &rtp[0], rtp_length + 4);
|
||||
if(result) {
|
||||
@@ -682,7 +682,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if(rtp_dataleft && rtp[0] == '$') {
|
||||
DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
|
||||
DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft,
|
||||
*readmore ? "(READMORE)" : ""));
|
||||
|
||||
/* Store the incomplete RTP packet for a "rewind" */
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef USE_HYPER
|
||||
#define CURL_DISABLE_RTSP
|
||||
#define CURL_DISABLE_RTSP 1
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
|
||||
@@ -106,7 +106,11 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#ifdef HAVE_POLL_FINE
|
||||
#define VALID_SOCK(s) ((s) >= 0) /* FD_SETSIZE is irrelevant for poll */
|
||||
#else
|
||||
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
|
||||
#endif
|
||||
#define VERIFY_SOCK(x) do { \
|
||||
if(!VALID_SOCK(x)) { \
|
||||
SET_SOCKERRNO(EINVAL); \
|
||||
|
||||
+9
-17
@@ -236,29 +236,21 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
|
||||
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
|
||||
/* Curl_infof() is for info message along the way */
|
||||
#define MAXINFO 2048
|
||||
|
||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(data && data->set.verbose) {
|
||||
va_list ap;
|
||||
size_t len;
|
||||
char print_buffer[2048 + 1];
|
||||
char buffer[MAXINFO + 2];
|
||||
va_start(ap, fmt);
|
||||
len = mvsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
|
||||
/*
|
||||
* Indicate truncation of the input by replacing the last 3 characters
|
||||
* with "...", and transfer the newline over in case the format had one.
|
||||
*/
|
||||
if(len >= sizeof(print_buffer)) {
|
||||
len = strlen(fmt);
|
||||
if(fmt[--len] == '\n')
|
||||
msnprintf(print_buffer + (sizeof(print_buffer) - 5), 5, "...\n");
|
||||
else
|
||||
msnprintf(print_buffer + (sizeof(print_buffer) - 4), 4, "...");
|
||||
}
|
||||
len = mvsnprintf(buffer, MAXINFO, fmt, ap);
|
||||
va_end(ap);
|
||||
len = strlen(print_buffer);
|
||||
Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = '\0';
|
||||
Curl_debug(data, CURLINFO_TEXT, buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,14 +266,14 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
size_t len;
|
||||
char error[CURL_ERROR_SIZE + 2];
|
||||
va_start(ap, fmt);
|
||||
(void)mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
len = strlen(error);
|
||||
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
|
||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||
strcpy(data->set.errorbuffer, error);
|
||||
data->state.errorbuf = TRUE; /* wrote error string */
|
||||
}
|
||||
error[len++] = '\n';
|
||||
error[len] = '\0';
|
||||
Curl_debug(data, CURLINFO_TEXT, error, len);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
+7
-7
@@ -1689,7 +1689,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_SSLCERT_BLOB:
|
||||
/*
|
||||
* Blob that holds file name of the SSL certificate to use
|
||||
* Blob that holds file content of the SSL certificate to use
|
||||
*/
|
||||
result = Curl_setblobopt(&data->set.blobs[BLOB_CERT],
|
||||
va_arg(param, struct curl_blob *));
|
||||
@@ -1704,7 +1704,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_PROXY_SSLCERT_BLOB:
|
||||
/*
|
||||
* Blob that holds file name of the SSL certificate to use for proxy
|
||||
* Blob that holds file content of the SSL certificate to use for proxy
|
||||
*/
|
||||
result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY],
|
||||
va_arg(param, struct curl_blob *));
|
||||
@@ -1735,7 +1735,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_SSLKEY_BLOB:
|
||||
/*
|
||||
* Blob that holds file name of the SSL key to use
|
||||
* Blob that holds file content of the SSL key to use
|
||||
*/
|
||||
result = Curl_setblobopt(&data->set.blobs[BLOB_KEY],
|
||||
va_arg(param, struct curl_blob *));
|
||||
@@ -1750,7 +1750,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_PROXY_SSLKEY_BLOB:
|
||||
/*
|
||||
* Blob that holds file name of the SSL key to use for proxy
|
||||
* Blob that holds file content of the SSL key to use for proxy
|
||||
*/
|
||||
result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY],
|
||||
va_arg(param, struct curl_blob *));
|
||||
@@ -1872,7 +1872,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_DOH_SSL_VERIFYPEER:
|
||||
/*
|
||||
* Enable peer SSL verifying for DOH.
|
||||
* Enable peer SSL verifying for DoH.
|
||||
*/
|
||||
data->set.doh_verifypeer = (0 != va_arg(param, long)) ?
|
||||
TRUE : FALSE;
|
||||
@@ -1911,7 +1911,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_DOH_SSL_VERIFYHOST:
|
||||
/*
|
||||
* Enable verification of the host name in the peer certificate for DOH
|
||||
* Enable verification of the host name in the peer certificate for DoH
|
||||
*/
|
||||
arg = va_arg(param, long);
|
||||
|
||||
@@ -1955,7 +1955,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
break;
|
||||
case CURLOPT_DOH_SSL_VERIFYSTATUS:
|
||||
/*
|
||||
* Enable certificate status verifying for DOH.
|
||||
* Enable certificate status verifying for DoH.
|
||||
*/
|
||||
if(!Curl_ssl_cert_status_request()) {
|
||||
result = CURLE_NOT_BUILT_IN;
|
||||
|
||||
+9
-8
@@ -42,8 +42,9 @@
|
||||
#ifdef USE_MBEDTLS
|
||||
#include <mbedtls/version.h>
|
||||
|
||||
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
|
||||
#define HAS_RESULT_CODE_BASED_FUNCTIONS
|
||||
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
|
||||
(MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
#define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
|
||||
#endif
|
||||
#endif /* USE_MBEDTLS */
|
||||
|
||||
@@ -105,8 +106,8 @@ typedef mbedtls_sha256_context SHA256_CTX;
|
||||
|
||||
static void SHA256_Init(SHA256_CTX *ctx)
|
||||
{
|
||||
#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_sha256_starts(ctx, 0);
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_sha256_starts(ctx, 0);
|
||||
#else
|
||||
(void) mbedtls_sha256_starts_ret(ctx, 0);
|
||||
#endif
|
||||
@@ -116,8 +117,8 @@ static void SHA256_Update(SHA256_CTX *ctx,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_sha256_update(ctx, data, length);
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_sha256_update(ctx, data, length);
|
||||
#else
|
||||
(void) mbedtls_sha256_update_ret(ctx, data, length);
|
||||
#endif
|
||||
@@ -125,8 +126,8 @@ static void SHA256_Update(SHA256_CTX *ctx,
|
||||
|
||||
static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
|
||||
{
|
||||
#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
mbedtls_sha256_finish(ctx, digest);
|
||||
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
|
||||
(void) mbedtls_sha256_finish(ctx, digest);
|
||||
#else
|
||||
(void) mbedtls_sha256_finish_ret(ctx, digest);
|
||||
#endif
|
||||
|
||||
@@ -204,7 +204,7 @@ static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate)
|
||||
};
|
||||
|
||||
if(smbc->state != newstate)
|
||||
infof(data, "SMB conn %p state change from %s to %s\n",
|
||||
infof(data, "SMB conn %p state change from %s to %s",
|
||||
(void *)smbc, names[smbc->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@@ -230,7 +230,7 @@ static void request_state(struct Curl_easy *data,
|
||||
};
|
||||
|
||||
if(req->state != newstate)
|
||||
infof(data, "SMB request %p state change from %s to %s\n",
|
||||
infof(data, "SMB request %p state change from %s to %s",
|
||||
(void *)req, names[req->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@@ -670,7 +670,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
|
||||
#ifdef USE_SSL
|
||||
if((conn->handler->flags & PROTOPT_SSL)) {
|
||||
bool ssl_done = FALSE;
|
||||
result = Curl_ssl_connect_nonblocking(data, conn,
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &ssl_done);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
return result;
|
||||
|
||||
+13
-9
@@ -78,7 +78,6 @@
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
@@ -308,7 +307,7 @@ static void state(struct Curl_easy *data, smtpstate newstate)
|
||||
};
|
||||
|
||||
if(smtpc->state != newstate)
|
||||
infof(data, "SMTP %p state change from %s to %s\n",
|
||||
infof(data, "SMTP %p state change from %s to %s",
|
||||
(void *)smtpc, names[smtpc->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@@ -397,7 +396,8 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
|
||||
/* Start the SSL connection */
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET,
|
||||
CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET,
|
||||
&smtpc->ssldone);
|
||||
|
||||
if(!result) {
|
||||
@@ -484,7 +484,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!\n");
|
||||
infof(data, "No known authentication mechanisms supported!");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@@ -834,6 +834,10 @@ static CURLcode smtp_state_starttls_resp(struct Curl_easy *data,
|
||||
CURLcode result = CURLE_OK;
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
/* Pipelining in response is forbidden. */
|
||||
if(data->conn->proto.smtpc.pp.cache_size)
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
if(smtpcode != 220) {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied, code %d", smtpcode);
|
||||
@@ -1258,7 +1262,7 @@ static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
|
||||
result = Curl_ssl_connect_nonblocking(data, conn,
|
||||
result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
|
||||
FIRSTSOCKET, &smtpc->ssldone);
|
||||
if(result || !smtpc->ssldone)
|
||||
return result;
|
||||
@@ -1455,7 +1459,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SMTP *smtp = data->req.p.smtp;
|
||||
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts"));
|
||||
|
||||
if(data->set.opt_no_body) {
|
||||
/* Requested no body means no transfer */
|
||||
@@ -1495,7 +1499,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1579,11 +1583,11 @@ static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
CURLcode result = smtp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(result)
|
||||
DEBUGF(infof(data, "DO phase failed\n"));
|
||||
DEBUGF(infof(data, "DO phase failed"));
|
||||
else if(*dophase_done) {
|
||||
result = smtp_dophase_done(data, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
+26
-10
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2019 - 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
|
||||
@@ -48,6 +48,10 @@
|
||||
#endif /* !INADDR_LOOPBACK */
|
||||
#endif /* !WIN32 */
|
||||
|
||||
#include "nonblock.h" /* for curlx_nonblock */
|
||||
#include "timeval.h" /* needed before select.h */
|
||||
#include "select.h" /* for Curl_poll */
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -59,12 +63,11 @@ int Curl_socketpair(int domain, int type, int protocol,
|
||||
union {
|
||||
struct sockaddr_in inaddr;
|
||||
struct sockaddr addr;
|
||||
} a;
|
||||
} a, a2;
|
||||
curl_socket_t listener;
|
||||
curl_socklen_t addrlen = sizeof(a.inaddr);
|
||||
int reuse = 1;
|
||||
char data[2][12];
|
||||
ssize_t dlen;
|
||||
struct pollfd pfd[1];
|
||||
(void)domain;
|
||||
(void)type;
|
||||
(void)protocol;
|
||||
@@ -85,7 +88,8 @@ int Curl_socketpair(int domain, int type, int protocol,
|
||||
goto error;
|
||||
if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1)
|
||||
goto error;
|
||||
if(getsockname(listener, &a.addr, &addrlen) == -1)
|
||||
if(getsockname(listener, &a.addr, &addrlen) == -1 ||
|
||||
addrlen < (int)sizeof(a.inaddr))
|
||||
goto error;
|
||||
if(listen(listener, 1) == -1)
|
||||
goto error;
|
||||
@@ -94,18 +98,30 @@ int Curl_socketpair(int domain, int type, int protocol,
|
||||
goto error;
|
||||
if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1)
|
||||
goto error;
|
||||
|
||||
/* use non-blocking accept to make sure we don't block forever */
|
||||
if(curlx_nonblock(listener, TRUE) < 0)
|
||||
goto error;
|
||||
pfd[0].fd = listener;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[0].revents = 0;
|
||||
(void)Curl_poll(pfd, 1, 10*1000); /* 10 seconds */
|
||||
socks[1] = accept(listener, NULL, NULL);
|
||||
if(socks[1] == CURL_SOCKET_BAD)
|
||||
goto error;
|
||||
|
||||
/* verify that nothing else connected */
|
||||
msnprintf(data[0], sizeof(data[0]), "%p", socks);
|
||||
dlen = strlen(data[0]);
|
||||
if(swrite(socks[0], data[0], dlen) != dlen)
|
||||
addrlen = sizeof(a.inaddr);
|
||||
if(getsockname(socks[0], &a.addr, &addrlen) == -1 ||
|
||||
addrlen < (int)sizeof(a.inaddr))
|
||||
goto error;
|
||||
if(sread(socks[1], data[1], sizeof(data[1])) != dlen)
|
||||
addrlen = sizeof(a2.inaddr);
|
||||
if(getpeername(socks[1], &a2.addr, &addrlen) == -1 ||
|
||||
addrlen < (int)sizeof(a2.inaddr))
|
||||
goto error;
|
||||
if(memcmp(data[0], data[1], dlen))
|
||||
if(a.inaddr.sin_family != a2.inaddr.sin_family ||
|
||||
a.inaddr.sin_addr.s_addr != a2.inaddr.sin_addr.s_addr ||
|
||||
a.inaddr.sin_port != a2.inaddr.sin_port)
|
||||
goto error;
|
||||
|
||||
sclose(listener);
|
||||
|
||||
+37
-35
@@ -99,24 +99,24 @@ int Curl_blockread_all(struct Curl_easy *data, /* transfer */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DEBUGBUILD
|
||||
#define sxstate(x,y) socksstate(x,y)
|
||||
#else
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define DEBUG_AND_VERBOSE
|
||||
#define sxstate(x,y) socksstate(x,y, __LINE__)
|
||||
#else
|
||||
#define sxstate(x,y) socksstate(x,y)
|
||||
#endif
|
||||
|
||||
|
||||
/* always use this function to change state, to make debugging easier */
|
||||
static void socksstate(struct Curl_easy *data,
|
||||
enum connect_t state
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef DEBUG_AND_VERBOSE
|
||||
, int lineno
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
enum connect_t oldstate = conn->cnnct.state;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#ifdef DEBUG_AND_VERBOSE
|
||||
/* synced with the state list in urldata.h */
|
||||
static const char * const statename[] = {
|
||||
"INIT",
|
||||
@@ -146,9 +146,9 @@ static void socksstate(struct Curl_easy *data,
|
||||
|
||||
conn->cnnct.state = state;
|
||||
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#ifdef DEBUG_AND_VERBOSE
|
||||
infof(data,
|
||||
"SXSTATE: %s => %s conn %p; line %d\n",
|
||||
"SXSTATE: %s => %s conn %p; line %d",
|
||||
statename[oldstate], statename[conn->cnnct.state], conn,
|
||||
lineno);
|
||||
#endif
|
||||
@@ -214,10 +214,10 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
/* SOCKS4 can only do IPv4, insist! */
|
||||
conn->ip_version = CURL_IPRESOLVE_V4;
|
||||
if(conn->bits.httpproxy)
|
||||
infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
|
||||
infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d",
|
||||
protocol4a ? "a" : "", hostname, remote_port);
|
||||
|
||||
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
|
||||
infof(data, "SOCKS4 communication to %s:%d", hostname, remote_port);
|
||||
|
||||
/*
|
||||
* Compose socks4 request
|
||||
@@ -244,7 +244,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
return CURLPX_RESOLVE_HOST;
|
||||
else if(rc == CURLRESOLV_PENDING) {
|
||||
sxstate(data, CONNECT_RESOLVING);
|
||||
infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
|
||||
infof(data, "SOCKS4 non-blocking resolve of %s", hostname);
|
||||
return CURLPX_OK;
|
||||
}
|
||||
sxstate(data, CONNECT_RESOLVED);
|
||||
@@ -264,7 +264,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
data->state.async.dns = dns;
|
||||
data->state.async.done = TRUE;
|
||||
#endif
|
||||
infof(data, "Hostname '%s' was found\n", hostname);
|
||||
infof(data, "Hostname '%s' was found", hostname);
|
||||
sxstate(data, CONNECT_RESOLVED);
|
||||
}
|
||||
else {
|
||||
@@ -279,18 +279,21 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
CONNECT_RESOLVED:
|
||||
case CONNECT_RESOLVED: {
|
||||
struct Curl_addrinfo *hp = NULL;
|
||||
char buf[64];
|
||||
/*
|
||||
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
|
||||
* returns a Curl_addrinfo pointer that may not always look the same.
|
||||
*/
|
||||
if(dns)
|
||||
if(dns) {
|
||||
hp = dns->addr;
|
||||
if(hp) {
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
if(hp->ai_family == AF_INET) {
|
||||
/* scan for the first IPv4 address */
|
||||
while(hp && (hp->ai_family != AF_INET))
|
||||
hp = hp->ai_next;
|
||||
|
||||
if(hp) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
char buf[64];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
|
||||
socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0];
|
||||
@@ -298,20 +301,19 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2];
|
||||
socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3];
|
||||
|
||||
infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
|
||||
}
|
||||
else {
|
||||
hp = NULL; /* fail! */
|
||||
failf(data, "SOCKS4 connection to %s not supported", buf);
|
||||
}
|
||||
infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)", buf);
|
||||
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
}
|
||||
else
|
||||
failf(data, "SOCKS4 connection to %s not supported", hostname);
|
||||
}
|
||||
if(!hp) {
|
||||
else
|
||||
failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
|
||||
hostname);
|
||||
|
||||
if(!hp)
|
||||
return CURLPX_RESOLVE_HOST;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
CONNECT_REQ_INIT:
|
||||
@@ -435,7 +437,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
/* Result */
|
||||
switch(socksreq[1]) {
|
||||
case 90:
|
||||
infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
|
||||
infof(data, "SOCKS4%s request granted.", protocol4a?"a":"");
|
||||
break;
|
||||
case 91:
|
||||
failf(data,
|
||||
@@ -528,19 +530,19 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
switch(sx->state) {
|
||||
case CONNECT_SOCKS_INIT:
|
||||
if(conn->bits.httpproxy)
|
||||
infof(data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
|
||||
infof(data, "SOCKS5: connecting to HTTP proxy %s port %d",
|
||||
hostname, remote_port);
|
||||
|
||||
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
|
||||
if(!socks5_resolve_local && hostname_len > 255) {
|
||||
infof(data, "SOCKS5: server resolving disabled for hostnames of "
|
||||
"length > 255 [actual len=%zu]\n", hostname_len);
|
||||
"length > 255 [actual len=%zu]", hostname_len);
|
||||
socks5_resolve_local = TRUE;
|
||||
}
|
||||
|
||||
if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
|
||||
infof(data,
|
||||
"warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
|
||||
"warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu",
|
||||
auth);
|
||||
if(!(auth & CURLAUTH_BASIC))
|
||||
/* disable username/password auth */
|
||||
@@ -778,7 +780,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
data->state.async.dns = dns;
|
||||
data->state.async.done = TRUE;
|
||||
#endif
|
||||
infof(data, "SOCKS5: hostname '%s' found\n", hostname);
|
||||
infof(data, "SOCKS5: hostname '%s' found", hostname);
|
||||
}
|
||||
|
||||
if(!dns) {
|
||||
@@ -820,7 +822,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", dest);
|
||||
infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)", dest);
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(hp->ai_family == AF_INET6) {
|
||||
@@ -834,7 +836,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", dest);
|
||||
infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)", dest);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
@@ -858,7 +860,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
socksreq[len++] = (char) hostname_len; /* one byte address length */
|
||||
memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
|
||||
len += hostname_len;
|
||||
infof(data, "SOCKS5 connect to %s:%d (remotely resolved)\n",
|
||||
infof(data, "SOCKS5 connect to %s:%d (remotely resolved)",
|
||||
hostname, remote_port);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -1022,7 +1024,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
}
|
||||
sxstate(data, CONNECT_DONE);
|
||||
}
|
||||
infof(data, "SOCKS5 request granted.\n");
|
||||
infof(data, "SOCKS5 request granted.");
|
||||
|
||||
*done = TRUE;
|
||||
return CURLPX_OK; /* Proxy was successful! */
|
||||
|
||||
+3
-3
@@ -328,7 +328,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
user[gss_send_token.length] = '\0';
|
||||
gss_release_name(&gss_status, &gss_client_name);
|
||||
gss_release_buffer(&gss_status, &gss_send_token);
|
||||
infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",user);
|
||||
infof(data, "SOCKS5 server authenticated user %s with GSS-API.",user);
|
||||
free(user);
|
||||
user = NULL;
|
||||
|
||||
@@ -344,7 +344,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
else if(gss_ret_flags & GSS_C_INTEG_FLAG)
|
||||
gss_enc = 1;
|
||||
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.",
|
||||
(gss_enc == 0)?"no":((gss_enc==1)?"integrity":"confidentiality"));
|
||||
/* force for the moment to no data protection */
|
||||
gss_enc = 0;
|
||||
@@ -518,7 +518,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
infof(data, "SOCKS5 access with%s protection granted.\n",
|
||||
infof(data, "SOCKS5 access with%s protection granted.",
|
||||
(socksreq[0] == 0)?"out GSS-API data":
|
||||
((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
|
||||
|
||||
|
||||
+3
-3
@@ -327,7 +327,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
failf(data, "Failed to determine user name.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",
|
||||
infof(data, "SOCKS5 server authenticated user %s with GSS-API.",
|
||||
names.sUserName);
|
||||
s_pSecFn->FreeContextBuffer(names.sUserName);
|
||||
|
||||
@@ -343,7 +343,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
|
||||
gss_enc = 1;
|
||||
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
|
||||
infof(data, "SOCKS5 server supports GSS-API %s data protection.",
|
||||
(gss_enc == 0)?"no":((gss_enc == 1)?"integrity":"confidentiality") );
|
||||
/* force to no data protection, avoid encryption/decryption for now */
|
||||
gss_enc = 0;
|
||||
@@ -591,7 +591,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
}
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
infof(data, "SOCKS5 access with%s protection granted.\n",
|
||||
infof(data, "SOCKS5 access with%s protection granted.",
|
||||
(socksreq[0] == 0)?"out GSS-API data":
|
||||
((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
|
||||
|
||||
|
||||
+27
-1
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "strdup.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
@@ -50,6 +54,28 @@ char *curlx_strdup(const char *str)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/***************************************************************************
|
||||
*
|
||||
* Curl_wcsdup(source)
|
||||
*
|
||||
* Copies the 'source' wchar string to a newly allocated buffer (that is
|
||||
* returned).
|
||||
*
|
||||
* Returns the new pointer or NULL on failure.
|
||||
*
|
||||
***************************************************************************/
|
||||
wchar_t *Curl_wcsdup(const wchar_t *src)
|
||||
{
|
||||
size_t length = wcslen(src);
|
||||
|
||||
if(length > (SIZE_T_MAX / sizeof(wchar_t)) - 1)
|
||||
return (wchar_t *)NULL; /* integer overflow */
|
||||
|
||||
return (wchar_t *)Curl_memdup(src, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Curl_memdup(source, length)
|
||||
|
||||
+4
-1
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -26,6 +26,9 @@
|
||||
#ifndef HAVE_STRDUP
|
||||
extern char *curlx_strdup(const char *str);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
wchar_t* Curl_wcsdup(const wchar_t* src);
|
||||
#endif
|
||||
void *Curl_memdup(const void *src, size_t buffer_length);
|
||||
void *Curl_saferealloc(void *ptr, size_t size);
|
||||
|
||||
|
||||
+3
-2
@@ -188,8 +188,8 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_UNKNOWN_OPTION:
|
||||
return "An unknown option was passed in to libcurl";
|
||||
|
||||
case CURLE_TELNET_OPTION_SYNTAX :
|
||||
return "Malformed telnet option";
|
||||
case CURLE_SETOPT_OPTION_SYNTAX :
|
||||
return "Malformed option provided in a setopt";
|
||||
|
||||
case CURLE_GOT_NOTHING:
|
||||
return "Server returned nothing (no headers, no data)";
|
||||
@@ -731,6 +731,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
|
||||
max = buflen - 1;
|
||||
*buf = '\0';
|
||||
|
||||
/* !checksrc! disable STRERROR 2 */
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#if defined(WIN32)
|
||||
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
|
||||
|
||||
+18
-15
@@ -268,9 +268,9 @@ static void printoption(struct Curl_easy *data,
|
||||
if(data->set.verbose) {
|
||||
if(cmd == CURL_IAC) {
|
||||
if(CURL_TELCMD_OK(option))
|
||||
infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
|
||||
infof(data, "%s IAC %s", direction, CURL_TELCMD(option));
|
||||
else
|
||||
infof(data, "%s IAC %d\n", direction, option);
|
||||
infof(data, "%s IAC %d", direction, option);
|
||||
}
|
||||
else {
|
||||
const char *fmt = (cmd == CURL_WILL) ? "WILL" :
|
||||
@@ -287,12 +287,12 @@ static void printoption(struct Curl_easy *data,
|
||||
opt = NULL;
|
||||
|
||||
if(opt)
|
||||
infof(data, "%s %s %s\n", direction, fmt, opt);
|
||||
infof(data, "%s %s %s", direction, fmt, opt);
|
||||
else
|
||||
infof(data, "%s %s %d\n", direction, fmt, option);
|
||||
infof(data, "%s %s %d", direction, fmt, option);
|
||||
}
|
||||
else
|
||||
infof(data, "%s %d %d\n", direction, cmd, option);
|
||||
infof(data, "%s %d %d", direction, cmd, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -765,8 +765,6 @@ static void printsub(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(direction)
|
||||
infof(data, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,7 +832,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data)
|
||||
tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
|
||||
else {
|
||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||
result = CURLE_TELNET_OPTION_SYNTAX;
|
||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
@@ -855,7 +853,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data)
|
||||
break;
|
||||
}
|
||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||
result = CURLE_TELNET_OPTION_SYNTAX;
|
||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -922,12 +920,17 @@ static void suboption(struct Curl_easy *data)
|
||||
size_t tmplen = (strlen(v->data) + 1);
|
||||
/* Add the variable only if it fits */
|
||||
if(len + tmplen < (int)sizeof(temp)-6) {
|
||||
if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) {
|
||||
msnprintf((char *)&temp[len], sizeof(temp) - len,
|
||||
"%c%s%c%s", CURL_NEW_ENV_VAR, varname,
|
||||
CURL_NEW_ENV_VALUE, varval);
|
||||
len += tmplen;
|
||||
}
|
||||
int rv;
|
||||
char sep[2] = "";
|
||||
varval[0] = 0;
|
||||
rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval);
|
||||
if(rv == 1)
|
||||
len += msnprintf((char *)&temp[len], sizeof(temp) - len,
|
||||
"%c%s", CURL_NEW_ENV_VAR, varname);
|
||||
else if(rv >= 2)
|
||||
len += msnprintf((char *)&temp[len], sizeof(temp) - len,
|
||||
"%c%s%c%s", CURL_NEW_ENV_VAR, varname,
|
||||
CURL_NEW_ENV_VALUE, varval);
|
||||
}
|
||||
}
|
||||
msnprintf((char *)&temp[len], sizeof(temp) - len,
|
||||
|
||||
+20
-20
@@ -239,7 +239,7 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
|
||||
|
||||
infof(state->data,
|
||||
"set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T
|
||||
", retry %d maxtry %d\n",
|
||||
", retry %d maxtry %d",
|
||||
(int)state->state, timeout_ms, state->retry_time, state->retry_max);
|
||||
|
||||
/* init RX time */
|
||||
@@ -325,7 +325,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
}
|
||||
|
||||
infof(data, "got option=(%s) value=(%s)\n", option, value);
|
||||
infof(data, "got option=(%s) value=(%s)", option, value);
|
||||
|
||||
if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
|
||||
long blksize;
|
||||
@@ -356,14 +356,14 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||
}
|
||||
|
||||
state->blksize = (int)blksize;
|
||||
infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
|
||||
infof(data, "%s (%d) %s (%d)", "blksize parsed from OACK",
|
||||
state->blksize, "requested", state->requested_blksize);
|
||||
}
|
||||
else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
|
||||
long tsize = 0;
|
||||
|
||||
tsize = strtol(value, NULL, 10);
|
||||
infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize);
|
||||
infof(data, "%s (%ld)", "tsize parsed from OACK", tsize);
|
||||
|
||||
/* tsize should be ignored on upload: Who cares about the size of the
|
||||
remote file? */
|
||||
@@ -397,7 +397,7 @@ static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
infof(data, "%s\n", "Connected for transmit");
|
||||
infof(data, "%s", "Connected for transmit");
|
||||
#endif
|
||||
state->state = TFTP_STATE_TX;
|
||||
result = tftp_set_timeouts(state);
|
||||
@@ -413,7 +413,7 @@ static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
infof(data, "%s\n", "Connected for receive");
|
||||
infof(data, "%s", "Connected for receive");
|
||||
#endif
|
||||
state->state = TFTP_STATE_RX;
|
||||
result = tftp_set_timeouts(state);
|
||||
@@ -596,12 +596,12 @@ static CURLcode tftp_rx(struct tftp_state_data *state,
|
||||
else if(state->block == rblock) {
|
||||
/* This is the last recently received block again. Log it and ACK it
|
||||
again. */
|
||||
infof(data, "Received last DATA packet block %d again.\n", rblock);
|
||||
infof(data, "Received last DATA packet block %d again.", rblock);
|
||||
}
|
||||
else {
|
||||
/* totally unexpected, just log it */
|
||||
infof(data,
|
||||
"Received unexpected DATA packet block %d, expecting block %d\n",
|
||||
"Received unexpected DATA packet block %d, expecting block %d",
|
||||
rblock, NEXT_BLOCKNUM(state->block));
|
||||
break;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state,
|
||||
/* Increment the retry count and fail if over the limit */
|
||||
state->retries++;
|
||||
infof(data,
|
||||
"Timeout waiting for block %d ACK. Retries = %d\n",
|
||||
"Timeout waiting for block %d ACK. Retries = %d",
|
||||
NEXT_BLOCKNUM(state->block), state->retries);
|
||||
if(state->retries > state->retry_max) {
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
@@ -720,11 +720,11 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
|
||||
/* There's a bug in tftpd-hpa that causes it to send us an ack for
|
||||
* 65535 when the block number wraps to 0. So when we're expecting
|
||||
* 0, also accept 65535. See
|
||||
* http://syslinux.zytor.com/archives/2010-September/015253.html
|
||||
* https://www.syslinux.org/archives/2010-September/015612.html
|
||||
* */
|
||||
!(state->block == 0 && rblock == 65535)) {
|
||||
/* This isn't the expected block. Log it and up the retry counter */
|
||||
infof(data, "Received ACK for block %d, expecting %d\n",
|
||||
infof(data, "Received ACK for block %d, expecting %d",
|
||||
rblock, state->block);
|
||||
state->retries++;
|
||||
/* Bail out if over the maximum */
|
||||
@@ -797,7 +797,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
|
||||
/* Increment the retry counter and log the timeout */
|
||||
state->retries++;
|
||||
infof(data, "Timeout waiting for block %d ACK. "
|
||||
" Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
|
||||
" Retries = %d", NEXT_BLOCKNUM(state->block), state->retries);
|
||||
/* Decide if we've had enough */
|
||||
if(state->retries > state->retry_max) {
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
@@ -906,22 +906,22 @@ static CURLcode tftp_state_machine(struct tftp_state_data *state,
|
||||
|
||||
switch(state->state) {
|
||||
case TFTP_STATE_START:
|
||||
DEBUGF(infof(data, "TFTP_STATE_START\n"));
|
||||
DEBUGF(infof(data, "TFTP_STATE_START"));
|
||||
result = tftp_send_first(state, event);
|
||||
break;
|
||||
case TFTP_STATE_RX:
|
||||
DEBUGF(infof(data, "TFTP_STATE_RX\n"));
|
||||
DEBUGF(infof(data, "TFTP_STATE_RX"));
|
||||
result = tftp_rx(state, event);
|
||||
break;
|
||||
case TFTP_STATE_TX:
|
||||
DEBUGF(infof(data, "TFTP_STATE_TX\n"));
|
||||
DEBUGF(infof(data, "TFTP_STATE_TX"));
|
||||
result = tftp_tx(state, event);
|
||||
break;
|
||||
case TFTP_STATE_FIN:
|
||||
infof(data, "%s\n", "TFTP finished");
|
||||
infof(data, "%s", "TFTP finished");
|
||||
break;
|
||||
default:
|
||||
DEBUGF(infof(data, "STATE: %d\n", state->state));
|
||||
DEBUGF(infof(data, "STATE: %d", state->state));
|
||||
failf(data, "%s", "Internal state machine error");
|
||||
result = CURLE_TFTP_ILLEGAL;
|
||||
break;
|
||||
@@ -1153,7 +1153,7 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data)
|
||||
size_t strn = state->rbytes - 4;
|
||||
state->error = (tftp_error_t)error;
|
||||
if(tftp_strnlen(str, strn) < strn)
|
||||
infof(data, "TFTP error: %s\n", str);
|
||||
infof(data, "TFTP error: %s", str);
|
||||
break;
|
||||
}
|
||||
case TFTP_EVENT_ACK:
|
||||
@@ -1288,7 +1288,7 @@ static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
result = tftp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
}
|
||||
else if(!result) {
|
||||
/* The multi code doesn't have this logic for the DOING state so we
|
||||
@@ -1325,7 +1325,7 @@ static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done)
|
||||
tftp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+37
-29
@@ -188,7 +188,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
|
||||
/* at this point we already verified that the callback exists
|
||||
so we compile and store the trailers buffer, then proceed */
|
||||
infof(data,
|
||||
"Moving trailers state machine from initialized to sending.\n");
|
||||
"Moving trailers state machine from initialized to sending.");
|
||||
data->state.trailers_state = TRAILERS_SENDING;
|
||||
Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS);
|
||||
|
||||
@@ -211,7 +211,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
|
||||
curl_slist_free_all(trailers);
|
||||
return result;
|
||||
}
|
||||
infof(data, "Successfully compiled trailers.\r\n");
|
||||
infof(data, "Successfully compiled trailers.");
|
||||
curl_slist_free_all(trailers);
|
||||
}
|
||||
#endif
|
||||
@@ -376,7 +376,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
|
||||
data->set.trailer_callback = NULL;
|
||||
/* mark the transfer as done */
|
||||
data->req.upload_done = TRUE;
|
||||
infof(data, "Signaling end of chunked upload after trailers.\n");
|
||||
infof(data, "Signaling end of chunked upload after trailers.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -385,7 +385,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
|
||||
/* mark this as done once this chunk is transferred */
|
||||
data->req.upload_done = TRUE;
|
||||
infof(data,
|
||||
"Signaling end of chunked upload via terminating chunk.\n");
|
||||
"Signaling end of chunked upload via terminating chunk.");
|
||||
}
|
||||
|
||||
if(added_crlf)
|
||||
@@ -463,7 +463,7 @@ CURLcode Curl_readrewind(struct Curl_easy *data)
|
||||
err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
|
||||
data->set.ioctl_client);
|
||||
Curl_set_in_callback(data, false);
|
||||
infof(data, "the ioctl callback returned %d\n", (int)err);
|
||||
infof(data, "the ioctl callback returned %d", (int)err);
|
||||
|
||||
if(err) {
|
||||
failf(data, "ioctl callback returned error %d", (int)err);
|
||||
@@ -530,7 +530,7 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
|
||||
default:
|
||||
if(timeofdoc <= data->set.timevalue) {
|
||||
infof(data,
|
||||
"The requested document is not new enough\n");
|
||||
"The requested document is not new enough");
|
||||
data->info.timecond = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -538,7 +538,7 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
|
||||
case CURL_TIMECOND_IFUNMODSINCE:
|
||||
if(timeofdoc >= data->set.timevalue) {
|
||||
infof(data,
|
||||
"The requested document is not old enough\n");
|
||||
"The requested document is not old enough");
|
||||
data->info.timecond = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -615,7 +615,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
else {
|
||||
/* read nothing but since we wanted nothing we consider this an OK
|
||||
situation to proceed from */
|
||||
DEBUGF(infof(data, "readwrite_data: we're done!\n"));
|
||||
DEBUGF(infof(data, "readwrite_data: we're done!"));
|
||||
nread = 0;
|
||||
}
|
||||
|
||||
@@ -638,10 +638,10 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
server closed the connection and we bail out from this! */
|
||||
#ifdef USE_NGHTTP2
|
||||
if(is_http2 && !nread)
|
||||
DEBUGF(infof(data, "nread == 0, stream closed, bailing\n"));
|
||||
DEBUGF(infof(data, "nread == 0, stream closed, bailing"));
|
||||
else
|
||||
#endif
|
||||
DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
|
||||
DEBUGF(infof(data, "nread <= 0, server closed connection, bailing"));
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
break;
|
||||
}
|
||||
@@ -684,7 +684,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
infof(data,
|
||||
"Excess found:"
|
||||
" excess = %zd"
|
||||
" url = %s (zero-length body)\n",
|
||||
" url = %s (zero-length body)",
|
||||
nread, data->state.up.path);
|
||||
}
|
||||
|
||||
@@ -764,7 +764,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
written to the client. */
|
||||
if(conn->chunk.datasize) {
|
||||
infof(data, "Leftovers after chunking: % "
|
||||
CURL_FORMAT_CURL_OFF_T "u bytes\n",
|
||||
CURL_FORMAT_CURL_OFF_T "u bytes",
|
||||
conn->chunk.datasize);
|
||||
}
|
||||
}
|
||||
@@ -775,7 +775,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
/* Account for body content stored in the header buffer */
|
||||
if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) {
|
||||
size_t headlen = Curl_dyn_len(&data->state.headerb);
|
||||
DEBUGF(infof(data, "Increasing bytecount by %zu\n", headlen));
|
||||
DEBUGF(infof(data, "Increasing bytecount by %zu", headlen));
|
||||
k->bytecount += headlen;
|
||||
}
|
||||
|
||||
@@ -789,7 +789,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
" excess = %zu"
|
||||
", size = %" CURL_FORMAT_CURL_OFF_T
|
||||
", maxdownload = %" CURL_FORMAT_CURL_OFF_T
|
||||
", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
|
||||
", bytecount = %" CURL_FORMAT_CURL_OFF_T,
|
||||
excess, k->size, k->maxdownload, k->bytecount);
|
||||
connclose(conn, "excess found in a read");
|
||||
}
|
||||
@@ -898,7 +898,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
/* When we've read the entire thing and the close bit is set, the server
|
||||
may now close the connection. If there's now any kind of sending going
|
||||
on from our side, we need to stop that immediately. */
|
||||
infof(data, "we are done reading and this is set to close, stop send\n");
|
||||
infof(data, "we are done reading and this is set to close, stop send");
|
||||
k->keepon &= ~KEEP_SEND; /* no writing anymore either */
|
||||
}
|
||||
|
||||
@@ -923,7 +923,7 @@ CURLcode Curl_done_sending(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && !defined(USE_LWIPSOCK)
|
||||
#if defined(WIN32) && defined(USE_WINSOCK)
|
||||
#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
|
||||
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
|
||||
#endif
|
||||
@@ -1128,7 +1128,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
(k->writebytecount == data->state.infilesize)) {
|
||||
/* we have sent all data we were supposed to */
|
||||
k->upload_done = TRUE;
|
||||
infof(data, "We are completely uploaded and fine\n");
|
||||
infof(data, "We are completely uploaded and fine");
|
||||
}
|
||||
|
||||
if(k->upload_present != bytes_written) {
|
||||
@@ -1199,7 +1199,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
|
||||
if(data->state.drain) {
|
||||
select_res |= CURL_CSELECT_IN;
|
||||
DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
|
||||
DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data"));
|
||||
}
|
||||
|
||||
if(!select_res) /* Call for select()/poll() only, if read/write/error
|
||||
@@ -1212,8 +1212,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
}
|
||||
|
||||
#ifdef USE_HYPER
|
||||
if(conn->datastream)
|
||||
return conn->datastream(data, conn, &didwhat, done, select_res);
|
||||
if(conn->datastream) {
|
||||
result = conn->datastream(data, conn, &didwhat, done, select_res);
|
||||
if(result || *done)
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
/* We go ahead and do a read if we have a readable socket or if
|
||||
the stream was rewound (in which case we have data in a
|
||||
@@ -1232,6 +1236,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#ifdef USE_HYPER
|
||||
}
|
||||
#endif
|
||||
|
||||
k->now = Curl_now();
|
||||
if(!didwhat) {
|
||||
@@ -1256,7 +1263,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||
infof(data, "Done waiting for 100-continue\n");
|
||||
infof(data, "Done waiting for 100-continue");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1632,7 +1639,8 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
DEBUGASSERT(data->state.uh);
|
||||
uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
|
||||
(type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
|
||||
((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) );
|
||||
((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) |
|
||||
CURLU_ALLOW_SPACE);
|
||||
if(uc) {
|
||||
if(type != FOLLOW_FAKE)
|
||||
return Curl_uc_to_curlcode(uc);
|
||||
@@ -1671,7 +1679,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
data->state.url = newurl;
|
||||
data->state.url_alloc = TRUE;
|
||||
|
||||
infof(data, "Issue another request to this URL: '%s'\n", data->state.url);
|
||||
infof(data, "Issue another request to this URL: '%s'", data->state.url);
|
||||
|
||||
/*
|
||||
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
||||
@@ -1714,7 +1722,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_301)) {
|
||||
infof(data, "Switch from POST to GET\n");
|
||||
infof(data, "Switch from POST to GET");
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
}
|
||||
break;
|
||||
@@ -1739,7 +1747,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_302)) {
|
||||
infof(data, "Switch from POST to GET\n");
|
||||
infof(data, "Switch from POST to GET");
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
}
|
||||
break;
|
||||
@@ -1757,7 +1765,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
!(data->set.keep_post & CURL_REDIR_POST_303))) {
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
data->set.upload = false;
|
||||
infof(data, "Switch to %s\n",
|
||||
infof(data, "Switch to %s",
|
||||
data->set.opt_no_body?"HEAD":"GET");
|
||||
}
|
||||
break;
|
||||
@@ -1818,7 +1826,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
|
||||
to issue again, but the nghttp2 API can deliver the message to other
|
||||
streams as well, which is why this adds the check the data counters
|
||||
too. */
|
||||
infof(data, "REFUSED_STREAM, retrying a fresh connect\n");
|
||||
infof(data, "REFUSED_STREAM, retrying a fresh connect");
|
||||
data->state.refused_stream = FALSE; /* clear again */
|
||||
retry = TRUE;
|
||||
}
|
||||
@@ -1830,8 +1838,8 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
|
||||
data->state.retrycount = 0;
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
infof(data, "Connection died, retrying a fresh connect\
|
||||
(retry count: %d)\n", data->state.retrycount);
|
||||
infof(data, "Connection died, retrying a fresh connect (retry count: %d)",
|
||||
data->state.retrycount);
|
||||
*url = strdup(data->state.url);
|
||||
if(!*url)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -62,6 +62,14 @@
|
||||
#ifdef USE_LIBIDN2
|
||||
#include <idn2.h>
|
||||
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
#define IDN2_LOOKUP(name, host, flags) \
|
||||
idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags)
|
||||
#else
|
||||
#define IDN2_LOOKUP(name, host, flags) \
|
||||
idn2_lookup_ul((const char *)name, (char **)host, flags)
|
||||
#endif
|
||||
|
||||
#elif defined(USE_WIN32_IDN)
|
||||
/* prototype for curl_win32_idn_to_ascii() */
|
||||
bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
@@ -92,7 +100,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
#include "speedcheck.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "inet_pton.h"
|
||||
#include "getinfo.h"
|
||||
#include "urlapi-int.h"
|
||||
#include "system_win32.h"
|
||||
@@ -726,7 +733,16 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(data);
|
||||
infof(data, "Closing connection %ld\n", conn->connection_id);
|
||||
infof(data, "Closing connection %ld", conn->connection_id);
|
||||
|
||||
#ifndef USE_HYPER
|
||||
if(conn->connect_state && conn->connect_state->prot_save) {
|
||||
/* If this was closed with a CONNECT in progress, cleanup this temporary
|
||||
struct arrangement */
|
||||
data->req.p.http = NULL;
|
||||
Curl_safefree(conn->connect_state->prot_save);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* possible left-overs from the async name resolvers */
|
||||
Curl_resolver_cancel(data);
|
||||
@@ -824,7 +840,7 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
|
||||
* are other users of it
|
||||
*/
|
||||
if(CONN_INUSE(conn) && !dead_connection) {
|
||||
DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn)));
|
||||
DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn)));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -957,7 +973,7 @@ static bool conn_maxage(struct Curl_easy *data,
|
||||
idletime /= 1000; /* integer seconds is fine */
|
||||
|
||||
if(idletime > data->set.maxage_conn) {
|
||||
infof(data, "Too old connection (%ld seconds), disconnect it\n",
|
||||
infof(data, "Too old connection (%ld seconds), disconnect it",
|
||||
idletime);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1006,7 +1022,7 @@ static bool extract_if_dead(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(dead) {
|
||||
infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
|
||||
infof(data, "Connection %ld seems to be dead!", conn->connection_id);
|
||||
Curl_conncache_remove_conn(data, conn, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1122,7 +1138,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
/* Max pipe length is zero (unlimited) for multiplexed connections */
|
||||
struct Curl_llist_element *curr;
|
||||
|
||||
infof(data, "Found bundle for host %s: %p [%s]\n",
|
||||
infof(data, "Found bundle for host %s: %p [%s]",
|
||||
hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
|
||||
"can multiplex" : "serially"));
|
||||
|
||||
@@ -1130,22 +1146,22 @@ ConnectionExists(struct Curl_easy *data,
|
||||
if(canmultiplex) {
|
||||
if(bundle->multiuse == BUNDLE_UNKNOWN) {
|
||||
if(data->set.pipewait) {
|
||||
infof(data, "Server doesn't support multiplex yet, wait\n");
|
||||
infof(data, "Server doesn't support multiplex yet, wait");
|
||||
*waitpipe = TRUE;
|
||||
CONNCACHE_UNLOCK(data);
|
||||
return FALSE; /* no re-use */
|
||||
}
|
||||
|
||||
infof(data, "Server doesn't support multiplex (yet)\n");
|
||||
infof(data, "Server doesn't support multiplex (yet)");
|
||||
canmultiplex = FALSE;
|
||||
}
|
||||
if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
|
||||
!Curl_multiplex_wanted(data->multi)) {
|
||||
infof(data, "Could multiplex, but not asked to!\n");
|
||||
infof(data, "Could multiplex, but not asked to!");
|
||||
canmultiplex = FALSE;
|
||||
}
|
||||
if(bundle->multiuse == BUNDLE_NO_MULTIUSE) {
|
||||
infof(data, "Can not multiplex, even if we wanted to!\n");
|
||||
infof(data, "Can not multiplex, even if we wanted to!");
|
||||
canmultiplex = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1193,7 +1209,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
completed yet and until then we don't re-use this connection */
|
||||
if(!check->primary_ip[0]) {
|
||||
infof(data,
|
||||
"Connection #%ld is still name resolving, can't reuse\n",
|
||||
"Connection #%ld is still name resolving, can't reuse",
|
||||
check->connection_id);
|
||||
continue;
|
||||
}
|
||||
@@ -1202,7 +1218,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
|
||||
foundPendingCandidate = TRUE;
|
||||
/* Don't pick a connection that hasn't connected yet */
|
||||
infof(data, "Connection #%ld isn't open enough, can't reuse\n",
|
||||
infof(data, "Connection #%ld isn't open enough, can't reuse",
|
||||
check->connection_id);
|
||||
continue;
|
||||
}
|
||||
@@ -1357,7 +1373,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
&check->ssl_config)) {
|
||||
DEBUGF(infof(data,
|
||||
"Connection #%ld has different SSL parameters, "
|
||||
"can't reuse\n",
|
||||
"can't reuse",
|
||||
check->connection_id));
|
||||
continue;
|
||||
}
|
||||
@@ -1365,7 +1381,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
foundPendingCandidate = TRUE;
|
||||
DEBUGF(infof(data,
|
||||
"Connection #%ld has not started SSL connect, "
|
||||
"can't reuse\n",
|
||||
"can't reuse",
|
||||
check->connection_id));
|
||||
continue;
|
||||
}
|
||||
@@ -1452,14 +1468,14 @@ ConnectionExists(struct Curl_easy *data,
|
||||
/* Multiplexed connections can only be HTTP/2 for now */
|
||||
struct http_conn *httpc = &check->proto.httpc;
|
||||
if(multiplexed >= httpc->settings.max_concurrent_streams) {
|
||||
infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
|
||||
infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)",
|
||||
multiplexed);
|
||||
continue;
|
||||
}
|
||||
else if(multiplexed >=
|
||||
Curl_multi_max_concurrent_streams(data->multi)) {
|
||||
infof(data, "client side MAX_CONCURRENT_STREAMS reached"
|
||||
", skip (%zu)\n",
|
||||
", skip (%zu)",
|
||||
multiplexed);
|
||||
continue;
|
||||
}
|
||||
@@ -1467,7 +1483,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
#endif
|
||||
/* When not multiplexed, we have a match here! */
|
||||
chosen = check;
|
||||
infof(data, "Multiplexed connection found!\n");
|
||||
infof(data, "Multiplexed connection found!");
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1490,7 +1506,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
|
||||
if(foundPendingCandidate && data->set.pipewait) {
|
||||
infof(data,
|
||||
"Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
|
||||
"Found pending candidate for reuse and CURLOPT_PIPEWAIT is set");
|
||||
*waitpipe = TRUE;
|
||||
}
|
||||
|
||||
@@ -1505,7 +1521,7 @@ void Curl_verboseconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(data->set.verbose)
|
||||
infof(data, "Connected to %s (%s) port %ld (#%ld)\n",
|
||||
infof(data, "Connected to %s (%s) port %u (#%ld)",
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
|
||||
@@ -1577,12 +1593,12 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
|
||||
#else
|
||||
int flags = IDN2_NFC_INPUT;
|
||||
#endif
|
||||
int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
|
||||
int rc = IDN2_LOOKUP(host->name, &ace_hostname, flags);
|
||||
if(rc != IDN2_OK)
|
||||
/* fallback to TR46 Transitional mode for better IDNA2003
|
||||
compatibility */
|
||||
rc = idn2_lookup_ul((const char *)host->name, &ace_hostname,
|
||||
IDN2_TRANSITIONAL);
|
||||
rc = IDN2_LOOKUP(host->name, &ace_hostname,
|
||||
IDN2_TRANSITIONAL);
|
||||
if(rc == IDN2_OK) {
|
||||
host->encalloc = (char *)ace_hostname;
|
||||
/* change the name pointer to point to the encoded hostname */
|
||||
@@ -1609,7 +1625,7 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
#else
|
||||
infof(data, "IDN support not present, can't parse Unicode domains\n");
|
||||
infof(data, "IDN support not present, can't parse Unicode domains");
|
||||
#endif
|
||||
}
|
||||
return CURLE_OK;
|
||||
@@ -1876,9 +1892,13 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data,
|
||||
#else
|
||||
scopeidx = if_nametoindex(zoneid);
|
||||
#endif
|
||||
if(!scopeidx)
|
||||
infof(data, "Invalid zoneid: %s; %s\n", zoneid,
|
||||
strerror(errno));
|
||||
if(!scopeidx) {
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Invalid zoneid: %s; %s", zoneid,
|
||||
Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
conn->scope_id = scopeidx;
|
||||
}
|
||||
@@ -1934,7 +1954,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
CURLU_DISALLOW_USER : 0) |
|
||||
(data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
|
||||
if(uc) {
|
||||
DEBUGF(infof(data, "curl_url_set rejected %s\n", data->state.url));
|
||||
DEBUGF(infof(data, "curl_url_set rejected %s", data->state.url));
|
||||
return Curl_uc_to_curlcode(uc);
|
||||
}
|
||||
|
||||
@@ -1979,7 +1999,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
}
|
||||
data->state.url = url;
|
||||
data->state.url_alloc = TRUE;
|
||||
infof(data, "Switched from HTTP to HTTPS due to HSTS => %s\n",
|
||||
infof(data, "Switched from HTTP to HTTPS due to HSTS => %s",
|
||||
data->state.url);
|
||||
}
|
||||
}
|
||||
@@ -2333,7 +2353,7 @@ static char *detect_proxy(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
if(proxy)
|
||||
infof(data, "Uses proxy env variable %s == '%s'\n", envp, proxy);
|
||||
infof(data, "Uses proxy env variable %s == '%s'", envp, proxy);
|
||||
|
||||
return proxy;
|
||||
}
|
||||
@@ -2448,7 +2468,7 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
||||
conn->bits.proxy_user_passwd = TRUE; /* enable it */
|
||||
}
|
||||
|
||||
curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
|
||||
(void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
|
||||
|
||||
if(portptr) {
|
||||
port = (int)strtol(portptr, NULL, 10);
|
||||
@@ -2576,7 +2596,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
|
||||
no_proxy = curl_getenv(p);
|
||||
}
|
||||
if(no_proxy) {
|
||||
infof(data, "Uses proxy env variable %s == '%s'\n", p, no_proxy);
|
||||
infof(data, "Uses proxy env variable %s == '%s'", p, no_proxy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2871,11 +2891,13 @@ static CURLcode override_login(struct Curl_easy *data,
|
||||
char **passwdp = &conn->passwd;
|
||||
char **optionsp = &conn->options;
|
||||
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) {
|
||||
Curl_safefree(*userp);
|
||||
Curl_safefree(*passwdp);
|
||||
conn->bits.user_passwd = FALSE; /* disable user+password */
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.str[STRING_OPTIONS]) {
|
||||
free(*optionsp);
|
||||
@@ -2884,6 +2906,7 @@ static CURLcode override_login(struct Curl_easy *data,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
conn->bits.netrc = FALSE;
|
||||
if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
|
||||
bool netrc_user_changed = FALSE;
|
||||
@@ -2895,7 +2918,7 @@ static CURLcode override_login(struct Curl_easy *data,
|
||||
&netrc_user_changed, &netrc_passwd_changed,
|
||||
data->set.str[STRING_NETRC_FILE]);
|
||||
if(ret > 0) {
|
||||
infof(data, "Couldn't find host %s in the %s file; using defaults\n",
|
||||
infof(data, "Couldn't find host %s in the %s file; using defaults",
|
||||
conn->host.name, data->set.str[STRING_NETRC_FILE]);
|
||||
}
|
||||
else if(ret < 0) {
|
||||
@@ -2909,6 +2932,7 @@ static CURLcode override_login(struct Curl_easy *data,
|
||||
conn->bits.user_passwd = TRUE; /* enable user+password */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for updated strings, we update them in the URL */
|
||||
if(*userp) {
|
||||
@@ -2996,6 +3020,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
char *host_portno;
|
||||
char *portptr;
|
||||
int port = -1;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) data;
|
||||
@@ -3025,7 +3050,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
if(*ptr == '%') {
|
||||
/* There might be a zone identifier */
|
||||
if(strncmp("%25", ptr, 3))
|
||||
infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
|
||||
infof(data, "Please URL encode %% as %%25, see RFC 6874.");
|
||||
ptr++;
|
||||
/* Allow unreserved characters as defined in RFC 3986 */
|
||||
while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
|
||||
@@ -3036,7 +3061,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
/* yeps, it ended nicely with a bracket as well */
|
||||
*ptr++ = '\0';
|
||||
else
|
||||
infof(data, "Invalid IPv6 address format\n");
|
||||
infof(data, "Invalid IPv6 address format");
|
||||
portptr = ptr;
|
||||
/* Note that if this didn't end with a bracket, we still advanced the
|
||||
* hostptr first, but I can't see anything wrong with that as no host
|
||||
@@ -3044,8 +3069,8 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
*/
|
||||
#else
|
||||
failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in!");
|
||||
free(host_dup);
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
result = CURLE_NOT_BUILT_IN;
|
||||
goto error;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3058,10 +3083,10 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
if(*host_portno) {
|
||||
long portparse = strtol(host_portno, &endp, 10);
|
||||
if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
|
||||
infof(data, "No valid port number in connect to host string (%s)\n",
|
||||
failf(data, "No valid port number in connect to host string (%s)",
|
||||
host_portno);
|
||||
hostptr = NULL;
|
||||
port = -1;
|
||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
port = (int)portparse; /* we know it will fit */
|
||||
@@ -3072,15 +3097,16 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
||||
if(hostptr) {
|
||||
*hostname_result = strdup(hostptr);
|
||||
if(!*hostname_result) {
|
||||
free(host_dup);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*port_result = port;
|
||||
|
||||
error:
|
||||
free(host_dup);
|
||||
return CURLE_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3176,7 +3202,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
|
||||
conn->conn_to_host.name = host;
|
||||
conn->bits.conn_to_host = TRUE;
|
||||
|
||||
infof(data, "Connecting to hostname: %s\n", host);
|
||||
infof(data, "Connecting to hostname: %s", host);
|
||||
}
|
||||
else {
|
||||
/* no "connect to host" */
|
||||
@@ -3187,7 +3213,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
|
||||
if(port >= 0) {
|
||||
conn->conn_to_port = port;
|
||||
conn->bits.conn_to_port = TRUE;
|
||||
infof(data, "Connecting to port: %d\n", port);
|
||||
infof(data, "Connecting to port: %d", port);
|
||||
}
|
||||
else {
|
||||
/* no "connect to port" */
|
||||
@@ -3248,7 +3274,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
|
||||
conn->conn_to_port = as->dst.port;
|
||||
conn->bits.conn_to_port = TRUE;
|
||||
conn->bits.altused = TRUE;
|
||||
infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n",
|
||||
infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d",
|
||||
Curl_alpnid2str(srcalpnid), host, conn->remote_port,
|
||||
Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port);
|
||||
if(srcalpnid != as->dst.alpnid) {
|
||||
@@ -3356,9 +3382,12 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
|
||||
else if(rc == CURLRESOLV_TIMEDOUT)
|
||||
else if(rc == CURLRESOLV_TIMEDOUT) {
|
||||
failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
|
||||
connhost->dispname,
|
||||
Curl_timediff(Curl_now(), data->progress.t_startsingle));
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
|
||||
}
|
||||
else if(!hostaddr) {
|
||||
failf(data, "Could not resolve host: %s", connhost->dispname);
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
@@ -3600,7 +3629,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
/* Check for overridden login details and set them accordingly so they
|
||||
/* Check for overridden login details and set them accordingly so that
|
||||
they are known when protocol->setup_connection is called! */
|
||||
result = override_login(data, conn);
|
||||
if(result)
|
||||
@@ -3736,6 +3765,8 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
*/
|
||||
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
|
||||
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
|
||||
data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
|
||||
data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
|
||||
data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
|
||||
data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
|
||||
data->set.ssl.primary.cipher_list =
|
||||
@@ -3763,8 +3794,11 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
|
||||
data->set.proxy_ssl.primary.ca_info_blob =
|
||||
data->set.blobs[BLOB_CAINFO_PROXY];
|
||||
data->set.proxy_ssl.primary.issuercert =
|
||||
data->set.str[STRING_SSL_ISSUERCERT_PROXY];
|
||||
data->set.proxy_ssl.primary.issuercert_blob =
|
||||
data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
|
||||
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
|
||||
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
|
||||
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
|
||||
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
|
||||
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
|
||||
@@ -3773,7 +3807,6 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
|
||||
#endif
|
||||
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
|
||||
data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
|
||||
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
|
||||
data->set.ssl.key = data->set.str[STRING_KEY];
|
||||
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
|
||||
@@ -3787,9 +3820,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY];
|
||||
data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
|
||||
|
||||
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
|
||||
&conn->ssl_config)) {
|
||||
@@ -3841,14 +3872,14 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
*in_connect = conn;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
|
||||
infof(data, "Re-using existing connection! (#%ld) with %s %s",
|
||||
conn->connection_id,
|
||||
conn->bits.proxy?"proxy":"host",
|
||||
conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
|
||||
conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
|
||||
conn->host.dispname);
|
||||
#else
|
||||
infof(data, "Re-using existing connection! (#%ld) with host %s\n",
|
||||
infof(data, "Re-using existing connection! (#%ld) with host %s",
|
||||
conn->connection_id, conn->host.dispname);
|
||||
#endif
|
||||
}
|
||||
@@ -3888,7 +3919,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
if(conn_candidate)
|
||||
(void)Curl_disconnect(data, conn_candidate, FALSE);
|
||||
else {
|
||||
infof(data, "No more connections allowed to host %s: %zu\n",
|
||||
infof(data, "No more connections allowed to host %s: %zu",
|
||||
bundlehost, max_host_connections);
|
||||
connections_available = FALSE;
|
||||
}
|
||||
@@ -3908,13 +3939,13 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
if(conn_candidate)
|
||||
(void)Curl_disconnect(data, conn_candidate, FALSE);
|
||||
else {
|
||||
infof(data, "No connections available in cache\n");
|
||||
infof(data, "No connections available in cache");
|
||||
connections_available = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!connections_available) {
|
||||
infof(data, "No connections available.\n");
|
||||
infof(data, "No connections available.");
|
||||
|
||||
conn_free(conn);
|
||||
*in_connect = NULL;
|
||||
@@ -3939,14 +3970,14 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
connection based. */
|
||||
if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
|
||||
data->state.authhost.done) {
|
||||
infof(data, "NTLM picked AND auth done set, clear picked!\n");
|
||||
infof(data, "NTLM picked AND auth done set, clear picked!");
|
||||
data->state.authhost.picked = CURLAUTH_NONE;
|
||||
data->state.authhost.done = FALSE;
|
||||
}
|
||||
|
||||
if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
|
||||
data->state.authproxy.done) {
|
||||
infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
|
||||
infof(data, "NTLM-proxy picked AND auth done set, clear picked!");
|
||||
data->state.authproxy.picked = CURLAUTH_NONE;
|
||||
data->state.authproxy.done = FALSE;
|
||||
}
|
||||
|
||||
+13
-14
@@ -131,7 +131,7 @@ static const char *find_host_sep(const char *url)
|
||||
*/
|
||||
static bool urlchar_needs_escaping(int c)
|
||||
{
|
||||
return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c));
|
||||
return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,7 +580,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
|
||||
}
|
||||
|
||||
/* scan for byte values < 31 or 127 */
|
||||
static CURLUcode junkscan(const char *part)
|
||||
static bool junkscan(const char *part, unsigned int flags)
|
||||
{
|
||||
if(part) {
|
||||
static const char badbytes[]={
|
||||
@@ -588,17 +588,18 @@ static CURLUcode junkscan(const char *part)
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x7f,
|
||||
0x00 /* null-terminate */
|
||||
0x7f, 0x00 /* null-terminate */
|
||||
};
|
||||
size_t n = strlen(part);
|
||||
size_t nfine = strcspn(part, badbytes);
|
||||
if(nfine != n)
|
||||
/* since we don't know which part is scanned, return a generic error
|
||||
code */
|
||||
return CURLUE_MALFORMED_INPUT;
|
||||
return TRUE;
|
||||
if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' '))
|
||||
return TRUE;
|
||||
}
|
||||
return CURLUE_OK;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
|
||||
@@ -769,8 +770,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
|
||||
size_t schemelen = 0;
|
||||
size_t urllen;
|
||||
|
||||
if(!url)
|
||||
return CURLUE_MALFORMED_INPUT;
|
||||
DEBUGASSERT(url);
|
||||
|
||||
/*************************************************************
|
||||
* Parse the URL.
|
||||
@@ -884,9 +884,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
|
||||
!(flags & CURLU_NON_SUPPORT_SCHEME))
|
||||
return CURLUE_UNSUPPORTED_SCHEME;
|
||||
|
||||
if(junkscan(schemep))
|
||||
if(junkscan(schemep, flags))
|
||||
return CURLUE_MALFORMED_INPUT;
|
||||
|
||||
}
|
||||
else {
|
||||
/* no scheme! */
|
||||
@@ -927,7 +926,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
|
||||
}
|
||||
}
|
||||
|
||||
if(junkscan(path))
|
||||
if(junkscan(path, flags))
|
||||
return CURLUE_MALFORMED_INPUT;
|
||||
|
||||
if((flags & CURLU_URLENCODE) && path[0]) {
|
||||
@@ -991,7 +990,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
|
||||
/*
|
||||
* Parse the login details and strip them out of the host name.
|
||||
*/
|
||||
if(junkscan(hostname))
|
||||
if(junkscan(hostname, flags))
|
||||
return CURLUE_MALFORMED_INPUT;
|
||||
|
||||
result = parse_hostname_login(u, &hostname, flags);
|
||||
@@ -1155,7 +1154,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
|
||||
const struct Curl_handler *h =
|
||||
Curl_builtin_scheme(u->scheme);
|
||||
if(h) {
|
||||
msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
|
||||
msnprintf(portbuf, sizeof(portbuf), "%u", h->defport);
|
||||
ptr = portbuf;
|
||||
}
|
||||
}
|
||||
@@ -1214,7 +1213,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
|
||||
/* there's no stored port number, but asked to deliver
|
||||
a default one for the scheme */
|
||||
if(h) {
|
||||
msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
|
||||
msnprintf(portbuf, sizeof(portbuf), "%u", h->defport);
|
||||
port = portbuf;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-10
@@ -246,6 +246,7 @@ struct ssl_primary_config {
|
||||
long version_max; /* max supported version the client wants to use*/
|
||||
char *CApath; /* certificate dir (doesn't work on windows) */
|
||||
char *CAfile; /* certificate to verify peer against */
|
||||
char *issuercert; /* optional issuer certificate filename */
|
||||
char *clientcert;
|
||||
char *random_file; /* path to file containing "random" data */
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
@@ -254,6 +255,7 @@ struct ssl_primary_config {
|
||||
char *pinned_key;
|
||||
struct curl_blob *cert_blob;
|
||||
struct curl_blob *ca_info_blob;
|
||||
struct curl_blob *issuercert_blob;
|
||||
char *curves; /* list of curves to use */
|
||||
BIT(verifypeer); /* set TRUE if this is desired */
|
||||
BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */
|
||||
@@ -265,8 +267,6 @@ struct ssl_config_data {
|
||||
struct ssl_primary_config primary;
|
||||
long certverifyresult; /* result from the certificate verification */
|
||||
char *CRLfile; /* CRL to check certificate revocation */
|
||||
char *issuercert;/* optional issuer certificate filename */
|
||||
struct curl_blob *issuercert_blob;
|
||||
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
|
||||
void *fsslctxp; /* parameter for call back */
|
||||
char *cert_type; /* format for certificate (default: PEM)*/
|
||||
@@ -508,7 +508,9 @@ struct ConnectBits {
|
||||
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
|
||||
BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
BIT(netrc); /* name+password provided by netrc */
|
||||
#endif
|
||||
BIT(bound); /* set true if bind() has already been done on this socket/
|
||||
connection */
|
||||
BIT(multiplex); /* connection is multiplexed */
|
||||
@@ -702,14 +704,15 @@ struct SingleRequest {
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
struct dohdata *doh; /* DoH specific data for this request */
|
||||
#endif
|
||||
BIT(header); /* incoming data has HTTP header */
|
||||
BIT(header); /* incoming data has HTTP header */
|
||||
BIT(content_range); /* set TRUE if Content-Range: was found */
|
||||
BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
|
||||
upload and we're uploading the last chunk */
|
||||
BIT(ignorebody); /* we read a response-body but we ignore it! */
|
||||
BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
|
||||
upload and we're uploading the last chunk */
|
||||
BIT(ignorebody); /* we read a response-body but we ignore it! */
|
||||
BIT(http_bodyless); /* HTTP response status code is between 100 and 199,
|
||||
204 or 304 */
|
||||
BIT(chunk); /* if set, this is a chunked transfer-encoding */
|
||||
BIT(chunk); /* if set, this is a chunked transfer-encoding */
|
||||
BIT(ignore_cl); /* ignore content-length */
|
||||
BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding
|
||||
on upload */
|
||||
BIT(getheader); /* TRUE if header parsing is wanted */
|
||||
@@ -1411,6 +1414,7 @@ struct UrlState {
|
||||
trailers_state trailers_state; /* whether we are sending trailers
|
||||
and what stage are we at */
|
||||
#ifdef USE_HYPER
|
||||
bool hconnect; /* set if a CONNECT request */
|
||||
CURLcode hresult; /* used to pass return codes back from hyper callbacks */
|
||||
#endif
|
||||
|
||||
@@ -1726,8 +1730,10 @@ struct UserDefined {
|
||||
*/
|
||||
curl_sshkeycallback ssh_keyfunc; /* key matching callback */
|
||||
void *ssh_keyfunc_userp; /* custom pointer to callback */
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
enum CURL_NETRC_OPTION
|
||||
use_netrc; /* defined in include/curl.h */
|
||||
#endif
|
||||
curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
|
||||
IMAP or POP3 or others! */
|
||||
long new_file_perms; /* Permissions to use when creating remote files */
|
||||
@@ -1847,9 +1853,9 @@ struct UserDefined {
|
||||
BIT(disallow_username_in_url); /* disallow username in url */
|
||||
BIT(doh); /* DNS-over-HTTPS enabled */
|
||||
BIT(doh_get); /* use GET for DoH requests, instead of POST */
|
||||
BIT(doh_verifypeer); /* DOH certificate peer verification */
|
||||
BIT(doh_verifyhost); /* DOH certificate hostname verification */
|
||||
BIT(doh_verifystatus); /* DOH certificate status verification */
|
||||
BIT(doh_verifypeer); /* DoH certificate peer verification */
|
||||
BIT(doh_verifyhost); /* DoH certificate hostname verification */
|
||||
BIT(doh_verifystatus); /* DoH certificate status verification */
|
||||
BIT(http09_allowed); /* allow HTTP/0.9 responses */
|
||||
BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
|
||||
recipients */
|
||||
|
||||
@@ -112,7 +112,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!Curl_bufref_len(chlg)) {
|
||||
infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n");
|
||||
infof(data, "DIGEST-MD5 handshake failure (empty challenge message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
|
||||
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
char buffer[STRERROR_LEN];
|
||||
#endif
|
||||
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
@@ -207,7 +209,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
if(status == SEC_E_INSUFFICIENT_MEMORY)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
infof(data, "schannel: InitializeSecurityContext failed: %s\n",
|
||||
infof(data, "schannel: InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(status, buffer, sizeof(buffer)));
|
||||
|
||||
return CURLE_AUTH_ERROR;
|
||||
@@ -461,7 +463,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
if(status == SEC_E_OK)
|
||||
output_token_len = chlg_buf[4].cbBuffer;
|
||||
else { /* delete the context so a new one can be made */
|
||||
infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx\n",
|
||||
infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx",
|
||||
(long)status);
|
||||
s_pSecFn->DeleteSecurityContext(digest->http_context);
|
||||
Curl_safefree(digest->http_context);
|
||||
@@ -585,7 +587,9 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
|
||||
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
char buffer[STRERROR_LEN];
|
||||
#endif
|
||||
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
@@ -597,7 +601,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
if(status == SEC_E_INSUFFICIENT_MEMORY)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
infof(data, "schannel: InitializeSecurityContext failed: %s\n",
|
||||
infof(data, "schannel: InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(status, buffer, sizeof(buffer)));
|
||||
|
||||
return CURLE_AUTH_ERROR;
|
||||
|
||||
+30
-52
@@ -123,7 +123,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
|
||||
if(chlg) {
|
||||
if(!Curl_bufref_len(chlg)) {
|
||||
infof(data, "GSSAPI handshake failure (empty challenge message)\n");
|
||||
infof(data, "GSSAPI handshake failure (empty challenge message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
input_token.value = (void *) Curl_bufref_ptr(chlg);
|
||||
@@ -170,6 +170,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* authzid [in] - The authorization identity if some.
|
||||
* chlg [in] - Optional challenge message.
|
||||
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
|
||||
* out [out] - The result storage.
|
||||
@@ -177,6 +178,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
const char *authzid,
|
||||
const struct bufref *chlg,
|
||||
struct kerberos5data *krb5,
|
||||
struct bufref *out)
|
||||
@@ -189,39 +191,17 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
OM_uint32 unused_status;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
unsigned int indata = 0;
|
||||
unsigned int outdata = 0;
|
||||
unsigned char *indata;
|
||||
gss_qop_t qop = GSS_C_QOP_DEFAULT;
|
||||
unsigned int sec_layer = 0;
|
||||
unsigned int max_size = 0;
|
||||
gss_name_t username = GSS_C_NO_NAME;
|
||||
gss_buffer_desc username_token;
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!Curl_bufref_len(chlg)) {
|
||||
infof(data, "GSSAPI handshake failure (empty security message)\n");
|
||||
infof(data, "GSSAPI handshake failure (empty security message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Get the fully qualified username back from the context */
|
||||
major_status = gss_inquire_context(&minor_status, krb5->context,
|
||||
&username, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_log_error(data, "gss_inquire_context() failed: ",
|
||||
major_status, minor_status);
|
||||
return CURLE_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* Convert the username from internal format to a displayable token */
|
||||
major_status = gss_display_name(&minor_status, username,
|
||||
&username_token, NULL);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_log_error(data, "gss_display_name() failed: ",
|
||||
major_status, minor_status);
|
||||
return CURLE_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* Setup the challenge "input" security buffer */
|
||||
input_token.value = (void *) Curl_bufref_ptr(chlg);
|
||||
input_token.length = Curl_bufref_len(chlg);
|
||||
@@ -232,32 +212,32 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_log_error(data, "gss_unwrap() failed: ",
|
||||
major_status, minor_status);
|
||||
gss_release_buffer(&unused_status, &username_token);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
|
||||
if(output_token.length != 4) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security data)\n");
|
||||
gss_release_buffer(&unused_status, &username_token);
|
||||
infof(data, "GSSAPI handshake failure (invalid security data)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Copy the data out and free the challenge as it is not required anymore */
|
||||
memcpy(&indata, output_token.value, 4);
|
||||
/* Extract the security layer and the maximum message size */
|
||||
indata = output_token.value;
|
||||
sec_layer = indata[0];
|
||||
max_size = (indata[1] << 16) | (indata[2] << 8) | indata[3];
|
||||
|
||||
/* Free the challenge as it is not required anymore */
|
||||
gss_release_buffer(&unused_status, &output_token);
|
||||
|
||||
/* Extract the security layer */
|
||||
sec_layer = indata & 0x000000FF;
|
||||
/* Process the security layer */
|
||||
if(!(sec_layer & GSSAUTH_P_NONE)) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
|
||||
infof(data, "GSSAPI handshake failure (invalid security layer)");
|
||||
|
||||
gss_release_buffer(&unused_status, &username_token);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
sec_layer &= GSSAUTH_P_NONE; /* We do not support a security layer */
|
||||
|
||||
/* Extract the maximum message size the server can receive */
|
||||
max_size = ntohl(indata & 0xFFFFFF00);
|
||||
/* Process the maximum message size the server can receive */
|
||||
if(max_size > 0) {
|
||||
/* The server has told us it supports a maximum receive buffer, however, as
|
||||
we don't require one unless we are encrypting data, we tell the server
|
||||
@@ -266,26 +246,24 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/* Allocate our message */
|
||||
messagelen = sizeof(outdata) + username_token.length + 1;
|
||||
messagelen = 4;
|
||||
if(authzid)
|
||||
messagelen += strlen(authzid);
|
||||
message = malloc(messagelen);
|
||||
if(!message) {
|
||||
gss_release_buffer(&unused_status, &username_token);
|
||||
if(!message)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the message with the security layer, client supported receive
|
||||
message size and authorization identity including the 0x00 based
|
||||
terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization
|
||||
identity is not terminated with the zero-valued (%x00) octet." it seems
|
||||
necessary to include it. */
|
||||
outdata = htonl(max_size) | sec_layer;
|
||||
memcpy(message, &outdata, sizeof(outdata));
|
||||
memcpy(message + sizeof(outdata), username_token.value,
|
||||
username_token.length);
|
||||
message[messagelen - 1] = '\0';
|
||||
/* Populate the message with the security layer and client supported receive
|
||||
message size. */
|
||||
message[0] = sec_layer & 0xFF;
|
||||
message[1] = (max_size >> 16) & 0xFF;
|
||||
message[2] = (max_size >> 8) & 0xFF;
|
||||
message[3] = max_size & 0xFF;
|
||||
|
||||
/* Free the username token as it is not required anymore */
|
||||
gss_release_buffer(&unused_status, &username_token);
|
||||
/* If given, append the authorization identity. */
|
||||
|
||||
if(authzid && *authzid)
|
||||
memcpy(message + 4, authzid, messagelen - 4);
|
||||
|
||||
/* Setup the "authentication data" security buffer */
|
||||
input_token.value = message;
|
||||
|
||||
+36
-46
@@ -173,7 +173,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
|
||||
if(chlg) {
|
||||
if(!Curl_bufref_len(chlg)) {
|
||||
infof(data, "GSSAPI handshake failure (empty challenge message)\n");
|
||||
infof(data, "GSSAPI handshake failure (empty challenge message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -238,13 +238,15 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* chlg [in] - The optional challenge message.
|
||||
* authzid [in] - The authorization identity if some.
|
||||
* chlg [in] - The optional challenge message.
|
||||
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
|
||||
* out [out] - The result storage.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
const char *authzid,
|
||||
const struct bufref *chlg,
|
||||
struct kerberos5data *krb5,
|
||||
struct bufref *out)
|
||||
@@ -260,19 +262,20 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
SecBuffer wrap_buf[3];
|
||||
SecBufferDesc input_desc;
|
||||
SecBufferDesc wrap_desc;
|
||||
unsigned long indata = 0;
|
||||
unsigned long outdata = 0;
|
||||
unsigned char *indata;
|
||||
unsigned long qop = 0;
|
||||
unsigned long sec_layer = 0;
|
||||
unsigned long max_size = 0;
|
||||
SecPkgContext_Sizes sizes;
|
||||
SecPkgCredentials_Names names;
|
||||
SECURITY_STATUS status;
|
||||
char *user_name;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) data;
|
||||
#endif
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!Curl_bufref_len(chlg)) {
|
||||
infof(data, "GSSAPI handshake failure (empty security message)\n");
|
||||
infof(data, "GSSAPI handshake failure (empty security message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -287,17 +290,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_AUTH_ERROR;
|
||||
|
||||
/* Get the fully qualified username back from the context */
|
||||
status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
|
||||
SECPKG_CRED_ATTR_NAMES,
|
||||
&names);
|
||||
|
||||
if(status == SEC_E_INSUFFICIENT_MEMORY)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_AUTH_ERROR;
|
||||
|
||||
/* Setup the "input" security buffer */
|
||||
input_desc.ulVersion = SECBUFFER_VERSION;
|
||||
input_desc.cBuffers = 2;
|
||||
@@ -312,29 +304,32 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
/* Decrypt the inbound challenge and obtain the qop */
|
||||
status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
|
||||
if(status != SEC_E_OK) {
|
||||
infof(data, "GSSAPI handshake failure (empty security message)\n");
|
||||
infof(data, "GSSAPI handshake failure (empty security message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
|
||||
if(input_buf[1].cbBuffer != 4) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security data)\n");
|
||||
infof(data, "GSSAPI handshake failure (invalid security data)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Copy the data out and free the challenge as it is not required anymore */
|
||||
memcpy(&indata, input_buf[1].pvBuffer, 4);
|
||||
/* Extract the security layer and the maximum message size */
|
||||
indata = input_buf[1].pvBuffer;
|
||||
sec_layer = indata[0];
|
||||
max_size = (indata[1] << 16) | (indata[2] << 8) | indata[3];
|
||||
|
||||
/* Free the challenge as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
|
||||
|
||||
/* Extract the security layer */
|
||||
sec_layer = indata & 0x000000FF;
|
||||
/* Process the security layer */
|
||||
if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
|
||||
infof(data, "GSSAPI handshake failure (invalid security layer)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
sec_layer &= KERB_WRAP_NO_ENCRYPT; /* We do not support a security layer */
|
||||
|
||||
/* Extract the maximum message size the server can receive */
|
||||
max_size = ntohl(indata & 0xFFFFFF00);
|
||||
/* Process the maximum message size the server can receive */
|
||||
if(max_size > 0) {
|
||||
/* The server has told us it supports a maximum receive buffer, however, as
|
||||
we don't require one unless we are encrypting data, we tell the server
|
||||
@@ -347,33 +342,28 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
if(!trailer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Convert the user name to UTF8 when operating with Unicode */
|
||||
user_name = curlx_convert_tchar_to_UTF8(names.sUserName);
|
||||
if(!user_name) {
|
||||
free(trailer);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Allocate our message */
|
||||
messagelen = sizeof(outdata) + strlen(user_name) + 1;
|
||||
messagelen = 4;
|
||||
if(authzid)
|
||||
messagelen += strlen(authzid);
|
||||
message = malloc(messagelen);
|
||||
if(!message) {
|
||||
free(trailer);
|
||||
curlx_unicodefree(user_name);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the message with the security layer, client supported receive
|
||||
message size and authorization identity including the 0x00 based
|
||||
terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization
|
||||
identity is not terminated with the zero-valued (%x00) octet." it seems
|
||||
necessary to include it. */
|
||||
outdata = htonl(max_size) | sec_layer;
|
||||
memcpy(message, &outdata, sizeof(outdata));
|
||||
strcpy((char *) message + sizeof(outdata), user_name);
|
||||
curlx_unicodefree(user_name);
|
||||
/* Populate the message with the security layer and client supported receive
|
||||
message size. */
|
||||
message[0] = sec_layer & 0xFF;
|
||||
message[1] = (max_size >> 16) & 0xFF;
|
||||
message[2] = (max_size >> 8) & 0xFF;
|
||||
message[3] = max_size & 0xFF;
|
||||
|
||||
/* If given, append the authorization identity. */
|
||||
|
||||
if(authzid && *authzid)
|
||||
memcpy(message + 4, authzid, messagelen - 4);
|
||||
|
||||
/* Allocate the padding */
|
||||
padding = malloc(sizes.cbBlockSize);
|
||||
|
||||
+4
-4
@@ -182,7 +182,7 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
|
||||
(target_info_offset + target_info_len) > type2len ||
|
||||
target_info_offset < 48) {
|
||||
infof(data, "NTLM handshake failure (bad type-2 message). "
|
||||
"Target Info Offset Len is set incorrect by the peer\n");
|
||||
"Target Info Offset Len is set incorrect by the peer");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
||||
(memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
|
||||
(memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
|
||||
/* This was not a good enough type-2 message */
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)\n");
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
|
||||
result = ntlm_decode_type2_target(data, type2ref, ntlm);
|
||||
if(result) {
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)\n");
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -533,7 +533,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
/* Get the machine's un-qualified host name as NTLM doesn't like the fully
|
||||
qualified domain name */
|
||||
if(Curl_gethostname(host, sizeof(host))) {
|
||||
infof(data, "gethostname() failed, continuing without!\n");
|
||||
infof(data, "gethostname() failed, continuing without!");
|
||||
hostlen = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -206,7 +206,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
||||
|
||||
/* Ensure we have a valid type-2 message */
|
||||
if(!Curl_bufref_len(type2)) {
|
||||
infof(data, "NTLM handshake failure (empty type-2 message)\n");
|
||||
infof(data, "NTLM handshake failure (empty type-2 message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -253,6 +253,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
unsigned long attrs;
|
||||
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) data;
|
||||
#endif
|
||||
(void) passwdp;
|
||||
(void) userp;
|
||||
|
||||
@@ -309,7 +312,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
&type_3_desc,
|
||||
&attrs, &expiry);
|
||||
if(status != SEC_E_OK) {
|
||||
infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
|
||||
infof(data, "NTLM handshake failure (type-3 message): Status=%x",
|
||||
status);
|
||||
|
||||
if(status == SEC_E_INSUFFICIENT_MEMORY)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -137,8 +137,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg) {
|
||||
infof(data, "SPNEGO handshake failure (empty challenge message)\n");
|
||||
|
||||
infof(data, "SPNEGO handshake failure (empty challenge message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* 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
|
||||
@@ -191,8 +191,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg) {
|
||||
infof(data, "SPNEGO handshake failure (empty challenge message)\n");
|
||||
|
||||
infof(data, "SPNEGO handshake failure (empty challenge message)");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
|
||||
token message */
|
||||
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
|
||||
const char *authzid,
|
||||
const struct bufref *chlg,
|
||||
struct kerberos5data *krb5,
|
||||
struct bufref *out);
|
||||
|
||||
+6
-8
@@ -75,28 +75,26 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROTLI
|
||||
static size_t brotli_version(char *buf, size_t bufsz)
|
||||
static void brotli_version(char *buf, size_t bufsz)
|
||||
{
|
||||
uint32_t brotli_version = BrotliDecoderVersion();
|
||||
unsigned int major = brotli_version >> 24;
|
||||
unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12;
|
||||
unsigned int patch = brotli_version & 0x00000FFF;
|
||||
|
||||
return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
|
||||
(void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
static size_t zstd_version(char *buf, size_t bufsz)
|
||||
static void zstd_version(char *buf, size_t bufsz)
|
||||
{
|
||||
unsigned long zstd_version = (unsigned long)ZSTD_versionNumber();
|
||||
unsigned int major = (unsigned int)(zstd_version / (100 * 100));
|
||||
unsigned int minor = (unsigned int)((zstd_version -
|
||||
(major * 100 * 100)) / 100);
|
||||
(major * 100 * 100)) / 100);
|
||||
unsigned int patch = (unsigned int)(zstd_version -
|
||||
(major * 100 * 100) - (minor * 100));
|
||||
|
||||
return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
|
||||
(major * 100 * 100) - (minor * 100));
|
||||
(void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+79
-126
@@ -28,6 +28,9 @@
|
||||
#include <nghttp3/nghttp3.h>
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/err.h>
|
||||
#include <ngtcp2/ngtcp2_crypto_openssl.h>
|
||||
#elif defined(USE_GNUTLS)
|
||||
#include <ngtcp2/ngtcp2_crypto_gnutls.h>
|
||||
#endif
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -86,7 +89,8 @@ struct h3out {
|
||||
#define QUIC_PRIORITY \
|
||||
"NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
|
||||
"+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
|
||||
"+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1"
|
||||
"+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
|
||||
"%DISABLE_TLS13_COMPAT_MODE"
|
||||
#endif
|
||||
|
||||
static CURLcode ng_process_ingress(struct Curl_easy *data,
|
||||
@@ -116,42 +120,6 @@ static void quic_printf(void *user_data, const char *fmt, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
static ngtcp2_crypto_level
|
||||
quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
|
||||
{
|
||||
switch(ossl_level) {
|
||||
case ssl_encryption_initial:
|
||||
return NGTCP2_CRYPTO_LEVEL_INITIAL;
|
||||
case ssl_encryption_early_data:
|
||||
return NGTCP2_CRYPTO_LEVEL_EARLY;
|
||||
case ssl_encryption_handshake:
|
||||
return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
|
||||
case ssl_encryption_application:
|
||||
return NGTCP2_CRYPTO_LEVEL_APPLICATION;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
#elif defined(USE_GNUTLS)
|
||||
static ngtcp2_crypto_level
|
||||
quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
|
||||
{
|
||||
switch(gtls_level) {
|
||||
case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
|
||||
return NGTCP2_CRYPTO_LEVEL_INITIAL;
|
||||
case GNUTLS_ENCRYPTION_LEVEL_EARLY:
|
||||
return NGTCP2_CRYPTO_LEVEL_EARLY;
|
||||
case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
|
||||
return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
|
||||
case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
|
||||
return NGTCP2_CRYPTO_LEVEL_APPLICATION;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void qlog_callback(void *user_data, uint32_t flags,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
@@ -222,27 +190,9 @@ static int write_client_handshake(struct quicsocket *qs,
|
||||
ngtcp2_crypto_level level,
|
||||
const uint8_t *data, size_t len)
|
||||
{
|
||||
struct quic_handshake *crypto_data;
|
||||
int rv;
|
||||
|
||||
crypto_data = &qs->crypto_data[level];
|
||||
if(!crypto_data->buf) {
|
||||
crypto_data->buf = malloc(4096);
|
||||
if(!crypto_data->buf)
|
||||
return 0;
|
||||
crypto_data->alloclen = 4096;
|
||||
}
|
||||
|
||||
/* TODO Just pretend that handshake does not grow more than 4KiB for
|
||||
now */
|
||||
assert(crypto_data->len + len <= crypto_data->alloclen);
|
||||
|
||||
memcpy(&crypto_data->buf[crypto_data->len], data, len);
|
||||
crypto_data->len += len;
|
||||
|
||||
rv = ngtcp2_conn_submit_crypto_data(
|
||||
qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len),
|
||||
len);
|
||||
rv = ngtcp2_conn_submit_crypto_data(qs->qconn, level, data, len);
|
||||
if(rv) {
|
||||
H3BUGF(fprintf(stderr, "write_client_handshake failed\n"));
|
||||
}
|
||||
@@ -259,7 +209,7 @@ static int quic_set_encryption_secrets(SSL *ssl,
|
||||
size_t secretlen)
|
||||
{
|
||||
struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
|
||||
int level = quic_from_ossl_level(ossl_level);
|
||||
int level = ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
|
||||
|
||||
if(ngtcp2_crypto_derive_and_install_rx_key(
|
||||
qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
|
||||
@@ -281,7 +231,8 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
|
||||
const uint8_t *data, size_t len)
|
||||
{
|
||||
struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
|
||||
ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level);
|
||||
ngtcp2_crypto_level level =
|
||||
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
|
||||
|
||||
return write_client_handshake(qs, level, data, len);
|
||||
}
|
||||
@@ -369,7 +320,8 @@ static int secret_func(gnutls_session_t ssl,
|
||||
const void *tx_secret, size_t secretlen)
|
||||
{
|
||||
struct quicsocket *qs = gnutls_session_get_ptr(ssl);
|
||||
int level = quic_from_gtls_level(gtls_level);
|
||||
int level =
|
||||
ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(gtls_level);
|
||||
|
||||
if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
|
||||
ngtcp2_crypto_derive_and_install_rx_key(
|
||||
@@ -394,7 +346,8 @@ static int read_func(gnutls_session_t ssl,
|
||||
size_t len)
|
||||
{
|
||||
struct quicsocket *qs = gnutls_session_get_ptr(ssl);
|
||||
ngtcp2_crypto_level level = quic_from_gtls_level(gtls_level);
|
||||
ngtcp2_crypto_level level =
|
||||
ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(gtls_level);
|
||||
int rv;
|
||||
|
||||
if(htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
|
||||
@@ -542,22 +495,6 @@ static int quic_init_ssl(struct quicsocket *qs)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level,
|
||||
uint64_t offset,
|
||||
const uint8_t *data, size_t datalen,
|
||||
void *user_data)
|
||||
{
|
||||
(void)offset;
|
||||
(void)user_data;
|
||||
|
||||
if(ngtcp2_crypto_read_write_crypto_data(tconn, crypto_level, data,
|
||||
datalen) != 0)
|
||||
return NGTCP2_ERR_CRYPTO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
|
||||
{
|
||||
(void)user_data;
|
||||
@@ -622,8 +559,8 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id,
|
||||
uint64_t app_error_code,
|
||||
static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags,
|
||||
int64_t stream_id, uint64_t app_error_code,
|
||||
void *user_data, void *stream_user_data)
|
||||
{
|
||||
struct quicsocket *qs = (struct quicsocket *)user_data;
|
||||
@@ -632,6 +569,10 @@ static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id,
|
||||
(void)stream_user_data;
|
||||
/* stream is closed... */
|
||||
|
||||
if(!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
|
||||
app_error_code = NGHTTP3_H3_NO_ERROR;
|
||||
}
|
||||
|
||||
rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
|
||||
app_error_code);
|
||||
if(rv) {
|
||||
@@ -652,7 +593,25 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
|
||||
(void)app_error_code;
|
||||
(void)stream_user_data;
|
||||
|
||||
rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id);
|
||||
rv = nghttp3_conn_shutdown_stream_read(qs->h3conn, stream_id);
|
||||
if(rv) {
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id,
|
||||
uint64_t app_error_code, void *user_data,
|
||||
void *stream_user_data)
|
||||
{
|
||||
struct quicsocket *qs = (struct quicsocket *)user_data;
|
||||
int rv;
|
||||
(void)tconn;
|
||||
(void)app_error_code;
|
||||
(void)stream_user_data;
|
||||
|
||||
rv = nghttp3_conn_shutdown_stream_read(qs->h3conn, stream_id);
|
||||
if(rv) {
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
@@ -712,14 +671,13 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
|
||||
static ngtcp2_callbacks ng_callbacks = {
|
||||
ngtcp2_crypto_client_initial_cb,
|
||||
NULL, /* recv_client_initial */
|
||||
cb_recv_crypto_data,
|
||||
ngtcp2_crypto_recv_crypto_data_cb,
|
||||
cb_handshake_completed,
|
||||
NULL, /* recv_version_negotiation */
|
||||
ngtcp2_crypto_encrypt_cb,
|
||||
ngtcp2_crypto_decrypt_cb,
|
||||
ngtcp2_crypto_hp_mask_cb,
|
||||
cb_recv_stream_data,
|
||||
NULL, /* acked_crypto_offset */
|
||||
cb_acked_stream_data_offset,
|
||||
NULL, /* stream_open */
|
||||
cb_stream_close,
|
||||
@@ -744,7 +702,9 @@ static ngtcp2_callbacks ng_callbacks = {
|
||||
ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
|
||||
NULL, /* recv_datagram */
|
||||
NULL, /* ack_datagram */
|
||||
NULL /* lost_datagram */
|
||||
NULL, /* lost_datagram */
|
||||
NULL, /* get_path_challenge_data */
|
||||
cb_stream_stop_sending
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -778,7 +738,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
infof(data, "Connect socket %d over QUIC to %s:%d\n",
|
||||
infof(data, "Connect socket %d over QUIC to %s:%d",
|
||||
sockfd, ipbuf, port);
|
||||
|
||||
qs->version = NGTCP2_PROTO_VER_MAX;
|
||||
@@ -827,15 +787,14 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* Store ngtp2 version info in this buffer, Prefix with a space. Return total
|
||||
* length written.
|
||||
* Store ngtcp2 version info in this buffer.
|
||||
*/
|
||||
int Curl_quic_ver(char *p, size_t len)
|
||||
void Curl_quic_ver(char *p, size_t len)
|
||||
{
|
||||
const ngtcp2_info *ng2 = ngtcp2_version(0);
|
||||
nghttp3_info *ht3 = nghttp3_version(0);
|
||||
return msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
|
||||
ng2->version_str, ht3->version_str);
|
||||
(void)msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
|
||||
ng2->version_str, ht3->version_str);
|
||||
}
|
||||
|
||||
static int ng_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
@@ -859,7 +818,6 @@ static int ng_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
||||
static void qs_disconnect(struct quicsocket *qs)
|
||||
{
|
||||
int i;
|
||||
if(!qs->conn) /* already closed */
|
||||
return;
|
||||
qs->conn = NULL;
|
||||
@@ -880,8 +838,6 @@ static void qs_disconnect(struct quicsocket *qs)
|
||||
qs->cred = NULL;
|
||||
}
|
||||
#endif
|
||||
for(i = 0; i < 3; i++)
|
||||
Curl_safefree(qs->crypto_data[i].buf);
|
||||
nghttp3_conn_del(qs->h3conn);
|
||||
ngtcp2_conn_del(qs->qconn);
|
||||
#ifdef USE_OPENSSL
|
||||
@@ -951,7 +907,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
|
||||
(void)stream_id;
|
||||
(void)app_error_code;
|
||||
(void)user_data;
|
||||
H3BUGF(infof(data, "cb_h3_stream_close CALLED\n"));
|
||||
H3BUGF(infof(data, "cb_h3_stream_close CALLED"));
|
||||
|
||||
stream->closed = TRUE;
|
||||
Curl_expire(data, 0, EXPIRE_QUIC);
|
||||
@@ -1143,14 +1099,10 @@ static nghttp3_callbacks ngh3_callbacks = {
|
||||
NULL, /* begin_trailers */
|
||||
cb_h3_recv_header,
|
||||
NULL, /* end_trailers */
|
||||
NULL, /* http_begin_push_promise */
|
||||
NULL, /* http_recv_push_promise */
|
||||
NULL, /* http_end_push_promise */
|
||||
NULL, /* http_cancel_push */
|
||||
cb_h3_send_stop_sending,
|
||||
NULL, /* push_stream */
|
||||
NULL, /* end_stream */
|
||||
NULL, /* reset_stream */
|
||||
NULL /* shutdown */
|
||||
};
|
||||
|
||||
static int init_ngh3_conn(struct quicsocket *qs)
|
||||
@@ -1287,7 +1239,7 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
|
||||
infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN");
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
@@ -1304,7 +1256,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
|
||||
if(!data->set.postfields) {
|
||||
stream->h3out->used -= datalen;
|
||||
H3BUGF(infof(data,
|
||||
"cb_h3_acked_stream_data, %zd bytes, %zd left unacked\n",
|
||||
"cb_h3_acked_stream_data, %zd bytes, %zd left unacked",
|
||||
datalen, stream->h3out->used));
|
||||
DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE);
|
||||
|
||||
@@ -1366,13 +1318,13 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
|
||||
if(!stream->upload_left)
|
||||
*pflags = NGHTTP3_DATA_FLAG_EOF;
|
||||
}
|
||||
H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)\n",
|
||||
H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)",
|
||||
nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
|
||||
out->used));
|
||||
}
|
||||
if(stream->upload_done && !stream->upload_len &&
|
||||
(stream->upload_left <= 0)) {
|
||||
H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF\n"));
|
||||
H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF"));
|
||||
*pflags = NGHTTP3_DATA_FLAG_EOF;
|
||||
return nread ? 1 : 0;
|
||||
}
|
||||
@@ -1565,7 +1517,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
|
||||
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.\n", MAX_ACC);
|
||||
"stream to be rejected.", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1611,7 +1563,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
|
||||
|
||||
Curl_safefree(nva);
|
||||
|
||||
infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n",
|
||||
infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)",
|
||||
stream3_id, (void *)data);
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -1641,7 +1593,7 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data,
|
||||
sent = len;
|
||||
}
|
||||
else {
|
||||
H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes\n",
|
||||
H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes",
|
||||
len));
|
||||
if(!stream->upload_len) {
|
||||
stream->upload_mem = mem;
|
||||
@@ -1660,6 +1612,12 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reset post upload buffer after resumed. */
|
||||
if(stream->upload_mem) {
|
||||
stream->upload_mem = NULL;
|
||||
stream->upload_len = 0;
|
||||
}
|
||||
|
||||
*curlcode = CURLE_OK;
|
||||
return sent;
|
||||
}
|
||||
@@ -1758,8 +1716,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
int rv;
|
||||
ssize_t sent;
|
||||
ssize_t outlen;
|
||||
uint8_t out[NGTCP2_MAX_PKTLEN_IPV4];
|
||||
size_t pktlen;
|
||||
uint8_t out[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
|
||||
ngtcp2_path_storage ps;
|
||||
ngtcp2_tstamp ts = timestamp();
|
||||
struct sockaddr_storage remote_addr;
|
||||
@@ -1772,19 +1729,6 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
ssize_t ndatalen;
|
||||
uint32_t flags;
|
||||
|
||||
switch(qs->local_addr.ss_family) {
|
||||
case AF_INET:
|
||||
pktlen = NGTCP2_MAX_PKTLEN_IPV4;
|
||||
break;
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
pktlen = NGTCP2_MAX_PKTLEN_IPV6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
|
||||
if(rv) {
|
||||
failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
|
||||
@@ -1811,15 +1755,16 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
|
||||
flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
|
||||
(fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
|
||||
outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, out, pktlen,
|
||||
outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, out,
|
||||
sizeof(out),
|
||||
&ndatalen, flags, stream_id,
|
||||
(const ngtcp2_vec *)vec, veccnt, ts);
|
||||
if(outlen == 0) {
|
||||
break;
|
||||
}
|
||||
if(outlen < 0) {
|
||||
if(outlen == NGTCP2_ERR_STREAM_DATA_BLOCKED ||
|
||||
outlen == NGTCP2_ERR_STREAM_SHUT_WR) {
|
||||
switch(outlen) {
|
||||
case NGTCP2_ERR_STREAM_DATA_BLOCKED:
|
||||
assert(ndatalen == -1);
|
||||
rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
|
||||
if(rv) {
|
||||
@@ -1828,8 +1773,17 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if(outlen == NGTCP2_ERR_WRITE_MORE) {
|
||||
case NGTCP2_ERR_STREAM_SHUT_WR:
|
||||
assert(ndatalen == -1);
|
||||
rv = nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id);
|
||||
if(rv) {
|
||||
failf(data,
|
||||
"nghttp3_conn_shutdown_stream_write returned error: %s\n",
|
||||
nghttp3_strerror(rv));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
continue;
|
||||
case NGTCP2_ERR_WRITE_MORE:
|
||||
assert(ndatalen >= 0);
|
||||
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
|
||||
if(rv) {
|
||||
@@ -1838,8 +1792,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
default:
|
||||
assert(ndatalen == -1);
|
||||
failf(data, "ngtcp2_conn_writev_stream returned error: %s",
|
||||
ngtcp2_strerror((int)outlen));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user