Aggiornato curl

Aggiunto curlpp

git-svn-id: svn://10.65.10.50/branches/R_10_00@24148 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
bonazzi 2017-10-23 22:22:45 +00:00
parent 635a076f2b
commit 4bcb3807c3
1529 changed files with 84782 additions and 32259 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -139,7 +139,7 @@ int main(void)
rc = gethostbyname_r(address, &h, &hdata); rc = gethostbyname_r(address, &h, &hdata);
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \ #elif defined(HAVE_GETHOSTBYNAME_R_5) || \
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
rc = gethostbyname_r(address, &h, buffer, 8192, 0, &h_errnop); rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
(void)hp; /* not used for test */ (void)hp; /* not used for test */
#elif defined(HAVE_GETHOSTBYNAME_R_6) || \ #elif defined(HAVE_GETHOSTBYNAME_R_6) || \
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT) defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
@ -533,3 +533,19 @@ main () {
return 0; return 0;
} }
#endif #endif
#ifdef HAVE_FSETXATTR_6
#include <sys/xattr.h> /* header from libc, not from libattr */
int
main() {
fsetxattr(0, 0, 0, 0, 0, 0);
return 0;
}
#endif
#ifdef HAVE_FSETXATTR_5
#include <sys/xattr.h> /* header from libc, not from libattr */
int
main() {
fsetxattr(0, 0, 0, 0, 0);
return 0;
}
#endif

View File

@ -12,7 +12,7 @@
# GSS_LINKER_FLAGS - Additional linker flags # GSS_LINKER_FLAGS - Additional linker flags
# GSS_COMPILER_FLAGS - Additional compiler flags # GSS_COMPILER_FLAGS - Additional compiler flags
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest. # GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
# In case the library is found but no version info availabe it'll be set to "unknown" # In case the library is found but no version info available it'll be set to "unknown"
set(_MIT_MODNAME mit-krb5-gssapi) set(_MIT_MODNAME mit-krb5-gssapi)
set(_HEIMDAL_MODNAME heimdal-gssapi) set(_HEIMDAL_MODNAME heimdal-gssapi)

View File

@ -93,3 +93,32 @@ macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif() endif()
endmacro(CURL_INTERNAL_TEST_RUN) endmacro(CURL_INTERNAL_TEST_RUN)
macro(CURL_NROFF_CHECK)
find_program(NROFF NAMES gnroff nroff)
if(NROFF)
# Need a way to write to stdin, this will do
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
# Tests for a valid nroff option to generate a manpage
foreach(_MANOPT "-man" "-mandoc")
execute_process(COMMAND "${NROFF}" ${_MANOPT}
OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
ERROR_QUIET)
# Save the option if it was valid
if(NROFF_MANOPT_OUTPUT)
message("Found *nroff option: -- ${_MANOPT}")
set(NROFF_MANOPT ${_MANOPT})
set(NROFF_USEFUL ON)
break()
endif()
endforeach()
# No need for the temporary file
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
if(NOT NROFF_USEFUL)
message(WARNING "Found no *nroff option to get plaintext from man pages")
endif()
else()
message(WARNING "Found no *nroff program")
endif()
endmacro(CURL_NROFF_CHECK)

View File

@ -10,8 +10,8 @@ endmacro(add_header_include)
set(signature_call_conv) set(signature_call_conv)
if(HAVE_WINDOWS_H) if(HAVE_WINDOWS_H)
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK2_H "winsock2.h") add_header_include(HAVE_WINSOCK2_H "winsock2.h")
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK_H "winsock.h") add_header_include(HAVE_WINSOCK_H "winsock.h")
set(_source_epilogue set(_source_epilogue
"${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif") "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
@ -32,9 +32,9 @@ int main(void) {
if(curl_cv_recv) if(curl_cv_recv)
if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown") if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
foreach(recv_retv "int" "ssize_t" ) foreach(recv_retv "int" "ssize_t" )
foreach(recv_arg1 "int" "ssize_t" "SOCKET") foreach(recv_arg1 "SOCKET" "int" )
foreach(recv_arg2 "void *" "char *") foreach(recv_arg2 "char *" "void *" )
foreach(recv_arg3 "size_t" "int" "socklen_t" "unsigned int") foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int")
foreach(recv_arg4 "int" "unsigned int") foreach(recv_arg4 "int" "unsigned int")
if(NOT curl_cv_func_recv_done) if(NOT curl_cv_func_recv_done)
unset(curl_cv_func_recv_test CACHE) unset(curl_cv_func_recv_test CACHE)
@ -96,9 +96,9 @@ int main(void) {
if(curl_cv_send) if(curl_cv_send)
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown") if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
foreach(send_retv "int" "ssize_t" ) foreach(send_retv "int" "ssize_t" )
foreach(send_arg1 "int" "ssize_t" "SOCKET") foreach(send_arg1 "SOCKET" "int" "ssize_t" )
foreach(send_arg2 "const void *" "void *" "char *" "const char *") foreach(send_arg2 "const char *" "const void *" "void *" "char *")
foreach(send_arg3 "size_t" "int" "socklen_t" "unsigned int") foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int")
foreach(send_arg4 "int" "unsigned int") foreach(send_arg4 "int" "unsigned int")
if(NOT curl_cv_func_send_done) if(NOT curl_cv_func_send_done)
unset(curl_cv_func_send_test CACHE) unset(curl_cv_func_send_test CACHE)
@ -179,17 +179,20 @@ int main(void) {
include(CheckCSourceRuns) include(CheckCSourceRuns)
set(CMAKE_REQUIRED_FLAGS) # See HAVE_POLL in CMakeLists.txt for why poll is disabled on macOS
if(HAVE_SYS_POLL_H) if(NOT APPLE)
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H") set(CMAKE_REQUIRED_FLAGS)
endif(HAVE_SYS_POLL_H) if(HAVE_SYS_POLL_H)
check_c_source_runs(" set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
#ifdef HAVE_SYS_POLL_H endif(HAVE_SYS_POLL_H)
# include <sys/poll.h> check_c_source_runs("
#endif #ifdef HAVE_SYS_POLL_H
int main(void) { # include <sys/poll.h>
return poll((void *)0, 0, 10 /*ms*/); #endif
}" HAVE_POLL_FINE) int main(void) {
return poll((void *)0, 0, 10 /*ms*/);
}" HAVE_POLL_FINE)
endif()
set(HAVE_SIG_ATOMIC_T 1) set(HAVE_SIG_ATOMIC_T 1)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS)

View File

@ -29,3 +29,16 @@ function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
set(${RETVAL} TRUE PARENT_SCOPE) set(${RETVAL} TRUE PARENT_SCOPE)
endif() endif()
endfunction() endfunction()
# Returns a list of arguments that evaluate to true
function(collect_true output_var output_count_var)
set(${output_var})
foreach(option_var IN LISTS ARGN)
if(${option_var})
list(APPEND ${output_var} ${option_var})
endif()
endforeach()
set(${output_var} ${${output_var}} PARENT_SCOPE)
list(LENGTH ${output_var} ${output_count_var})
set(${output_count_var} ${${output_count_var}} PARENT_SCOPE)
endfunction()

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
COPYRIGHT AND PERMISSION NOTICE COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2015, Daniel Stenberg, <daniel@haxx.se>. Copyright (c) 1996 - 2017, Daniel Stenberg, <daniel@haxx.se>, and many
contributors, see the THANKS file.
All rights reserved. All rights reserved.

View File

@ -65,7 +65,7 @@ else
ARCHES64='-arch x86_64' ARCHES64='-arch x86_64'
#We "know" that 10.4 and earlier do not support 64bit #We "know" that 10.4 and earlier do not support 64bit
OLD_SDK64=`ls $SDK_PATH|egrep -v "10.[0-4]"|head -1` OLD_SDK64=`ls $SDK_PATH|egrep -v "10.[0-4]"|head -1`
NEW_SDK64=`ls -r $SDK_PATH|egrep -v "10.[0-4]"|head -1` NEW_SDK64=`ls -r $SDK_PATH|egrep -v "10.[0-4][^0-9]" | head -1`
if test $USE_OLD -gt 0 if test $USE_OLD -gt 0
then then
SDK64=$OLD_SDK64 SDK64=$OLD_SDK64
@ -126,15 +126,6 @@ if test ! -z $SDK32; then
pwd pwd
lipo libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 -create -output libcurl.framework/${FRAMEWORK_VERSION}/libcurl lipo libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 -create -output libcurl.framework/${FRAMEWORK_VERSION}/libcurl
rm libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 rm libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
cp libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild32.h
cp include/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild64.h
cat >libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h <<EOF
#ifdef __LP64__
#include "curl/curlbuild64.h"
#else
#include "curl/curlbuild32.h"
#endif
EOF
fi fi
pwd pwd

View File

@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -24,112 +24,138 @@ AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \ CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake \ CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake \
CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake \ CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake \
include/curl/curlbuild.h.cmake CMake/Macros.cmake CMake/Macros.cmake \
CMake/CurlSymbolHiding.cmake CMake/FindCARES.cmake \
CMake/FindLibSSH2.cmake CMake/FindNGHTTP2.cmake \
CMake/FindMbedTLS.cmake CMake/cmake_uninstall.cmake.in
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist
VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc
VC6_SRCTMPL = projects/Windows/VC6/src/curlsrc.tmpl VC6_SRCTMPL = projects/Windows/VC6/src/curl.tmpl
VC6_SRCDSP = projects/Windows/VC6/src/curlsrc.dsp.dist VC6_SRCDSP = projects/Windows/VC6/src/curl.dsp.dist
VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc
VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl
VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist
VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc
VC7_SRCTMPL = projects/Windows/VC7/src/curlsrc.tmpl VC7_SRCTMPL = projects/Windows/VC7/src/curl.tmpl
VC7_SRCVCPROJ = projects/Windows/VC7/src/curlsrc.vcproj.dist VC7_SRCVCPROJ = projects/Windows/VC7/src/curl.vcproj.dist
VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc
VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl
VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist
VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc
VC71_SRCTMPL = projects/Windows/VC7.1/src/curlsrc.tmpl VC71_SRCTMPL = projects/Windows/VC7.1/src/curl.tmpl
VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curlsrc.vcproj.dist VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curl.vcproj.dist
VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc
VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl
VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist
VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc
VC8_SRCTMPL = projects/Windows/VC8/src/curlsrc.tmpl VC8_SRCTMPL = projects/Windows/VC8/src/curl.tmpl
VC8_SRCVCPROJ = projects/Windows/VC8/src/curlsrc.vcproj.dist VC8_SRCVCPROJ = projects/Windows/VC8/src/curl.vcproj.dist
VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc
VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl
VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist
VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc
VC9_SRCTMPL = projects/Windows/VC9/src/curlsrc.tmpl VC9_SRCTMPL = projects/Windows/VC9/src/curl.tmpl
VC9_SRCVCPROJ = projects/Windows/VC9/src/curlsrc.vcproj.dist VC9_SRCVCPROJ = projects/Windows/VC9/src/curl.vcproj.dist
VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc
VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl
VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist
VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc
VC10_SRCTMPL = projects/Windows/VC10/src/curlsrc.tmpl VC10_SRCTMPL = projects/Windows/VC10/src/curl.tmpl
VC10_SRCVCXPROJ = projects/Windows/VC10/src/curlsrc.vcxproj.dist VC10_SRCVCXPROJ = projects/Windows/VC10/src/curl.vcxproj.dist
VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc
VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl
VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist
VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc
VC11_SRCTMPL = projects/Windows/VC11/src/curlsrc.tmpl VC11_SRCTMPL = projects/Windows/VC11/src/curl.tmpl
VC11_SRCVCXPROJ = projects/Windows/VC11/src/curlsrc.vcxproj.dist VC11_SRCVCXPROJ = projects/Windows/VC11/src/curl.vcxproj.dist
VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc
VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl
VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist
VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc
VC12_SRCTMPL = projects/Windows/VC12/src/curlsrc.tmpl VC12_SRCTMPL = projects/Windows/VC12/src/curl.tmpl
VC12_SRCVCXPROJ = projects/Windows/VC12/src/curlsrc.vcxproj.dist VC12_SRCVCXPROJ = projects/Windows/VC12/src/curl.vcxproj.dist
VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc
VC_DIST = projects/README \ VC14_LIBTMPL = projects/Windows/VC14/lib/libcurl.tmpl
projects/build-openssl.bat \ VC14_LIBVCXPROJ = projects/Windows/VC14/lib/libcurl.vcxproj.dist
projects/checksrc.bat \ VC14_LIBVCXPROJ_DEPS = $(VC14_LIBTMPL) Makefile.am lib/Makefile.inc
projects/Windows/VC6/curl-all.dsw \ VC14_SRCTMPL = projects/Windows/VC14/src/curl.tmpl
projects/Windows/VC6/lib/libcurl.dsw \ VC14_SRCVCXPROJ = projects/Windows/VC14/src/curl.vcxproj.dist
projects/Windows/VC6/src/curlsrc.dsw \ VC14_SRCVCXPROJ_DEPS = $(VC14_SRCTMPL) Makefile.am src/Makefile.inc
projects/Windows/VC7/curl-all.sln \
projects/Windows/VC7/lib/libcurl.sln \ VC_DIST = projects/README \
projects/Windows/VC7/src/curlsrc.sln \ projects/build-openssl.bat \
projects/Windows/VC7.1/curl-all.sln \ projects/build-wolfssl.bat \
projects/Windows/VC7.1/lib/libcurl.sln \ projects/checksrc.bat \
projects/Windows/VC7.1/src/curlsrc.sln \ projects/Windows/VC6/curl-all.dsw \
projects/Windows/VC8/curl-all.sln \ projects/Windows/VC6/lib/libcurl.dsw \
projects/Windows/VC8/lib/libcurl.sln \ projects/Windows/VC6/src/curl.dsw \
projects/Windows/VC8/src/curlsrc.sln \ projects/Windows/VC7/curl-all.sln \
projects/Windows/VC9/curl-all.sln \ projects/Windows/VC7/lib/libcurl.sln \
projects/Windows/VC9/lib/libcurl.sln \ projects/Windows/VC7/src/curl.sln \
projects/Windows/VC9/src/curlsrc.sln \ projects/Windows/VC7.1/curl-all.sln \
projects/Windows/VC10/curl-all.sln \ projects/Windows/VC7.1/lib/libcurl.sln \
projects/Windows/VC10/lib/libcurl.sln \ projects/Windows/VC7.1/src/curl.sln \
projects/Windows/VC10/src/curlsrc.sln \ projects/Windows/VC8/curl-all.sln \
projects/Windows/VC11/curl-all.sln \ projects/Windows/VC8/lib/libcurl.sln \
projects/Windows/VC11/lib/libcurl.sln \ projects/Windows/VC8/src/curl.sln \
projects/Windows/VC11/src/curlsrc.sln \ projects/Windows/VC9/curl-all.sln \
projects/Windows/VC12/curl-all.sln \ projects/Windows/VC9/lib/libcurl.sln \
projects/Windows/VC12/lib/libcurl.sln \ projects/Windows/VC9/src/curl.sln \
projects/Windows/VC12/src/curlsrc.sln projects/Windows/VC10/curl-all.sln \
projects/Windows/VC10/lib/libcurl.sln \
projects/Windows/VC10/lib/libcurl.vcxproj.filters \
projects/Windows/VC10/src/curl.sln \
projects/Windows/VC10/src/curl.vcxproj.filters \
projects/Windows/VC11/curl-all.sln \
projects/Windows/VC11/lib/libcurl.sln \
projects/Windows/VC11/lib/libcurl.vcxproj.filters \
projects/Windows/VC11/src/curl.sln \
projects/Windows/VC11/src/curl.vcxproj.filters \
projects/Windows/VC12/curl-all.sln \
projects/Windows/VC12/lib/libcurl.sln \
projects/Windows/VC12/lib/libcurl.vcxproj.filters \
projects/Windows/VC12/src/curl.sln \
projects/Windows/VC12/src/curl.vcxproj.filters \
projects/Windows/VC14/curl-all.sln \
projects/Windows/VC14/lib/libcurl.sln \
projects/Windows/VC14/lib/libcurl.vcxproj.filters \
projects/Windows/VC14/src/curl.sln \
projects/Windows/VC14/src/curl.vcxproj.filters \
projects/generate.bat \
projects/wolfssl_options.h \
projects/wolfssl_override.props
WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \ WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
winbuild/MakefileBuild.vc winbuild/Makefile.vc \ winbuild/MakefileBuild.vc winbuild/Makefile.vc
winbuild/Makefile.msvc.names
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \ EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
RELEASE-NOTES buildconf libcurl.pc.in MacOSX-Framework \ RELEASE-NOTES buildconf libcurl.pc.in MacOSX-Framework scripts/zsh.pl \
$(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) lib/libcurl.vers.in scripts/updatemanpages.pl $(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) \
lib/libcurl.vers.in buildconf.bat scripts/coverage.sh
CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
$(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \ $(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \
$(VC9_LIBVCPROJ) $(VC9_SRCVCPROJ) $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) \ $(VC9_LIBVCPROJ) $(VC9_SRCVCPROJ) $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) \
$(VC11_LIBVCXPROJ) $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ) $(VC11_LIBVCXPROJ) $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ) \
$(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ)
bin_SCRIPTS = curl-config bin_SCRIPTS = curl-config
SUBDIRS = lib src include SUBDIRS = lib src
DIST_SUBDIRS = $(SUBDIRS) tests packages docs DIST_SUBDIRS = $(SUBDIRS) tests packages scripts include docs
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcurl.pc pkgconfig_DATA = libcurl.pc
@ -144,14 +170,14 @@ dist-hook:
(distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \ (distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \
for file in $$distit; do \ for file in $$distit; do \
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
cp $$file $(distdir)$$strip; \ cp -p $$file $(distdir)$$strip; \
done) done)
html: html:
cd docs; make html cd docs && $(MAKE) html
pdf: pdf:
cd docs; make pdf cd docs && $(MAKE) pdf
check: test examples check-docs check: test examples check-docs
@ -170,14 +196,23 @@ test:
test-full: test-full:
@(cd tests; $(MAKE) all full-test) @(cd tests; $(MAKE) all full-test)
test-nonflaky:
@(cd tests; $(MAKE) all nonflaky-test)
test-torture: test-torture:
@(cd tests; $(MAKE) all torture-test) @(cd tests; $(MAKE) all torture-test)
test-event:
@(cd tests; $(MAKE) all event-test)
test-am: test-am:
@(cd tests; $(MAKE) all am-test) @(cd tests; $(MAKE) all am-test)
endif endif
fuzzer:
@(cd tests/fuzz; $(MAKE) all)
examples: examples:
@(cd docs/examples; $(MAKE) check) @(cd docs/examples; $(MAKE) check)
@ -227,10 +262,10 @@ rpm:
# pkgadd -d ./HAXXcurl-* # pkgadd -d ./HAXXcurl-*
# #
# gak - libtool requires an absoulte directory, hence the pwd below... # gak - libtool requires an absolute directory, hence the pwd below...
pkgadd: pkgadd:
umask 022 ; \ umask 022 ; \
make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \ $(MAKE) install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \
cat COPYING > $(srcdir)/packages/Solaris/copyright ; \ cat COPYING > $(srcdir)/packages/Solaris/copyright ; \
cd $(srcdir)/packages/Solaris && $(MAKE) package cd $(srcdir)/packages/Solaris && $(MAKE) package
@ -244,11 +279,13 @@ cygwinbin:
install-data-hook: install-data-hook:
cd include && $(MAKE) install cd include && $(MAKE) install
cd docs && $(MAKE) install cd docs && $(MAKE) install
cd docs/libcurl && $(MAKE) install
# We extend the standard uninstall with a custom hook: # We extend the standard uninstall with a custom hook:
uninstall-hook: uninstall-hook:
cd include && $(MAKE) uninstall cd include && $(MAKE) uninstall
cd docs && $(MAKE) uninstall cd docs && $(MAKE) uninstall
cd docs/libcurl && $(MAKE) uninstall
ca-bundle: lib/mk-ca-bundle.pl ca-bundle: lib/mk-ca-bundle.pl
@echo "generating a fresh ca-bundle.crt" @echo "generating a fresh ca-bundle.crt"
@ -261,6 +298,9 @@ ca-firefox: lib/firefox-db2pem.sh
checksrc: checksrc:
cd lib && $(MAKE) checksrc cd lib && $(MAKE) checksrc
cd src && $(MAKE) checksrc cd src && $(MAKE) checksrc
cd tests && $(MAKE) checksrc
cd include/curl && $(MAKE) checksrc
cd docs/examples && $(MAKE) checksrc
.PHONY: vc-ide .PHONY: vc-ide
@ -269,10 +309,12 @@ vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
$(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \ $(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \
$(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \ $(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \
$(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \ $(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \
$(VC12_SRCVCXPROJ_DEPS) $(VC12_SRCVCXPROJ_DEPS) $(VC14_LIBVCXPROJ_DEPS) $(VC14_SRCVCXPROJ_DEPS)
@(win32_lib_srcs='$(LIB_CFILES)'; \ @(win32_lib_srcs='$(LIB_CFILES)'; \
win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \ win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \
win32_lib_rc='$(LIB_RCFILES)'; \ win32_lib_rc='$(LIB_RCFILES)'; \
win32_lib_vauth_srcs='$(LIB_VAUTH_CFILES)'; \
win32_lib_vauth_hdrs='$(LIB_VAUTH_HFILES)'; \
win32_lib_vtls_srcs='$(LIB_VTLS_CFILES)'; \ win32_lib_vtls_srcs='$(LIB_VTLS_CFILES)'; \
win32_lib_vtls_hdrs='$(LIB_VTLS_HFILES)'; \ win32_lib_vtls_hdrs='$(LIB_VTLS_HFILES)'; \
win32_src_srcs='$(CURL_CFILES)'; \ win32_src_srcs='$(CURL_CFILES)'; \
@ -283,6 +325,8 @@ vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
\ \
sorted_lib_srcs=`for file in $$win32_lib_srcs; do echo $$file; done | sort`; \ sorted_lib_srcs=`for file in $$win32_lib_srcs; do echo $$file; done | sort`; \
sorted_lib_hdrs=`for file in $$win32_lib_hdrs; do echo $$file; done | sort`; \ sorted_lib_hdrs=`for file in $$win32_lib_hdrs; do echo $$file; done | sort`; \
sorted_lib_vauth_srcs=`for file in $$win32_lib_vauth_srcs; do echo $$file; done | sort`; \
sorted_lib_vauth_hdrs=`for file in $$win32_lib_vauth_hdrs; do echo $$file; done | sort`; \
sorted_lib_vtls_srcs=`for file in $$win32_lib_vtls_srcs; do echo $$file; done | sort`; \ sorted_lib_vtls_srcs=`for file in $$win32_lib_vtls_srcs; do echo $$file; done | sort`; \
sorted_lib_vtls_hdrs=`for file in $$win32_lib_vtls_hdrs; do echo $$file; done | sort`; \ sorted_lib_vtls_hdrs=`for file in $$win32_lib_vtls_hdrs; do echo $$file; done | sort`; \
sorted_src_srcs=`for file in $$win32_src_srcs; do echo $$file; done | sort`; \ sorted_src_srcs=`for file in $$win32_src_srcs; do echo $$file; done | sort`; \
@ -293,10 +337,11 @@ vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
awk_code='\ awk_code='\
function gen_element(type, dir, file)\ function gen_element(type, dir, file)\
{\ {\
sub(/vauth\//, "", file);\
sub(/vtls\//, "", file);\ sub(/vtls\//, "", file);\
\ \
spaces=" ";\ spaces=" ";\
if(dir == "lib\\vtls")\ if(dir == "lib\\vauth" || dir == "lib\\vtls")\
tabs=" ";\ tabs=" ";\
else\ else\
tabs=" ";\ tabs=" ";\
@ -350,6 +395,14 @@ function gen_element(type, dir, file)\
split(lib_rc, arr);\ split(lib_rc, arr);\
for(val in arr) gen_element(proj_type, "lib", arr[val]);\ for(val in arr) gen_element(proj_type, "lib", arr[val]);\
}\ }\
else if($$0 == "CURL_LIB_VAUTH_C_FILES") {\
split(lib_vauth_srcs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\
}\
else if($$0 == "CURL_LIB_VAUTH_H_FILES") {\
split(lib_vauth_hdrs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\
}\
else if($$0 == "CURL_LIB_VTLS_C_FILES") {\ else if($$0 == "CURL_LIB_VTLS_C_FILES") {\
split(lib_vtls_srcs, arr);\ split(lib_vtls_srcs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\ for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\
@ -393,6 +446,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC6_LIBTMPL) > $(VC6_LIBDSP) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC6_LIBTMPL) > $(VC6_LIBDSP) || { exit 1; }; \
@ -411,6 +466,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC7_LIBTMPL) > $(VC7_LIBVCPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC7_LIBTMPL) > $(VC7_LIBVCPROJ) || { exit 1; }; \
@ -429,6 +486,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC71_LIBTMPL) > $(VC71_LIBVCPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC71_LIBTMPL) > $(VC71_LIBVCPROJ) || { exit 1; }; \
@ -447,6 +506,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC8_LIBTMPL) > $(VC8_LIBVCPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC8_LIBTMPL) > $(VC8_LIBVCPROJ) || { exit 1; }; \
@ -465,6 +526,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC9_LIBTMPL) > $(VC9_LIBVCPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC9_LIBTMPL) > $(VC9_LIBVCPROJ) || { exit 1; }; \
@ -483,6 +546,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \
@ -501,6 +566,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \
@ -519,6 +586,8 @@ function gen_element(type, dir, file)\
-v lib_srcs="$$sorted_lib_srcs" \ -v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \ -v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \ -v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \ "$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \
@ -530,4 +599,24 @@ function gen_element(type, dir, file)\
-v src_rc="$$win32_src_rc" \ -v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \ -v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \ -v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; };) "$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC14_LIBVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC14_LIBTMPL) > $(VC14_LIBVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC14_SRCVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC14_SRCTMPL) > $(VC14_SRCVCXPROJ) || { exit 1; };)

View File

@ -24,7 +24,7 @@ README
CONTACT CONTACT
If you have problems, questions, ideas or suggestions, please contact us If you have problems, questions, ideas or suggestions, please contact us
by posting to a suitable mailing list. See http://curl.haxx.se/mail/ by posting to a suitable mailing list. See https://curl.haxx.se/mail/
All contributors to the project are listed in the THANKS document. All contributors to the project are listed in the THANKS document.
@ -32,13 +32,13 @@ WEB SITE
Visit the curl web site for the latest news and downloads: Visit the curl web site for the latest news and downloads:
http://curl.haxx.se/ https://curl.haxx.se/
GIT GIT
To download the very latest source off the GIT server do this: To download the very latest source off the GIT server do this:
git clone git://github.com/bagder/curl.git git clone https://github.com/curl/curl.git
(you'll get a directory named curl created, filled with the source code) (you'll get a directory named curl created, filled with the source code)

View File

@ -1,50 +1,201 @@
Curl and libcurl 7.43.0 Curl and libcurl 7.56.0
Public curl releases: 147 Public curl releases: 169
Command line options: 176 Command line options: 211
curl_easy_setopt() options: 218 curl_easy_setopt() options: 249
Public functions in libcurl: 58 Public functions in libcurl: 74
Contributors: 1265 Contributors: 1618
This release includes the following changes: This release includes the following changes:
o New: CURLOPT_PROXY_SERVICE_NAME and CURLOPT_SERVICE_NAME o curl: enable compression for SCP/SFTP with --compressed-ssh [11]
o New curl options: --proxy-service-name and --service-name o libcurl: enable compression for SCP/SFTP with CURLOPT_SSH_COMPRESSION [11]
o New curl option: --data-raw [5] o vtls: added dynamic changing SSL backend with curl_global_sslset() [28]
o new MIME API, curl_mime_init() and friends [32]
o openssl: initial SSLKEYLOGFILE implementation [36]
This release includes the following bugfixes: This release includes the following bugfixes:
o nss: fix compilation failure with old versions of NSS [1] o FTP: zero terminate the entry path even on bad input [67]
o curl_easy_getinfo.3: document 'internals' in CURLINFO_TLS_SESSION o examples/ftpuploadresume.c: use portable code
o schannel.c: Fix possible SEC_E_BUFFER_TOO_SMALL error o runtests: match keywords case insensitively
o Curl_ossl_init: load builtin modules [2] o travis: build the examples too [1]
o configure: follow-up fix for krb5-config [3] o strtoofft: reduce integer overflow risks globally [2]
o sasl_sspi: Populate domain from the realm in the challenge [4] o zsh.pl: produce a working completion script again [3]
o netrc: support 'default' token o cmake: remove dead code for CURL_DISABLE_RTMP [4]
o README: convert to UTF-8 o progress: Track total times following redirects [5]
o cyassl: Implement public key pinning o configure: fix --disable-threaded-resolver [6]
o nss: implement public key pinning for NSS backend o cmake: remove dead code for DISABLED_THREADSAFE [7]
o configure: fix clang version detection
o darwinssi: fix error: variable length array used
o travis: add metalink to some osx builds [8]
o configure: check for __builtin_available() availability [9]
o http_proxy: fix build error for CURL_DOES_CONVERSIONS [10]
o examples/ftpuploadresume: checksrc compliance
o ftp: fix CWD when doing multicwd then nocwd on same connection [12]
o system.h: remove all CURL_SIZEOF_* defines [13]
o http: Don't wait on CONNECT when there is no proxy [14]
o system.h: check for __ppc__ as well [15]
o http2_recv: return error better on fatal h2 errors [16]
o scripts/contri*sh: use "git log --use-mailmap"
o tftp: fix memory leak on too long filename [17]
o system.h: fix build for hppa [18]
o cmake: enable picky compiler options with clang and gcc [19]
o makefile.m32: add support for libidn2 [20]
o curl: turn off MinGW CRT's globbing [21]
o request-target.d: mention added in 7.55.0
o curl: shorten and clean up CA cert verification error message [22]
o imap: support PREAUTH [23]
o CURLOPT_USERPWD.3: see also CURLOPT_PROXYUSERPWD
o examples/threaded-ssl: mention that this is for openssl before 1.1
o winbuild: fix embedded manifest option [24]
o tests: Make sure libtests & unittests call curl_global_cleanup()
o system.h: include sys/poll.h for AIX [25]
o darwinssl: handle long strings in TLS certs [26]
o strtooff: fix build for systems with long long but no strtoll [27]
o asyn-thread: Improved cleanup after OOM situations
o HELP-US.md: "How to get started helping out in the curl project" [29]
o curl.h: CURLSSLBACKEND_WOLFSSL used wrong value [30]
o unit1301: fix error message on first test
o ossfuzz: moving towards the ideal integration [31]
o http: fix a memory leakage in checkrtspprefix()
o examples/post-callback: stop returning one byte at a time
o schannel: return CURLE_SSL_CACERT on failed verification [33]
o MAIL-ETIQUETTE: added "1.9 Your emails are public"
o http-proxy: treat all 2xx as CONNECT success [34]
o openssl: use OpenSSL's default ciphers by default [35]
o runtests.pl: support attribute "nonewline" in part verify/upload
o configure: remove --enable-soname-bump and SONAME_BUMP [37]
o travis: add c-ares enabled builds linux + osx [38]
o vtls: fix WolfSSL 3.12 build problems [39]
o http-proxy: when not doing CONNECT, that phase is done immediately [40]
o configure: fix curl_off_t check's include order [41]
o configure: use -Wno-varargs on clang 3.9[.X] debug builds
o rtsp: do not call fwrite() with NULL pointer FILE * [42]
o mbedtls: enable CA path processing [43]
o travis: add build without HTTP/SMTP/IMAP
o checksrc: verify more code style rules [44]
o HTTP proxy: on connection re-use, still use the new remote port [45]
o tests: add initial gssapi test using stub implementation [46]
o rtsp: Segfault when using WRITEDATA [47]
o docs: clarify the CURLOPT_INTERLEAVE* options behavior
o non-ascii: use iconv() with 'char **' argument [48]
o server/getpart: provide dummy function to build conversion enabled
o conversions: fix several compiler warnings
o openssl: add missing includes [49]
o schannel: Support partial send for when data is too large [50]
o socks: fix incorrect port number in SOCKS4 error message [51]
o curl: fix integer overflow in timeout options [52]
o travis: on mac, don't install openssl or libidn [53]
o cookies: reject oversized cookies instead of truncating [54]
o cookies: use lock when using CURLINFO_COOKIELIST [55]
o curl: check fseek() return code and bail on error
o examples/post-callback: use long for CURLOPT_POSTFIELDSIZE
o openssl: only verify RSA private key if supported [56]
o tests: make the imap server not verify user+password [57]
o imap: quote atoms properly when escaping characters [58]
o tests: fix a compiler warning in test 643
o file_range: avoid integer overflow when figuring out byte range [59]
o curl.h: include <sys/select.h> on cygwin too [60]
o reuse_conn: don't copy flags that are known to be equal [61]
o http: fix adding custom empty headers to repeated requests [62]
o docs: clarify the use of environment variables for proxy [63]
o docs: link CURLOPT_CONNECTTIMEOUT and CURLOPT_CONNECTTIMEOUT_MS [64]
o connect: fix race condition with happy eyeballs timeout [65]
o cookie: fix memory leak if path was set twice in header [66]
o vtls: compare and clone ssl configs properly [68]
o proxy: read the "no_proxy" variable only if necessary [69]
This release includes the following known bugs: This release includes the following known bugs:
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html) o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html)
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Alessandro Ghedini, Anthony Avina, Brian Chrisman, Dagobert Michelsen, Anders Bakken, Andrei Karas, Benbuck Nason, Ben Greear, Benjamin Sergeant,
Dan Fandrich, Daniel Stenberg, Grant Pannell, Jens Rantil, Kamil Dudka, Bill Pyne, Brian Carpenter, Dan Fandrich, Daniel Stenberg, David Benjamin,
Linus Nielsen, Marc Hoersken, Oren Souroujon, Patrick Rapin, Paul Howarth, Dirk Feytons, Even Rouault, Frank Denis, Gergely Nagy, Gisle Vanem,
Ray Satiro, Viktor Szakáts, Yehezkel Horowitz, Ian Fette, imilli on github, Isaac Boukris, Jackarain on github,
(17 contributors) Jakub Zakrzewski, Jan Alexander Steffens, Johannes Schindelin,
John David Anglin, joshhe on github, Kamil Dudka, Kevin Smith,
Lawrence Wagerfield, Maksim Stsepanenka, Marc Aldorasi, Marcel Raad,
Max Dymond, Michael Kaufmann, Michael Smith, Nick Zitzmann,
Nicolas Morey-Chaisemartin, Oli Kingshott, Patrick Monnerat, Pavel P,
Peter Lamare, Peter Wu, Ray Satiro, Rich Gray, Ryan Schmidt, Ryan Winograd,
SBKarr on github, Tatsuhiro Tsujikawa, Viktor Szakáts,
(47 contributors)
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues: References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/mail/lib-2015-04/0095.html [1] = https://curl.haxx.se/bug/?i=1777
[2] = https://github.com/bagder/curl/pull/206 [2] = https://curl.haxx.se/bug/?i=1758
[3] = https://github.com/bagder/curl/commit/5b668606527613179d0349f21b4ab0df2971e3d2#commitcomment-10473445 [3] = https://curl.haxx.se/bug/?i=1779
[4] = https://github.com/bagder/curl/pull/141 [4] = https://curl.haxx.se/bug/?i=1785
[5] = https://github.com/bagder/curl/issues/198 [5] = https://curl.haxx.se/bug/?i=1602
[6] = https://curl.haxx.se/bug/?i=1784
[7] = https://curl.haxx.se/bug/?i=1786
[8] = https://curl.haxx.se/bug/?i=1790
[9] = https://curl.haxx.se/bug/?i=1788
[10] = https://curl.haxx.se/bug/?i=1793
[11] = https://curl.haxx.se/bug/?i=1735
[12] = https://curl.haxx.se/bug/?i=1782
[13] = https://curl.haxx.se/bug/?i=1767
[14] = https://curl.haxx.se/bug/?i=1803
[15] = https://curl.haxx.se/bug/?i=1797
[16] = https://curl.haxx.se/bug/?i=1021
[17] = https://curl.haxx.se/bug/?i=1808
[18] = https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872502#10
[19] = https://curl.haxx.se/bug/?i=1799
[20] = https://curl.haxx.se/bug/?i=1815
[21] = https://curl.haxx.se/bug/?i=1751
[22] = https://curl.haxx.se/bug/?i=1810
[23] = https://curl.haxx.se/bug/?i=1818
[24] = https://curl.haxx.se/bug/?i=1832
[25] = https://curl.haxx.se/bug/?i=1828
[26] = https://curl.haxx.se/bug/?i=1823
[27] = https://curl.haxx.se/bug/?i=1829
[28] = https://curl.haxx.se/libcurl/c/curl_global_sslset.html
[29] = https://curl.haxx.se/bug/?i=1837
[30] = https://curl.haxx.se/mail/lib-2017-08/0120.html
[31] = https://curl.haxx.se/bug/?i=1842
[32] = https://curl.haxx.se/bug/?i=1839
[33] = https://curl.haxx.se/bug/?i=1858
[34] = https://curl.haxx.se/bug/?i=1859
[35] = https://curl.haxx.se/bug/?i=1846
[36] = https://curl.haxx.se/bug/?i=1866
[37] = https://curl.haxx.se/bug/?i=1861
[38] = https://curl.haxx.se/bug/?i=1868
[39] = https://curl.haxx.se/bug/?i=1865
[40] = https://curl.haxx.se/bug/?i=1853
[41] = https://curl.haxx.se/bug/?i=1870
[42] = https://curl.haxx.se/bug/?i=1874
[43] = https://curl.haxx.se/bug/?i=1877
[44] = https://curl.haxx.se/bug/?i=1878
[45] = https://curl.haxx.se/bug/?i=1887
[46] = https://curl.haxx.se/bug/?i=1687
[47] = https://curl.haxx.se/bug/?i=1880
[48] = https://curl.haxx.se/mail/lib-2017-09/0031.html
[49] = https://curl.haxx.se/bug/?i=1891
[50] = https://curl.haxx.se/bug/?i=1890
[51] = https://curl.haxx.se/bug/?i=1892
[52] = https://curl.haxx.se/bug/?i=1893
[53] = https://curl.haxx.se/bug/?i=1895
[54] = https://curl.haxx.se/bug/?i=1894
[55] = https://curl.haxx.se/bug/?i=1896
[56] = https://curl.haxx.se/bug/?i=1904
[57] = https://curl.haxx.se/bug/?i=1902
[58] = https://curl.haxx.se/bug/?i=1902
[59] = https://curl.haxx.se/bug/?i=1908
[60] = https://curl.haxx.se/bug/?i=1925
[61] = https://curl.haxx.se/bug/?i=1918
[62] = https://curl.haxx.se/bug/?i=1920
[63] = https://curl.haxx.se/bug/?i=1921
[64] = https://curl.haxx.se/bug/?i=1922
[65] = https://curl.haxx.se/bug/?i=1928
[66] = https://curl.haxx.se/bug/?i=1932
[67] = https://curl.haxx.se/docs/adv_20171004.html
[68] = https://curl.haxx.se/bug/?i=1917
[69] = https://curl.haxx.se/bug/?i=1919

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -255,7 +255,7 @@ echo "buildconf: libtoolize version $lt_version (ok)"
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# m4 check # m4 check
# #
m4=`(${M4:-m4} --version || ${M4:-gm4} --version) 2>/dev/null | head -n 1`; m4=`(${M4:-m4} --version 0<&- || ${M4:-gm4} --version) 2>/dev/null 0<&- | head -n 1`;
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'` m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
@ -306,7 +306,6 @@ for fname in .deps \
configure \ configure \
configurehelp.pm \ configurehelp.pm \
curl-config \ curl-config \
curlbuild.h \
depcomp \ depcomp \
libcares.pc \ libcares.pc \
libcurl.pc \ libcurl.pc \

View File

@ -1,38 +1,317 @@
@echo off @echo off
REM rem ***************************************************************************
REM rem * _ _ ____ _
REM This batch file must be used to set up a git tree to build on rem * Project ___| | | | _ \| |
REM systems where there is no autotools support (i.e. Microsoft). rem * / __| | | | |_) | |
REM rem * | (__| |_| | _ <| |___
REM This file is not included nor needed for curl's release rem * \___|\___/|_| \_\_____|
REM archives, neither for curl's daily snapshot archives. rem *
rem * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
rem *
rem * This software is licensed as described in the file COPYING, which
rem * you should have received as part of this distribution. The terms
rem * are also available at https://curl.haxx.se/docs/copyright.html.
rem *
rem * You may opt to use, copy, modify, merge, publish, distribute and/or sell
rem * copies of the Software, and permit persons to whom the Software is
rem * furnished to do so, under the terms of the COPYING file.
rem *
rem * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
rem * KIND, either express or implied.
rem *
rem ***************************************************************************
if exist GIT-INFO goto start_doing rem NOTES
ECHO ERROR: This file shall only be used with a curl git tree checkout. rem
goto end_all rem This batch file must be used to set up a git tree to build on systems where
:start_doing rem there is no autotools support (i.e. DOS and Windows).
rem
REM create tool_hugehelp.c :begin
if not exist src\tool_hugehelp.c.cvs goto end_hugehelp_c rem Set our variables
copy /Y src\tool_hugehelp.c.cvs src\tool_hugehelp.c if "%OS%" == "Windows_NT" setlocal
:end_hugehelp_c set MODE=GENERATE
REM create Makefile rem Switch to this batch file's directory
if not exist Makefile.dist goto end_makefile cd /d "%~0\.." 1>NUL 2>&1
copy /Y Makefile.dist Makefile
:end_makefile
REM create curlbuild.h rem Check we are running from a curl git repository
if not exist include\curl\curlbuild.h.dist goto end_curlbuild_h if not exist GIT-INFO goto norepo
copy /Y include\curl\curlbuild.h.dist include\curl\curlbuild.h
:end_curlbuild_h
REM setup c-ares git tree rem Detect programs. HAVE_<PROGNAME>
if not exist ares\buildconf.bat goto end_c_ares rem When not found the variable is set undefined. The undefined pattern
cd ares rem allows for statements like "if not defined HAVE_PERL (command)"
call buildconf.bat groff --version <NUL 1>NUL 2>&1
cd .. if errorlevel 1 (set HAVE_GROFF=) else (set HAVE_GROFF=Y)
:end_c_ares nroff --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_NROFF=) else (set HAVE_NROFF=Y)
perl --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_PERL=) else (set HAVE_PERL=Y)
gzip --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_GZIP=) else (set HAVE_GZIP=Y)
:end_all :parseArgs
if "%~1" == "" goto start
if /i "%~1" == "-clean" (
set MODE=CLEAN
) else if /i "%~1" == "-?" (
goto syntax
) else if /i "%~1" == "-h" (
goto syntax
) else if /i "%~1" == "-help" (
goto syntax
) else (
goto unknown
)
shift & goto parseArgs
:start
if "%MODE%" == "GENERATE" (
echo.
echo Generating prerequisite files
call :generate
if errorlevel 3 goto nogenhugehelp
if errorlevel 2 goto nogenmakefile
if errorlevel 1 goto warning
) else (
echo.
echo Removing prerequisite files
call :clean
if errorlevel 2 goto nocleanhugehelp
if errorlevel 1 goto nocleanmakefile
)
goto success
rem Main generate function.
rem
rem Returns:
rem
rem 0 - success
rem 1 - success with simplified tool_hugehelp.c
rem 2 - failed to generate Makefile
rem 3 - failed to generate tool_hugehelp.c
rem
:generate
if "%OS%" == "Windows_NT" setlocal
set BASIC_HUGEHELP=0
rem Create Makefile
echo * %CD%\Makefile
if exist Makefile.dist (
copy /Y Makefile.dist Makefile 1>NUL 2>&1
if errorlevel 1 (
if "%OS%" == "Windows_NT" endlocal
exit /B 2
)
)
rem Create tool_hugehelp.c
echo * %CD%\src\tool_hugehelp.c
call :genHugeHelp
if errorlevel 2 (
if "%OS%" == "Windows_NT" endlocal
exit /B 3
)
if errorlevel 1 (
set BASIC_HUGEHELP=1
)
cmd /c exit 0
rem Setup c-ares git tree
if exist ares\buildconf.bat (
echo.
echo Configuring c-ares build environment
cd ares
call buildconf.bat
cd ..
)
if "%BASIC_HUGEHELP%" == "1" (
if "%OS%" == "Windows_NT" endlocal
exit /B 1
)
if "%OS%" == "Windows_NT" endlocal
exit /B 0
rem Main clean function.
rem
rem Returns:
rem
rem 0 - success
rem 1 - failed to clean Makefile
rem 2 - failed to clean tool_hugehelp.c
rem
:clean
rem Remove Makefile
echo * %CD%\Makefile
if exist Makefile (
del Makefile 2>NUL
if exist Makefile (
exit /B 1
)
)
rem Remove tool_hugehelp.c
echo * %CD%\src\tool_hugehelp.c
if exist src\tool_hugehelp.c (
del src\tool_hugehelp.c 2>NUL
if exist src\tool_hugehelp.c (
exit /B 2
)
)
exit /B
rem Function to generate src\tool_hugehelp.c
rem
rem Returns:
rem
rem 0 - full tool_hugehelp.c generated
rem 1 - simplified tool_hugehelp.c
rem 2 - failure
rem
:genHugeHelp
if "%OS%" == "Windows_NT" setlocal
set LC_ALL=C
set ROFFCMD=
set BASIC=1
if defined HAVE_PERL (
if defined HAVE_GROFF (
set ROFFCMD=groff -mtty-char -Tascii -P-c -man
) else if defined HAVE_NROFF (
set ROFFCMD=nroff -c -Tascii -man
)
)
if defined ROFFCMD (
echo #include "tool_setup.h"> src\tool_hugehelp.c
echo #include "tool_hugehelp.h">> src\tool_hugehelp.c
if defined HAVE_GZIP (
echo #ifndef HAVE_LIBZ>> src\tool_hugehelp.c
)
%ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl docs\MANUAL >> src\tool_hugehelp.c
if defined HAVE_GZIP (
echo #else>> src\tool_hugehelp.c
%ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl -c docs\MANUAL >> src\tool_hugehelp.c
echo #endif /^* HAVE_LIBZ ^*/>> src\tool_hugehelp.c
)
set BASIC=0
) else (
if exist src\tool_hugehelp.c.cvs (
copy /Y src\tool_hugehelp.c.cvs src\tool_hugehelp.c 1>NUL 2>&1
) else (
echo #include "tool_setup.h"> src\tool_hugehelp.c
echo #include "tool_hugehelp.hd">> src\tool_hugehelp.c
echo.>> src\tool_hugehelp.c
echo void hugehelp(void^)>> src\tool_hugehelp.c
echo {>> src\tool_hugehelp.c
echo #ifdef USE_MANUAL>> src\tool_hugehelp.c
echo fputs("Built-in manual not included\n", stdout^);>> src\tool_hugehelp.c
echo #endif>> src\tool_hugehelp.c
echo }>> src\tool_hugehelp.c
)
)
findstr "/C:void hugehelp(void)" src\tool_hugehelp.c 1>NUL 2>&1
if errorlevel 1 (
if "%OS%" == "Windows_NT" endlocal
exit /B 2
)
if "%BASIC%" == "1" (
if "%OS%" == "Windows_NT" endlocal
exit /B 1
)
if "%OS%" == "Windows_NT" endlocal
exit /B 0
rem Function to clean-up local variables under DOS, Windows 3.x and
rem Windows 9x as setlocal isn't available until Windows NT
rem
:dosCleanup
set MODE=
set HAVE_GROFF=
set HAVE_NROFF=
set HAVE_PERL=
set HAVE_GZIP=
set BASIC_HUGEHELP=
set LC_ALL
set ROFFCMD=
set BASIC=
exit /B
:syntax
rem Display the help
echo.
echo Usage: buildconf [-clean]
echo.
echo -clean - Removes the files
goto error
:unknown
echo.
echo Error: Unknown argument '%1'
goto error
:norepo
echo.
echo Error: This batch file should only be used with a curl git repository
goto error
:nogenmakefile
echo.
echo Error: Unable to generate Makefile
goto error
:nogenhugehelp
echo.
echo Error: Unable to generate src\tool_hugehelp.c
goto error
:nocleanmakefile
echo.
echo Error: Unable to clean Makefile
goto error
:nocleanhugehelp
echo.
echo Error: Unable to clean src\tool_hugehelp.c
goto error
:warning
echo.
echo Warning: The curl manual could not be integrated in the source. This means when
echo you build curl the manual will not be available (curl --man^). Integration of
echo the manual is not required and a summary of the options will still be available
echo (curl --help^). To integrate the manual your PATH is required to have
echo groff/nroff, perl and optionally gzip for compression.
goto success
:error
if "%OS%" == "Windows_NT" (
endlocal
) else (
call :dosCleanup
)
exit /B 1
:success
if "%OS%" == "Windows_NT" (
endlocal
) else (
call :dosCleanup
)
exit /B 0

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is

View File

@ -9,19 +9,30 @@ BUGS
1. Bugs 1. Bugs
1.1 There are still bugs 1.1 There are still bugs
1.2 Where to report 1.2 Where to report
1.3 What to report 1.3 Security bugs
1.4 libcurl problems 1.4 What to report
1.5 Who will fix the problems 1.5 libcurl problems
1.6 How to get a stack trace 1.6 Who will fix the problems
1.7 Bugs in libcurl bindings 1.7 How to get a stack trace
1.8 Bugs in libcurl bindings
1.9 Bugs in old versions
2. Bug fixing procedure
2.1 What happens on first filing
2.2 First response
2.3 Not reproducible
2.4 Unresponsive
2.5 Lack of time/interest
2.6 KNOWN_BUGS
2.7 TODO
2.8 Closing off stalled bugs
============================================================================== ==============================================================================
1.1 There are still bugs 1.1 There are still bugs
Curl and libcurl have grown substantially since the beginning. At the time Curl and libcurl keep being developed. Adding features and changing code
of writing (January 2013), there are about 83,000 lines of source code, and means that bugs will sneak in, no matter how hard we try not to.
by the time you read this it has probably grown even more.
Of course there are lots of bugs left. And lots of misfeatures. Of course there are lots of bugs left. And lots of misfeatures.
@ -35,14 +46,31 @@ BUGS
have a go at a solution. You can optionally also post your bug/problem at have a go at a solution. You can optionally also post your bug/problem at
curl's bug tracking system over at curl's bug tracking system over at
https://github.com/bagder/curl/issues https://github.com/curl/curl/issues
Please read the rest of this document below first before doing that! Please read the rest of this document below first before doing that!
If you feel you need to ask around first, find a suitable mailing list and If you feel you need to ask around first, find a suitable mailing list and
post there. The lists are available on http://curl.haxx.se/mail/ post there. The lists are available on https://curl.haxx.se/mail/
1.3 What to report 1.3 Security bugs
If you find a bug or problem in curl or libcurl that you think has a
security impact, for example a bug that can put users in danger or make them
vulnerable if the bug becomes public knowledge, then please report that bug
using our security development process.
Security related bugs or bugs that are suspected to have a security impact,
should be reported by email to curl-security@haxx.se so that they first can
be dealt with away from the public to minimize the harm and impact it will
have on existing users out there who might be using the vulernable versions.
The curl project's process for handling security related issues is
documented here:
https://curl.haxx.se/dev/security.html
1.4 What to report
When reporting a bug, you should include all information that will help us When reporting a bug, you should include all information that will help us
understand what's wrong, what you expected to happen and how to repeat the understand what's wrong, what you expected to happen and how to repeat the
@ -74,9 +102,7 @@ BUGS
The address and how to subscribe to the mailing lists are detailed in the The address and how to subscribe to the mailing lists are detailed in the
MANUAL file. MANUAL file.
1.4 libcurl problems 1.5 libcurl problems
First, post all libcurl problems on the curl-library mailing list.
When you've written your own application with libcurl to perform transfers, When you've written your own application with libcurl to perform transfers,
it is even more important to be specific and detailed when reporting bugs. it is even more important to be specific and detailed when reporting bugs.
@ -96,7 +122,7 @@ BUGS
valgrind or similar before you post memory-related or "crashing" problems to valgrind or similar before you post memory-related or "crashing" problems to
us. us.
1.5 Who will fix the problems 1.6 Who will fix the problems
If the problems or bugs you describe are considered to be bugs, we want to If the problems or bugs you describe are considered to be bugs, we want to
have the problems fixed. have the problems fixed.
@ -115,7 +141,7 @@ BUGS
We get reports from many people every month and each report can take a We get reports from many people every month and each report can take a
considerable amount of time to really go to the bottom with. considerable amount of time to really go to the bottom with.
1.6 How to get a stack trace 1.7 How to get a stack trace
First, you must make sure that you compile all sources with -g and that you First, you must make sure that you compile all sources with -g and that you
don't 'strip' the final executable. Try to avoid optimizing the code as don't 'strip' the final executable. Try to avoid optimizing the code as
@ -135,7 +161,7 @@ BUGS
crashed. Include the stack trace with your detailed bug report. It'll help a crashed. Include the stack trace with your detailed bug report. It'll help a
lot. lot.
1.7 Bugs in libcurl bindings 1.8 Bugs in libcurl bindings
There will of course pop up bugs in libcurl bindings. You should then There will of course pop up bugs in libcurl bindings. You should then
primarily approach the team that works on that particular binding and see primarily approach the team that works on that particular binding and see
@ -144,3 +170,128 @@ BUGS
If you suspect that the problem exists in the underlying libcurl, then If you suspect that the problem exists in the underlying libcurl, then
please convert your program over to plain C and follow the steps outlined please convert your program over to plain C and follow the steps outlined
above. above.
1.9 Bugs in old versions
The curl project typically releases new versions every other month, and we
fix several hundred bugs per year. For a huge table of releases, number of
bug fixes and more, see: https://curl.haxx.se/docs/releases.html
The developers in the curl project do not have bandwidth or energy enough to
maintain several branches or to spend much time on hunting down problems in
old versions when chances are we already fixed them or at least that they've
changed nature and appearance in later versions.
When you experience a problem and want to report it, you really SHOULD
include the version number of the curl you're using when you experience the
issue. If that version number shows us that you're using an out-of-date
curl, you should also try out a modern curl version to see if the problem
persists or how/if it has changed in apperance.
Even if you cannot immediately upgrade your application/system to run the
latest curl version, you can most often at least run a test version or
experimental build or similar, to get this confirmed or not.
At times people insist that they cannot upgrade to a modern curl version,
but instead they "just want the bug fixed". That's fine, just don't count on
us spending many cycles on trying to identify which single commit, if that's
even possible, that at some point in the past fixed the problem you're now
experiencing.
Security wise, it is almost always a bad idea to lag behind the current curl
versions by a lot. We keeping discovering and reporting security problems
over time see you can see in this table:
https://curl.haxx.se/docs/vulnerabilities.html
2. Bug fixing procedure
2.1 What happens on first filing
When a new issue is posted in the issue tracker or on the mailing list, the
team of developers first need to see the report. Maybe they took the day
off, maybe they're off in the woods hunting. Have patience. Allow at least a
few days before expecting someone to have responded.
In the issue tracker you can expect that some labels will be set on the
issue to help categorize it.
2.2 First response
If your issue/bug report wasn't perfect at once (and few are), chances are
that someone will ask follow-up questions. Which version did you use? Which
options did you use? How often does the problem occur? How can we reproduce
this problem? Which protocols does it involve? Or perhaps much more specific
and deep diving questions. It all depends on your specific issue.
You should then respond to these follow-up questions and provide more info
about the problem, so that we can help you figure it out. Or maybe you can
help us figure it out. An active back-and-forth communication is important
and the key for finding a cure and landing a fix.
2.3 Not reproducible
For problems that we can't reproduce and can't understand even after having
gotten all the info we need and having studied the source code over again,
are really hard to solve so then we may require further work from you who
actually see or experience the problem.
2.4 Unresponsive
If the problem haven't been understood or reproduced, and there's nobody
responding to follow-up questions or questions asking for clarifications or
for discussing possible ways to move forward with the task, we take that as
a strong suggestion that the bug is not important.
Unimportant issues will be closed as inactive sooner or later as they can't
be fixed. The inactivity period (waiting for responses) should not be
shorter than two weeks but may extend months.
2.5 Lack of time/interest
Bugs that are filed and are understood can unfortunately end up in the
"nobody cares enough about it to work on it" category. Such bugs are
perfectly valid problems that *should* get fixed but apparently aren't. We
try to mark such bugs as "KNOWN_BUGS material" after a time of inactivity
and if no activity is noticed after yet some time those bugs are added to
KNOWN_BUGS and are closed in the issue tracker.
2.6 KNOWN_BUGS
This is a list of known bugs. Bugs we know exist and that have been pointed
out but that haven't yet been fixed. The reasons for why they haven't been
fixed can involve anything really, but the primary reason is that nobody has
considered these problems to be important enough to spend the necessary time
and effort to have them fixed.
The KNOWN_BUGS are always up for grabs and we will always love the ones who
bring one of them back to live and offers solutions to them.
The KNOWN_BUGS document has a sibling document known as TODO.
2.7 TODO
Issues that are filed or reported that aren't really bugs but more missing
features or ideas for future improvements and so on are marked as
'enhancement' or 'feature-request' and will be added to the TODO document
instead and the issue is closed. We don't keep TODO items in the issue
tracker.
The TODO document is full of ideas and suggestions of what we can add or fix
one day. You're always encouraged and free to grab one of those items and
take up a discussion with the curl development team on how that could be
implemented or provided in the project so that you can work on ticking it
odd that document.
If the issue is rather a bug and not a missing feature or functionality, it
is listed in KNOWN_BUGS instead.
2.8 Closing off stalled bugs
The issue and pull request trackers on https://github.com/curl/curl will
only hold "active" entries (using a non-precise definition of what active
actually is, but they're at least not completely dead). Those that are
abandonded or in other ways dormant will be closed and sometimes added to
TODO and KNOWN_BUGS instead.
This way, we only have "active" issues open on github. Irrelevant issues and
pull requests will not distract developes or casual visitors.

View File

@ -21,6 +21,7 @@ FAQ
1.12 I have a problem who can I chat with? 1.12 I have a problem who can I chat with?
1.13 curl's ECCN number? 1.13 curl's ECCN number?
1.14 How do I submit my patch? 1.14 How do I submit my patch?
1.15 How do I port libcurl to my OS?
2. Install Related Problems 2. Install Related Problems
2.1 configure doesn't find OpenSSL even when it is installed 2.1 configure doesn't find OpenSSL even when it is installed
@ -79,7 +80,7 @@ FAQ
4.16 My HTTP POST or PUT requests are slow! 4.16 My HTTP POST or PUT requests are slow!
4.17 Non-functional connect timeouts on Windows 4.17 Non-functional connect timeouts on Windows
4.18 file:// URLs containing drive letters (Windows, NetWare) 4.18 file:// URLs containing drive letters (Windows, NetWare)
4.19 Why doesn't cURL return an error when the network cable is unplugged? 4.19 Why doesn't curl return an error when the network cable is unplugged?
4.20 curl doesn't return error for HTTP non-200 responses! 4.20 curl doesn't return error for HTTP non-200 responses!
4.21 Why is there a HTTP/1.1 in my HTTP/2 request? 4.21 Why is there a HTTP/1.1 in my HTTP/2 request?
@ -116,6 +117,7 @@ FAQ
7.1 What is PHP/CURL? 7.1 What is PHP/CURL?
7.2 Who wrote PHP/CURL? 7.2 Who wrote PHP/CURL?
7.3 Can I perform multiple requests using the same handle? 7.3 Can I perform multiple requests using the same handle?
7.4 Does PHP/CURL have dependencies?
============================================================================== ==============================================================================
@ -160,7 +162,7 @@ FAQ
We pronounce curl with an initial k sound. It rhymes with words like girl We pronounce curl with an initial k sound. It rhymes with words like girl
and earl. This is a short WAV file to help you: and earl. This is a short WAV file to help you:
http://media.merriam-webster.com/soundc11/c/curl0001.wav https://media.merriam-webster.com/soundc11/c/curl0001.wav
There are numerous sub-projects and related projects that also use the word There are numerous sub-projects and related projects that also use the word
curl in the project names in various combinations, but you should take curl in the project names in various combinations, but you should take
@ -213,20 +215,22 @@ FAQ
another tool that uses libcurl. another tool that uses libcurl.
We do not add things to curl that other small and available tools already do We do not add things to curl that other small and available tools already do
very fine at the side. Curl's output is fine to pipe into another program or very well at the side. Curl's output can be piped into another program or
redirect to another file for the next program to interpret. redirected to another file for the next program to interpret.
We focus on protocol related issues and improvements. If you wanna do more We focus on protocol related issues and improvements. If you wanna do more
magic with the supported protocols than curl currently does, chances are big magic with the supported protocols than curl currently does, chances are good
we will agree. If you wanna add more protocols, we may very well agree. we will agree. If you wanna add more protocols, we may very well agree.
If you want someone else to make all the work while you wait for us to If you want someone else to do all the work while you wait for us to
implement it for you, that is not a very friendly attitude. We spend a implement it for you, that is not a very friendly attitude. We spend a
considerable time already on maintaining and developing curl. In order to considerable time already on maintaining and developing curl. In order to
get more out of us, you should consider trading in some of your time and get more out of us, you should consider trading in some of your time and
efforts in return. effort in return. Simply go to the GitHub repo which resides at
https://github.com/curl/curl, fork the project, and create pull requests
with your proposed changes.
If you write the code, chances are bigger that it will get into curl faster. If you write the code, chances are better that it will get into curl faster.
1.5 Who makes curl? 1.5 Who makes curl?
@ -234,7 +238,7 @@ FAQ
project leader and main developer, but other persons' submissions are project leader and main developer, but other persons' submissions are
important and crucial. Anyone can contribute and post their changes and important and crucial. Anyone can contribute and post their changes and
improvements and have them inserted in the main sources (of course on the improvements and have them inserted in the main sources (of course on the
condition that developers agree on that the fixes are good). condition that developers agree that the fixes are good).
The full list of all contributors is found in the docs/THANKS file. The full list of all contributors is found in the docs/THANKS file.
@ -243,23 +247,24 @@ FAQ
1.6 What do you get for making curl? 1.6 What do you get for making curl?
Project cURL is entirely free and open. No person gets paid for developing Project cURL is entirely free and open. No person gets paid for developing
curl on full time. We do this voluntarily, mostly on spare time. curl full time. We do this voluntarily, mostly in our spare time.
Occasionally companies pay individual developers to work on curl, but that's Occasionally companies pay individual developers to work on curl, but that's
up to each company and developer. It is not controlled by nor supervised in up to each company and developer. This is not controlled by nor supervised in
any way by the project. any way by the project.
We still get help from companies. Haxx provides web site, bandwidth, mailing We still get help from companies. Haxx provides web site, bandwidth, mailing
lists etc, sourceforge.net hosts project services we take advantage from, lists etc, sourceforge.net hosts project services we take advantage from,
like the bug tracker and github hosts the primary git repository. Also like the bug tracker, and GitHub hosts the primary git repository at
again, some companies have sponsored certain parts of the development in the https://github.com/curl/curl. Also again, some companies have sponsored
past and I hope some will continue to do so in the future. certain parts of the development in the past and I hope some will continue to
do so in the future.
If you want to support our project, consider a donation or a banner-program If you want to support our project, consider a donation or a banner-program
or even better: by helping us coding, documenting, testing etc. or even better: by helping us with coding, documenting or testing etc.
1.7 What about CURL from curl.com? 1.7 What about CURL from curl.com?
During the summer 2001, curl.com was busy advertising their client-side During the summer of 2001, curl.com was busy advertising their client-side
programming language for the web, named CURL. programming language for the web, named CURL.
We are in no way associated with curl.com or their CURL programming We are in no way associated with curl.com or their CURL programming
@ -272,16 +277,16 @@ FAQ
We recognize that we will be living in parallel with curl.com and wish them We recognize that we will be living in parallel with curl.com and wish them
every success. every success.
1.8 I have a problem who do I mail? 1.8 I have a problem whom do I mail?
Please do not mail any single individual unless you really need to. Keep Please do not mail any single individual unless you really need to. Keep
curl-related questions on a suitable mailing list. All available mailing curl-related questions on a suitable mailing list. All available mailing
lists are listed in the MANUAL document and online at lists are listed in the MANUAL document and online at
http://curl.haxx.se/mail/ https://curl.haxx.se/mail/
Keeping curl-related questions and discussions on mailing lists allows Keeping curl-related questions and discussions on mailing lists allows
others to join in and help, to share their ideas, contribute their others to join in and help, to share their ideas, to contribute their
suggestions and spread their wisdom. Keeping discussions on public mailing suggestions and to spread their wisdom. Keeping discussions on public mailing
lists also allows for others to learn from this (both current and future lists also allows for others to learn from this (both current and future
users thanks to the web based archives of the mailing lists), thus saving us users thanks to the web based archives of the mailing lists), thus saving us
from having to repeat ourselves even more. Thanks for respecting this. from having to repeat ourselves even more. Thanks for respecting this.
@ -298,7 +303,7 @@ FAQ
your curl-related problems. your curl-related problems.
We list available alternatives on the curl web site: We list available alternatives on the curl web site:
http://curl.haxx.se/support.html https://curl.haxx.se/support.html
1.10 How many are using curl? 1.10 How many are using curl?
@ -315,13 +320,13 @@ FAQ
In May 2012 Daniel did a counting game and came up with a number that may In May 2012 Daniel did a counting game and came up with a number that may
be completely wrong or somewhat accurate. Over 500 million! be completely wrong or somewhat accurate. Over 500 million!
See http://daniel.haxx.se/blog/2012/05/16/300m-users/ See https://daniel.haxx.se/blog/2012/05/16/300m-users/
1.11 Why don't you update ca-bundle.crt 1.11 Why don't you update ca-bundle.crt
The ca cert bundle that used to shipped with curl was very outdated and must The ca cert bundle that used to be shipped with curl was very outdated and
be replaced with an up-to-date version by anyone who wants to verify must be replaced with an up-to-date version by anyone who wants to verify
peers. It is no longer provided by curl. The last curl release ever that peers. It is no longer provided by curl. The last curl release that ever
shipped a ca cert bundle was curl 7.18.0. shipped a ca cert bundle was curl 7.18.0.
In the cURL project we've decided not to attempt to keep this file updated In the cURL project we've decided not to attempt to keep this file updated
@ -337,12 +342,12 @@ FAQ
If you want the most recent collection of ca certs that Mozilla Firefox If you want the most recent collection of ca certs that Mozilla Firefox
uses, we recommend that you extract the collection yourself from Mozilla uses, we recommend that you extract the collection yourself from Mozilla
Firefox (by running 'make ca-bundle), or by using our online service setup Firefox (by running 'make ca-bundle), or by using our online service setup
for this purpose: http://curl.haxx.se/docs/caextract.html for this purpose: https://curl.haxx.se/docs/caextract.html
1.12 I have a problem who can I chat with? 1.12 I have a problem who can I chat with?
There's a bunch of friendly people hanging out in the #curl channel on the There's a bunch of friendly people hanging out in the #curl channel on the
IRC network irc.freenode.net. If you're polite and nice, chances are big IRC network irc.freenode.net. If you're polite and nice, chances are good
that you can get -- or provide -- help instantly. that you can get -- or provide -- help instantly.
1.13 curl's ECCN number? 1.13 curl's ECCN number?
@ -351,16 +356,18 @@ FAQ
cryptography. When doing so, the Export Control Classification Number (ECCN) cryptography. When doing so, the Export Control Classification Number (ECCN)
is used to identify the level of export control etc. is used to identify the level of export control etc.
ASF gives a good explanation at http://www.apache.org/dev/crypto.html Apache Software Foundation gives a good explanation of ECCNs at
https://www.apache.org/dev/crypto.html
We believe curl's number might be ECCN 5D002, another possibility is We believe curl's number might be ECCN 5D002, another possibility is
5D992. It seems necessary to write them, asking to confirm. 5D992. It seems necessary to write them (the authority that administers ECCN
numbers), asking to confirm.
Comprehensible explanations of the meaning of such numbers and how to Comprehensible explanations of the meaning of such numbers and how to obtain
obtain them (resp.) are here them (resp.) are here
http://www.bis.doc.gov/licensing/exportingbasics.htm https://www.bis.doc.gov/licensing/exportingbasics.htm
http://www.bis.doc.gov/licensing/do_i_needaneccn.html https://www.bis.doc.gov/licensing/do_i_needaneccn.html
An incomprehensible description of the two numbers above is here An incomprehensible description of the two numbers above is here
http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf
@ -380,6 +387,19 @@ FAQ
Lots of more details are found in the CONTRIBUTE and INTERNALS docs. Lots of more details are found in the CONTRIBUTE and INTERNALS docs.
1.15 How do I port libcurl to my OS?
Here's a rough step-by-step:
1. copy a suitable lib/config-*.h file as a start to lib/config-[youros].h
2. edit lib/config-[youros].h to match your OS and setup
3. edit lib/curl_setup.h to include config-[youros].h when your OS is
detected by the preprocessor, in the style others already exist
4. compile lib/*.c and make them into a library
2. Install Related Problems 2. Install Related Problems
@ -410,7 +430,7 @@ FAQ
2.1.2 only the libssl lib is missing 2.1.2 only the libssl lib is missing
If all include files and the libcrypto lib is present, with only the If all include files and the libcrypto lib is present, with only the
libssl being missing according to configure, this is mostly likely because libssl being missing according to configure, this is most likely because
a few functions are left out from the libssl. a few functions are left out from the libssl.
If the function names missing include RSA or RSAREF you can be certain If the function names missing include RSA or RSAREF you can be certain
@ -430,7 +450,7 @@ FAQ
GnuTLS, yassl, NSS, PolarSSL, axTLS, Secure Transport (native iOS/OS X), GnuTLS, yassl, NSS, PolarSSL, axTLS, Secure Transport (native iOS/OS X),
WinSSL (native Windows) or GSKit (native IBM i). They all have their pros WinSSL (native Windows) or GSKit (native IBM i). They all have their pros
and cons, and we try to maintain a comparison of them here: and cons, and we try to maintain a comparison of them here:
http://curl.haxx.se/docs/ssl-compared.html https://curl.haxx.se/docs/ssl-compared.html
2.3 Where can I find a copy of LIBEAY32.DLL? 2.3 Where can I find a copy of LIBEAY32.DLL?
@ -474,11 +494,14 @@ FAQ
3.3 Why doesn't my posting using -F work? 3.3 Why doesn't my posting using -F work?
You can't simply use -F or -d at your choice. The web server that will You can't arbitrarily use -F or -d, the choice between -F or -d depends on the
receive your post expects one of the formats. If the form you're trying to HTTP operation you need curl to do and what the web server that will receive
submit uses the type 'multipart/form-data', then and only then you must use your post expects.
the -F type. In all the most common cases, you should use -d which then
causes a posting with the type 'application/x-www-form-urlencoded'. If the form you're trying to submit uses the type 'multipart/form-data', then
and only then you must use the -F type. In all the most common cases, you
should use -d which then causes a posting with the type
'application/x-www-form-urlencoded'.
This is described in some detail in the MANUAL and TheArtOfHttpScripting This is described in some detail in the MANUAL and TheArtOfHttpScripting
documents, and if you don't understand it the first time, read it again documents, and if you don't understand it the first time, read it again
@ -542,7 +565,7 @@ FAQ
Find out more about which languages that support curl directly, and how to Find out more about which languages that support curl directly, and how to
install and use them, in the libcurl section of the curl web site: install and use them, in the libcurl section of the curl web site:
http://curl.haxx.se/libcurl/ https://curl.haxx.se/libcurl/
All the various bindings to libcurl are made by other projects and people, All the various bindings to libcurl are made by other projects and people,
outside of the cURL project. The cURL project itself only produces libcurl outside of the cURL project. The cURL project itself only produces libcurl
@ -553,7 +576,7 @@ FAQ
In October 2009, there were interfaces available for the following In October 2009, there were interfaces available for the following
languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria, languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET, Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET,
Object-Pascal, O'Caml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby, Object-Pascal, OCaml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby,
Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro, Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro,
Q, wxwidgets and XBLite. By the time you read this, additional ones may have Q, wxwidgets and XBLite. By the time you read this, additional ones may have
appeared! appeared!
@ -565,7 +588,7 @@ FAQ
XML-RPC are all such ones. You can use -X to set custom requests and -H to XML-RPC are all such ones. You can use -X to set custom requests and -H to
set custom headers (or replace internally generated ones). set custom headers (or replace internally generated ones).
Using libcurl is of course just as fine and you'd just use the proper Using libcurl is of course just as good and you'd just use the proper
library options to do the same. library options to do the same.
3.11 How do I POST with a different Content-Type? 3.11 How do I POST with a different Content-Type?
@ -585,7 +608,7 @@ FAQ
There is one exception to this rule, and that is if you can "tunnel through" There is one exception to this rule, and that is if you can "tunnel through"
the given HTTP proxy. Proxy tunneling is enabled with a special option (-p) the given HTTP proxy. Proxy tunneling is enabled with a special option (-p)
and is generally not available as proxy admins usually disable tunneling to and is generally not available as proxy admins usually disable tunneling to
other ports than 443 (which is used for HTTPS access through proxies). ports other than 443 (which is used for HTTPS access through proxies).
3.13 Why does my single/double quotes fail? 3.13 Why does my single/double quotes fail?
@ -604,7 +627,7 @@ FAQ
Windows/DOS prompts I believe you're forced to use double (") quotes. Windows/DOS prompts I believe you're forced to use double (") quotes.
Please study the documentation for your particular environment. Examples in Please study the documentation for your particular environment. Examples in
the curl docs will use a mix of both these ones as shown above. You must the curl docs will use a mix of both of these as shown above. You must
adjust them to work in your environment. adjust them to work in your environment.
Remember that curl works and runs on more operating systems than most single Remember that curl works and runs on more operating systems than most single
@ -639,7 +662,7 @@ FAQ
No. curl itself has no code that performs recursive operations, such as No. curl itself has no code that performs recursive operations, such as
those performed by wget and similar tools. those performed by wget and similar tools.
There exist wrapper scripts with that functionality (for example the There exists wrapper scripts with that functionality (for example the
curlmirror perl script), and you can write programs based on libcurl to do curlmirror perl script), and you can write programs based on libcurl to do
it, but the command line tool curl itself cannot. it, but the command line tool curl itself cannot.
@ -650,9 +673,9 @@ FAQ
CLIENT CERTIFICATE CLIENT CERTIFICATE
The server you communicate may require that you can provide this in order to The server you communicate with may require that you can provide this in
prove that you actually are who you claim to be. If the server doesn't order to prove that you actually are who you claim to be. If the server
require this, you don't need a client certificate. doesn't require this, you don't need a client certificate.
A client certificate is always used together with a private key, and the A client certificate is always used together with a private key, and the
private key has a pass phrase that protects it. private key has a pass phrase that protects it.
@ -675,7 +698,7 @@ FAQ
certificate. Server certificate verification is enabled by default in curl certificate. Server certificate verification is enabled by default in curl
and libcurl and is often the reason for problems as explained in FAQ entry and libcurl and is often the reason for problems as explained in FAQ entry
4.12 and the SSLCERTS document 4.12 and the SSLCERTS document
(http://curl.haxx.se/docs/sslcerts.html). Server certificates that are (https://curl.haxx.se/docs/sslcerts.html). Server certificates that are
"self-signed" or otherwise signed by a CA that you do not have a CA cert "self-signed" or otherwise signed by a CA that you do not have a CA cert
for, cannot be verified. If the verification during a connect fails, you are for, cannot be verified. If the verification during a connect fails, you are
refused access. You then need to explicitly disable the verification to refused access. You then need to explicitly disable the verification to
@ -813,14 +836,14 @@ FAQ
4.3 How can I use {, }, [ or ] to specify multiple URLs? 4.3 How can I use {, }, [ or ] to specify multiple URLs?
Because those letters have a special meaning to the shell, and to be used in Because those letters have a special meaning to the shell, to be used in
a URL specified to curl you must quote them. a URL specified to curl you must quote them.
An example that downloads two URLs (sequentially) would do: An example that downloads two URLs (sequentially) would be:
curl '{curl,www}.haxx.se' curl '{curl,www}.haxx.se'
To be able to use those letters as actual parts of the URL (without using To be able to use those characters as actual parts of the URL (without using
them for the curl URL "globbing" system), use the -g/--globoff option: them for the curl URL "globbing" system), use the -g/--globoff option:
curl -g 'www.site.com/weirdname[].html' curl -g 'www.site.com/weirdname[].html'
@ -922,8 +945,8 @@ FAQ
4.9 Curl can't authenticate to the server that requires NTLM? 4.9 Curl can't authenticate to the server that requires NTLM?
NTLM support requires OpenSSL, GnuTLS, NSS, Secure Transport, or Microsoft NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or
Windows libraries at build-time to provide this functionality. Microsoft Windows libraries at build-time to provide this functionality.
NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
should not use such ones. should not use such ones.
@ -966,18 +989,20 @@ FAQ
this check. this check.
Details are also in the SSLCERTS file in the release archives, found online Details are also in the SSLCERTS file in the release archives, found online
here: http://curl.haxx.se/docs/sslcerts.html here: https://curl.haxx.se/docs/sslcerts.html
4.13 Why is curl -R on Windows one hour off? 4.13 Why is curl -R on Windows one hour off?
During daylight savings time, when -R is used, curl will set a time that Since curl 7.53.0 this issue should be fixed as long as curl was built with
appears one hour off. This happens due to a flaw in how Windows stores and any modern compiler that allows for a 64-bit curl_off_t type. For older
uses file modification times and it is not easily worked around. For details compilers or prior curl versions it may set a time that appears one hour off.
on this problem, read this: http://www.codeproject.com/datetime/dstbugs.asp This happens due to a flaw in how Windows stores and uses file modification
times and it is not easily worked around. For more details read this:
http://www.codeproject.com/datetime/dstbugs.asp
4.14 Redirects work in browser but not with curl! 4.14 Redirects work in browser but not with curl!
curl supports HTTP redirects fine (see item 3.8). Browsers generally support curl supports HTTP redirects well (see item 3.8). Browsers generally support
at least two other ways to perform redirects that curl does not: at least two other ways to perform redirects that curl does not:
Meta tags. You can write a HTML tag that will cause the browser to redirect Meta tags. You can write a HTML tag that will cause the browser to redirect
@ -1001,7 +1026,7 @@ FAQ
To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one
of its related flavours). This is the most common method, and the one of its related flavours). This is the most common method, and the one
mandated by RFC4217. This kind of connection then of course uses the mandated by RFC4217. This kind of connection will then of course use the
standard FTP port 21 by default. standard FTP port 21 by default.
4.16 My HTTP POST or PUT requests are slow! 4.16 My HTTP POST or PUT requests are slow!
@ -1009,7 +1034,7 @@ FAQ
libcurl makes all POST and PUT requests (except for POST requests with a libcurl makes all POST and PUT requests (except for POST requests with a
very tiny request body) use the "Expect: 100-continue" header. This header very tiny request body) use the "Expect: 100-continue" header. This header
allows the server to deny the operation early so that libcurl can bail out allows the server to deny the operation early so that libcurl can bail out
already before having to send any data. This is useful in authentication before having to send any data. This is useful in authentication
cases and others. cases and others.
However, many servers don't implement the Expect: stuff properly and if the However, many servers don't implement the Expect: stuff properly and if the
@ -1028,7 +1053,7 @@ FAQ
timeout is set. timeout is set.
See option TcpMaxConnectRetransmissions on this page: See option TcpMaxConnectRetransmissions on this page:
http://support.microsoft.com/?scid=kb%3Ben-us%3B175523&x=6&y=7 https://support.microsoft.com/en-us/kb/175523/en-us
Also, even on non-Windows systems there may run a firewall or anti-virus Also, even on non-Windows systems there may run a firewall or anti-virus
software or similar that accepts the connection but does not actually do software or similar that accepts the connection but does not actually do
@ -1037,18 +1062,18 @@ FAQ
4.18 file:// URLs containing drive letters (Windows, NetWare) 4.18 file:// URLs containing drive letters (Windows, NetWare)
When using cURL to try to download a local file, one might use a URL When using curl to try to download a local file, one might use a URL
in this format: in this format:
file://D:/blah.txt file://D:/blah.txt
You'll find that even if D:\blah.txt does exist, cURL returns a 'file You'll find that even if D:\blah.txt does exist, curl returns a 'file
not found' error. not found' error.
According to RFC 1738 (http://www.faqs.org/rfcs/rfc1738.html), According to RFC 1738 (https://www.ietf.org/rfc/rfc1738.txt),
file:// URLs must contain a host component, but it is ignored by file:// URLs must contain a host component, but it is ignored by
most implementations. In the above example, 'D:' is treated as the most implementations. In the above example, 'D:' is treated as the
host component, and is taken away. Thus, cURL tries to open '/blah.txt'. host component, and is taken away. Thus, curl tries to open '/blah.txt'.
If your system is installed to drive C:, that will resolve to 'C:\blah.txt', If your system is installed to drive C:, that will resolve to 'C:\blah.txt',
and if that doesn't exist you will get the not found error. and if that doesn't exist you will get the not found error.
@ -1061,9 +1086,9 @@ FAQ
file://localhost/D:/blah.txt file://localhost/D:/blah.txt
In either case, cURL should now be looking for the correct file. In either case, curl should now be looking for the correct file.
4.19 Why doesn't cURL return an error when the network cable is unplugged? 4.19 Why doesn't curl return an error when the network cable is unplugged?
Unplugging a cable is not an error situation. The TCP/IP protocol stack Unplugging a cable is not an error situation. The TCP/IP protocol stack
was designed to be fault tolerant, so even though there may be a physical was designed to be fault tolerant, so even though there may be a physical
@ -1073,7 +1098,7 @@ FAQ
In such cases, the TCP/IP stack is responsible for detecting when the In such cases, the TCP/IP stack is responsible for detecting when the
network connection is irrevocably lost. Since with some protocols it is network connection is irrevocably lost. Since with some protocols it is
perfectly legal for the client wait indefinitely for data, the stack may perfectly legal for the client to wait indefinitely for data, the stack may
never report a problem, and even when it does, it can take up to 20 minutes never report a problem, and even when it does, it can take up to 20 minutes
for it to detect an issue. The curl option --keepalive-time enables for it to detect an issue. The curl option --keepalive-time enables
keep-alive support in the TCP/IP stack which makes it periodically probe the keep-alive support in the TCP/IP stack which makes it periodically probe the
@ -1100,7 +1125,7 @@ FAQ
When doing HTTP transfers, curl will perform exactly what you're asking it When doing HTTP transfers, curl will perform exactly what you're asking it
to do and if successful it will not return an error. You can use curl to to do and if successful it will not return an error. You can use curl to
test your web server's "file not found" page (that gets 404 back), you can test your web server's "file not found" page (that gets 404 back), you can
use it to check your authentication protected web pages (that get a 401 use it to check your authentication protected web pages (that gets a 401
back) and so on. back) and so on.
The specific HTTP response code does not constitute a problem or error for The specific HTTP response code does not constitute a problem or error for
@ -1115,7 +1140,7 @@ FAQ
libcurl speak). libcurl speak).
You can also use the -w option and the variable %{response_code} to extract You can also use the -w option and the variable %{response_code} to extract
the exact response code that was return in the response. the exact response code that was returned in the response.
4.21 Why is there a HTTP/1.1 in my HTTP/2 request? 4.21 Why is there a HTTP/1.1 in my HTTP/2 request?
@ -1125,8 +1150,8 @@ FAQ
The reason for this is that we first generate the request to send using the The reason for this is that we first generate the request to send using the
old 1.1 style and show that request in the verbose output, and then we old 1.1 style and show that request in the verbose output, and then we
convert it over to the binary header-compressed HTTP/2 style. The actual convert it over to the binary header-compressed HTTP/2 style. The actual
"1.1" part from that request is then not actually used in the transfer. The "1.1" part from that request is then not actually used in the transfer.
binary HTTP/2 headers are not human readable. The binary HTTP/2 headers are not human readable.
5. libcurl Issues 5. libcurl Issues
@ -1139,25 +1164,9 @@ FAQ
your system has such. Note that you must never share the same handle in your system has such. Note that you must never share the same handle in
multiple threads. multiple threads.
libcurl's implementation of timeouts might use signals (depending on what it There may be some exceptions to thread safety depending on how libcurl was
was built to use for name resolving), and signal handling is generally not built. Please review the guidelines for thread safety to learn more:
thread-safe. Multi-threaded Applicationss that call libcurl from different https://curl.haxx.se/libcurl/c/threadsafe.html
threads (on different handles) might want to use CURLOPT_NOSIGNAL, e.g.:
curl_easy_setopt(handle, CURLOPT_NOSIGNAL, true);
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
need to provide one or two locking functions:
http://www.openssl.org/docs/crypto/threads.html
If you use a GnuTLS-powered libcurl in a multi-threaded environment, you
need to provide locking function(s) for libgcrypt (which is used by GnuTLS
for the crypto functions).
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
No special locking is needed with a NSS-powered libcurl. NSS is thread-safe.
5.2 How can I receive all data into a large memory chunk? 5.2 How can I receive all data into a large memory chunk?
@ -1224,10 +1233,10 @@ FAQ
libcurl will reuse connections for all transfers that are made using the libcurl will reuse connections for all transfers that are made using the
same libcurl handle. same libcurl handle.
When you use the easy interface, the connection cache is kept within the When you use the easy interface the connection cache is kept within the easy
easy handle. If you instead use the multi interface, the connection cache handle. If you instead use the multi interface, the connection cache will be
will be kept within the multi handle and will be shared among all the easy kept within the multi handle and will be shared among all the easy handles
handles that are used within the same multi handle. that are used within the same multi handle.
5.7 Link errors when building libcurl on Windows! 5.7 Link errors when building libcurl on Windows!
@ -1286,8 +1295,8 @@ FAQ
you want to change name resolver function you must rebuild libcurl and tell you want to change name resolver function you must rebuild libcurl and tell
it to use a different function. it to use a different function.
- The non-IPv6 resolver that can use one out of four host name resolve calls - The non-IPv6 resolver that can use one of four different host name resolve
(depending on what your system supports): calls (depending on what your system supports):
A - gethostbyname() A - gethostbyname()
B - gethostbyname_r() with 3 arguments B - gethostbyname_r() with 3 arguments
@ -1321,7 +1330,7 @@ FAQ
5.12 Can I make libcurl fake or hide my real IP address? 5.12 Can I make libcurl fake or hide my real IP address?
No. libcurl operates on a higher level. Besides, faking IP address would No. libcurl operates on a higher level. Besides, faking IP address would
imply sending IP packet with a made-up source address, and then you normally imply sending IP packets with a made-up source address, and then you normally
get a problem with receiving the packet sent back as they would then not be get a problem with receiving the packet sent back as they would then not be
routed to you! routed to you!
@ -1331,7 +1340,7 @@ FAQ
Also note that on many networks NATs or other IP-munging techniques are used Also note that on many networks NATs or other IP-munging techniques are used
that makes you see and use a different IP address locally than what the that makes you see and use a different IP address locally than what the
remote server will see you coming from. You may also consider using remote server will see you coming from. You may also consider using
http://www.torproject.org . https://www.torproject.org/ .
5.13 How do I stop an ongoing transfer? 5.13 How do I stop an ongoing transfer?
@ -1351,18 +1360,18 @@ FAQ
libcurl is a C library, it doesn't know anything about C++ member functions. libcurl is a C library, it doesn't know anything about C++ member functions.
You can overcome this "limitation" with a relative ease using a static You can overcome this "limitation" with relative ease using a static
member function that is passed a pointer to the class: member function that is passed a pointer to the class:
// f is the pointer to your object. // f is the pointer to your object.
static YourClass::func(void *buffer, size_t sz, size_t n, void *f) static size_t YourClass::func(void *buffer, size_t sz, size_t n, void *f)
{ {
// Call non-static member function. // Call non-static member function.
static_cast<YourClass*>(f)->nonStaticFunction(); static_cast<YourClass*>(f)->nonStaticFunction();
} }
// This is how you pass pointer to the static function: // This is how you pass pointer to the static function:
curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass:func); curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass::func);
curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this); curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this);
5.15 How do I get an FTP directory listing? 5.15 How do I get an FTP directory listing?
@ -1372,18 +1381,28 @@ FAQ
CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use
to list the files. to list the files.
The follow-up question that tend to follow the previous one, is how a The follow-up question tends to be how is a program supposed to parse the
program is supposed to parse the directory listing. How does it know what's directory listing. How does it know what's a file and what's a dir and what's
a file and what's a dir and what's a symlink etc. The harsh reality is that a symlink etc. If the FTP server supports the MLSD command then it will
FTP provides no such fine and easy-to-parse output. The output format FTP return data in a machine-readable format that can be parsed for type. The
servers respond to LIST commands are entirely at the server's own liking and types are specified by RFC3659 section 7.5.1. If MLSD is not supported then
the NLST output doesn't reveal any types and in many cases don't even you have to work with what you're given. The LIST output format is entirely
include all the directory entries. Also, both LIST and NLST tend to hide at the server's own liking and the NLST output doesn't reveal any types and
unix-style hidden files (those that start with a dot) by default so you need in many cases doesn't even include all the directory entries. Also, both LIST
to do "LIST -a" or similar to see them. and NLST tend to hide unix-style hidden files (those that start with a dot)
by default so you need to do "LIST -a" or similar to see them.
The application thus needs to parse the LIST output. One such existing Example - List only directories.
list parser is available at http://cr.yp.to/ftpparse.html Versions of ftp.funet.fi supports MLSD and ftp.kernel.org does not:
curl -s ftp.funet.fi/pub/ -X MLSD | \
perl -lne 'print if s/(?:^|;)type=dir;[^ ]+ (.+)$/$1/'
curl -s ftp.kernel.org/pub/linux/kernel/ | \
perl -lne 'print if s/^d[-rwx]{9}(?: +[^ ]+){7} (.+)$/$1/'
If you need to parse LIST output in libcurl one such existing
list parser is available at https://cr.yp.to/ftpparse.html Versions of
libcurl since 7.21.0 also provide the ability to specify a wildcard to libcurl since 7.21.0 also provide the ability to specify a wildcard to
download multiple files from one FTP directory. download multiple files from one FTP directory.
@ -1502,7 +1521,7 @@ FAQ
notice" somewhere. Most probably like in the documentation or in the section notice" somewhere. Most probably like in the documentation or in the section
where other third party dependencies already are mentioned and acknowledged. where other third party dependencies already are mentioned and acknowledged.
As can be seen here: http://curl.haxx.se/docs/companies.html and elsewhere, As can be seen here: https://curl.haxx.se/docs/companies.html and elsewhere,
more and more companies are discovering the power of libcurl and take more and more companies are discovering the power of libcurl and take
advantage of it even in commercial environments. advantage of it even in commercial environments.
@ -1522,9 +1541,7 @@ FAQ
7.2 Who wrote PHP/CURL? 7.2 Who wrote PHP/CURL?
PHP/CURL is a module that comes with the regular PHP package. It depends and PHP/CURL was initially written by Sterling Hughes.
uses libcurl, so you need to have libcurl installed properly first before
PHP/CURL can be used. PHP/CURL was initially written by Sterling Hughes.
7.3 Can I perform multiple requests using the same handle? 7.3 Can I perform multiple requests using the same handle?
@ -1533,4 +1550,10 @@ FAQ
unknown to me). unknown to me).
After a transfer, you just set new options in the handle and make another After a transfer, you just set new options in the handle and make another
transfer. This will make libcurl to re-use the same connection if it can. transfer. This will make libcurl re-use the same connection if it can.
7.4 Does PHP/CURL have dependencies?
PHP/CURL is a module that comes with the regular PHP package. It depends on
and uses libcurl, so you need to have libcurl installed properly before
PHP/CURL can be used.

View File

@ -185,7 +185,7 @@ FOOTNOTES
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native *1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native
Windows), Secure Transport (native iOS/OS X) or GSKit (native IBM i) Windows), Secure Transport (native iOS/OS X) or GSKit (native IBM i)
*2 = requires OpenLDAP *2 = requires OpenLDAP or WinLDAP
*3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or *3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
SSPI (native Windows) SSPI (native Windows)
*4 = requires a GSS-API implementation, however, only Windows SSPI is *4 = requires a GSS-API implementation, however, only Windows SSPI is
@ -195,8 +195,8 @@ FOOTNOTES
*7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for *7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for
example, only supports SSLv3 and TLSv1 example, only supports SSLv3 and TLSv1
*8 = requires libssh2 *8 = requires libssh2
*9 = requires OpenSSL, GnuTLS, NSS, yassl, Secure Transport or SSPI (native *9 = requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI
Windows) (native Windows)
*10 = requires any of the SSL libraries in (*1) above other than axTLS, which *10 = requires any of the SSL libraries in (*1) above other than axTLS, which
does not support SSLv3 does not support SSLv3
*11 = requires libidn or Windows *11 = requires libidn or Windows

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,9 @@ Current flaws in the curl CMake build
Missing features in the cmake build: Missing features in the cmake build:
- Builds libcurl without large file support - Builds libcurl without large file support
- Can't select which SSL library to build with, only OpenSSL - Does not support all SSL libraries (only OpenSSL, WinSSL, DarwinSSL, and
- Doesn't build with SCP and SFTP support (libssh2) mbed TLS)
- Doesn't build with SCP and SFTP support (libssh2) (see issue #1155)
- Doesn't allow different resolver backends (no c-ares build support) - Doesn't allow different resolver backends (no c-ares build support)
- No RTMP support built - No RTMP support built
- Doesn't allow build curl and libcurl debug enabled - Doesn't allow build curl and libcurl debug enabled
@ -33,19 +34,9 @@ Current flaws in the curl CMake build
- Doesn't allow you to disable specific protocols from the build - Doesn't allow you to disable specific protocols from the build
- Doesn't find or use krb4 or GSS - Doesn't find or use krb4 or GSS
- Rebuilds test files too eagerly, but still can't run the tests - Rebuilds test files too eagerly, but still can't run the tests
- Does't detect the correct strerror_r flavor when cross-compiling (issue #1123)
Important notice
==================
If you got your curl sources from a distribution tarball, make sure to
delete the generic 'include/curl/curlbuild.h' file that comes with it:
rm -f curl/include/curl/curlbuild.h
The purpose of this file is to provide reasonable definitions for systems
where autoconfiguration is not available. CMake will create its own
version of this file in its build directory. If the "generic" version
is not deleted, weird build errors may occur on some systems.
Command Line CMake Command Line CMake
================== ==================
A CMake build of curl is similar to the autotools build of curl. It A CMake build of curl is similar to the autotools build of curl. It

View File

@ -1,257 +1,593 @@
These are problems known to exist at the time of this release. Feel free to _ _ ____ _
join in and help us correct one or more of these! Also be sure to check the ___| | | | _ \| |
changelog of the current development status, as one or more of these problems / __| | | | |_) | |
may have been fixed since this was written! | (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
90. IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the Known Bugs
code reveals that pingpong.c contains some truncation code, at line 408,
when it deems the server response to be too large truncating it to 40
characters"
http://curl.haxx.se/bug/view.cgi?id=1366
89. Disabling HTTP Pipelining when there are ongoing transfers can lead to These are problems and bugs known to exist at the time of this release. Feel
heap corruption and crash. http://curl.haxx.se/bug/view.cgi?id=1411 free to join in and help us correct one or more of these! Also be sure to
check the changelog of the current development status, as one or more of these
problems may have been fixed or changed somewhat since this was written!
88. libcurl doesn't support CURLINFO_FILETIME for SFTP transfers and thus 1. HTTP
curl's -R option also doesn't work then. 1.1 CURLFORM_CONTENTLEN in an array
1.2 Disabling HTTP Pipelining
1.3 STARTTRANSFER time is wrong for HTTP POSTs
1.4 multipart formposts file name encoding
1.5 Expect-100 meets 417
1.6 Unnecessary close when 401 received waiting for 100
1.9 HTTP/2 frames while in the connection pool kill reuse
1.10 Strips trailing dot from host name
1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
87. -J/--remote-header-name doesn't decode %-encoded file names. RFC6266 2. TLS
details how it should be done. The can of worm is basically that we have no 2.1 CURLINFO_SSL_VERIFYRESULT has limited support
charset handling in curl and ascii >=128 is a challenge for us. Not to 2.2 DER in keychain
mention that decoding also means that we need to check for nastiness that is 2.3 GnuTLS backend skips really long certificate fields
attempted, like "../" sequences and the like. Probably everything to the left 2.4 DarwinSSL won't import PKCS#12 client certificates without a password
of any embedded slashes should be cut off.
http://curl.haxx.se/bug/view.cgi?id=1294
86. The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3 3. Email protocols
and SMTP if a failure occurs during the authentication phase of a 3.1 IMAP SEARCH ALL truncated response
connection. 3.2 No disconnect command
3.3 SMTP to multiple recipients
3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses
85. Wrong STARTTRANSFER timer accounting for POST requests 4. Command line
Timer works fine with GET requests, but while using POST the time for 4.1 -J with %-encoded file nameas
CURLINFO_STARTTRANSFER_TIME is wrong. While using POST 4.2 -J with -C - fails
CURLINFO_STARTTRANSFER_TIME minus CURLINFO_PRETRANSFER_TIME is near to zero 4.3 --retry and transfer timeouts
every time.
http://curl.haxx.se/bug/view.cgi?id=1213
84. CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS 5. Build and portability issues
backends, so relying on this information in a generic app is flaky. 5.1 Windows Borland compiler
5.2 curl-config --libs contains private details
5.4 AIX shared build with c-ares fails
5.5 can't handle Unicode arguments in Windows
5.6 cmake support gaps
5.7 Visual Studio project gaps
5.8 configure finding libs in wrong directory
5.9 Utilize Requires.private directives in libcurl.pc
82. When building with the Windows Borland compiler, it fails because the 6. Authentication
"tlib" tool doesn't support hyphens (minus signs) in file names and we have 6.1 NTLM authentication and unicode
such in the build. 6.2 MIT Kerberos for Windows build
http://curl.haxx.se/bug/view.cgi?id=1222 6.3 NTLM in system context uses wrong name
6.4 Negotiate and Kerberos V5 need a fake user name
81. When using -J (with -O), automatically resumed downloading together with 7. FTP
"-C -" fails. Without -J the same command line works! This happens because 7.1 FTP without or slow 220 response
the resume logic is worked out before the target file name (and thus its 7.2 FTP with CONNECT and slow server
pre-transfer size) has been figured out! 7.3 FTP with NOBODY and FAILONERROR
http://curl.haxx.se/bug/view.cgi?id=1169 7.4 FTP with ACCT
7.5 ASCII FTP
7.6 FTP with NULs in URL parts
7.7 FTP and empty path parts in the URL
7.8 Premature transfer end but healthy control channel
80. Curl doesn't recognize certificates in DER format in keychain, but it 8. TELNET
works with PEM. 8.1 TELNET and time limtiations don't work
http://curl.haxx.se/bug/view.cgi?id=1065 8.2 Microsoft telnet server
79. SMTP. When sending data to multiple recipients, curl will abort and return 9. SFTP and SCP
failure if one of the recipients indicate failure (on the "RCPT TO" 9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct
command). Ordinary mail programs would proceed and still send to the ones
that can receive data. This is subject for change in the future.
http://curl.haxx.se/bug/view.cgi?id=1116
78. curl and libcurl don't always signal the client properly when "sending" 10. SOCKS
zero bytes files - it makes for example the command line client not creating 10.1 SOCKS proxy connections are done blocking
any file at all. Like when using FTP. 10.2 SOCKS don't support timeouts
http://curl.haxx.se/bug/view.cgi?id=1063 10.3 FTPS over SOCKS
10.4 active FTP over a SOCKS
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on 11. Internals
that platform), and long is only 32 bits. It makes it impossible for 11.1 Curl leaks .onion hostnames in DNS
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET 11.2 error buffer not set if connection to multiple addresses fails
option as for all other operating systems. 11.3 c-ares deviates from stock resolver on http://1346569778
11.4 HTTP test server 'connection-monitor' problems
75. NTLM authentication involving unicode user name or password only works 12. LDAP and OpenLDAP
properly if built with UNICODE defined together with the WinSSL/schannel 12.1 OpenLDAP hangs after returning results
backend. The original problem was mentioned in:
http://curl.haxx.se/mail/lib-2009-10/0024.html
http://curl.haxx.se/bug/view.cgi?id=896
The WinSSL/schannel version verified to work as mentioned in 13. TCP/IP
http://curl.haxx.se/mail/lib-2012-07/0073.html 13.1 --interface for ipv6 binds to unusable IP address
73. if a connection is made to a FTP server but the server then just never
sends the 220 response or otherwise is dead slow, libcurl will not
acknowledge the connection timeout during that phase but only the "real"
timeout - which may surprise users as it is probably considered to be the
connect phase to most people. Brought up (and is being misunderstood) in:
http://curl.haxx.se/bug/view.cgi?id=856
72. "Pausing pipeline problems." ==============================================================================
http://curl.haxx.se/mail/lib-2009-07/0214.html
70. Problem re-using easy handle after call to curl_multi_remove_handle 1. HTTP
http://curl.haxx.se/mail/lib-2009-07/0249.html
68. "More questions about ares behavior". 1.1 CURLFORM_CONTENTLEN in an array
http://curl.haxx.se/mail/lib-2009-08/0012.html
67. When creating multipart formposts. The file name part can be encoded with It is not possible to pass a 64-bit value using CURLFORM_CONTENTLEN with
something beyond ascii but currently libcurl will only pass in the verbatim CURLFORM_ARRAY, when compiled on 32-bit platforms that support 64-bit
string the app provides. There are several browsers that already do this integers. This is because the underlying structure 'curl_forms' uses a dual
encoding. The key seems to be the updated draft to RFC2231: purpose char* for storing these values in via casting. For more information
http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02 see the now closed related issue:
https://github.com/curl/curl/issues/608
66. When using telnet, the time limitation options don't work. 1.2 Disabling HTTP Pipelining
http://curl.haxx.se/bug/view.cgi?id=846
65. When doing FTP over a socks proxy or CONNECT through HTTP proxy and the Disabling HTTP Pipelining when there are ongoing transfers can lead to
multi interface is used, libcurl will fail if the (passive) TCP connection heap corruption and crash. https://curl.haxx.se/bug/view.cgi?id=1411
for the data transfer isn't more or less instant as the code does not
properly wait for the connect to be confirmed. See test case 564 for a first
shot at a test case.
63. When CURLOPT_CONNECT_ONLY is used, the handle cannot reliably be re-used 1.3 STARTTRANSFER time is wrong for HTTP POSTs
for any further requests or transfers. The work-around is then to close that
handle with curl_easy_cleanup() and create a new. Some more details:
http://curl.haxx.se/mail/lib-2009-04/0300.html
61. If an upload using Expect: 100-continue receives an HTTP 417 response, Wrong STARTTRANSFER timer accounting for POST requests Timer works fine with
it ought to be automatically resent without the Expect:. A workaround is GET requests, but while using POST the time for CURLINFO_STARTTRANSFER_TIME
for the client application to redo the transfer after disabling Expect:. is wrong. While using POST CURLINFO_STARTTRANSFER_TIME minus
http://curl.haxx.se/mail/archive-2008-02/0043.html CURLINFO_PRETRANSFER_TIME is near to zero every time.
60. libcurl closes the connection if an HTTP 401 reply is received while it https://github.com/curl/curl/issues/218
is waiting for the the 100-continue response. https://curl.haxx.se/bug/view.cgi?id=1213
http://curl.haxx.se/mail/lib-2008-08/0462.html
58. It seems sensible to be able to use CURLOPT_NOBODY and 1.4 multipart formposts file name encoding
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP When creating multipart formposts. The file name part can be encoded with
server using the multi interface, the commands are not being sent correctly something beyond ascii but currently libcurl will only pass in the verbatim
and instead the connection is "cancelled" (the operation is considered done) string the app provides. There are several browsers that already do this
prematurely. There is a half-baked (busy-looping) patch provided in the bug encoding. The key seems to be the updated draft to RFC2231:
report but it cannot be accepted as-is. See https://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
http://curl.haxx.se/bug/view.cgi?id=748
55. libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's 1.5 Expect-100 meets 417
library header files exporting symbols/macros that should be kept private
to the KfW library. See ticket #5601 at http://krbdev.mit.edu/rt/
52. Gautam Kachroo's issue that identifies a problem with the multi interface If an upload using Expect: 100-continue receives an HTTP 417 response, it
where a connection can be re-used without actually being properly ought to be automatically resent without the Expect:. A workaround is for
SSL-negotiated: the client application to redo the transfer after disabling Expect:.
http://curl.haxx.se/mail/lib-2008-01/0277.html https://curl.haxx.se/mail/archive-2008-02/0043.html
49. If using --retry and the transfer timeouts (possibly due to using -m or 1.6 Unnecessary close when 401 received waiting for 100
-y/-Y) the next attempt doesn't resume the transfer properly from what was
downloaded in the previous attempt but will truncate and restart at the
original position where it was at before the previous failed attempt. See
http://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
https://qa.mandriva.com/show_bug.cgi?id=22565
48. If a CONNECT response-headers are larger than BUFSIZE (16KB) when the libcurl closes the connection if an HTTP 401 reply is received while it is
connection is meant to be kept alive (like for NTLM proxy auth), the waiting for the the 100-continue response.
function will return prematurely and will confuse the rest of the HTTP https://curl.haxx.se/mail/lib-2008-08/0462.html
protocol code. This should be very rare.
43. There seems to be a problem when connecting to the Microsoft telnet server. 1.9 HTTP/2 frames while in the connection pool kill reuse
http://curl.haxx.se/bug/view.cgi?id=649
41. When doing an operation over FTP that requires the ACCT command (but not If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to
when logging in), the operation will fail since libcurl doesn't detect this curl while the connection is held in curl's connection pool, the socket will
and thus fails to issue the correct command: be found readable when considered for reuse and that makes curl think it is
http://curl.haxx.se/bug/view.cgi?id=635 dead and then it will be closed and a new connection gets created instead.
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT: This is *best* fixed by adding monitoring to connections while they are kept
http://curl.haxx.se/mail/lib-2007-01/0045.html in the pool so that pings can be responded to appropriately.
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation: 1.10 Strips trailing dot from host name
http://curl.haxx.se/mail/lib-2007-01/0103.html
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very When given a URL with a trailing dot for the host name part:
bad when used with the multi interface. "https://example.com./", libcurl will strip off the dot and use the name
without a dot internally and send it dot-less in HTTP Host: headers and in
the TLS SNI field.
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts. The HTTP part violates RFC 7230 section 5.4 but the SNI part is accordance
Also see #12. According to bug #1556528, even the SOCKS5 connect code does with RFC 6066 section 3.
not do it right: http://curl.haxx.se/bug/view.cgi?id=604
31. "curl-config --libs" will include details set in LDFLAGS when configure is URLs using these trailing dots are very rare in the wild and we have not seen
run that might be needed only for building libcurl. Further, curl-config or gotten any real-world problems with such URLs reported. The popular
--cflags suffers from the same effects with CFLAGS/CPPFLAGS. browsers seem to have stayed with not stripping the dot for both uses (thus
they violate RFC 6066 instead of RFC 7230).
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in Daniel took the discussion to the HTTPbis mailing list in March 2016:
"system context" will make it use wrong(?) user name - at least when compared https://lists.w3.org/Archives/Public/ietf-http-wg/2016JanMar/0430.html but
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=535 there was not major rush or interest to fix this. The impression I get is
that most HTTP people rather not rock the boat now and instead prioritize web
compatibility rather than to strictly adhere to these RFCs.
23. SOCKS-related problems: Our current approach allows a knowing client to send a custom HTTP header
B) libcurl doesn't support FTPS over a SOCKS proxy. with the dot added.
E) libcurl doesn't support active FTP over a SOCKS proxy
We probably have even more bugs and lack of features when a SOCKS proxy is It can also be noted that while adding a trailing dot to the host name in
used. most (all?) cases will make the name resolve to the same set of IP addresses,
many HTTP servers will not happily accept the trailing dot there unless that
has been specifically configured to be a fine virtual host.
21. FTP ASCII transfers do not follow RFC959. They don't convert the data If URLs with trailing dots for host names become more popular or even just
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1 used more than for just plain fun experiments, I'm sure we will have reason
clearly describes how this should be done: to go back and reconsider.
The sender converts the data from an internal character representation to See https://github.com/curl/curl/issues/716 for the discussion.
the standard 8-bit NVT-ASCII representation (see the Telnet
specification). The receiver will convert the data from the standard
form to his own internal form.
Since 7.15.4 at least line endings are converted. 1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>, I'm using libcurl to POST form data using a FILE* with the CURLFORM_STREAM
<password>, and <fpath> components, encoded as "%00". The problem is that option of curl_formadd(). I've noticed that if the connection drops at just
curl_unescape does not detect this, but instead returns a shortened C the right time, the POST is reattempted without the data from the file. It
string. From a strict FTP protocol standpoint, NUL is a valid character seems like the file stream position isn't getting reset to the beginning of
within RFC 959 <string>, so the way to handle this correctly in curl would the file. I found the CURLOPT_SEEKFUNCTION option and set that with a
be to use a data structure other than a plain C string, one that can handle function that performs an fseek() on the FILE*. However, setting that didn't
embedded NUL characters. From a practical standpoint, most FTP servers seem to fix the issue or even get called. See
would not meaningfully support NUL characters within RFC 959 <string>, https://github.com/curl/curl/issues/768
anyway (e.g., Unix pathnames may not contain NUL).
14. Test case 165 might fail on a system which has libidn present, but with an
old iconv version (2.1.3 is a known bad version), since it doesn't recognize
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
test pass, but instead makes it fail on Solaris hosts that use its native
iconv.
13. curl version 7.12.2 fails on AIX if compiled with --enable-ares. 2. TLS
The workaround is to combine --enable-ares with --disable-shared
12. When connecting to a SOCKS proxy, the (connect) timeout is not properly 2.1 CURLINFO_SSL_VERIFYRESULT has limited support
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase).
10. To get HTTP Negotiate (SPNEGO) authentication to work fine, you need to CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
provide a (fake) user name (this concerns both curl and the lib) because the backends, so relying on this information in a generic app is flaky.
code wrongly only considers authentication if there's a user name provided.
http://curl.haxx.se/bug/view.cgi?id=440 How?
http://curl.haxx.se/mail/lib-2004-08/0182.html
8. Doing resumed upload over HTTP does not work with '-C -', because curl 2.2 DER in keychain
doesn't do a HEAD first to get the initial size. This needs to be done
manually for HTTP PUT resume to work, and then '-C [index]'.
6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that Curl doesn't recognize certificates in DER format in keychain, but it works
such parts should be sent to the server as 'CWD ' (without an argument). with PEM. https://curl.haxx.se/bug/view.cgi?id=1065
The only exception to this rule, is that we knowingly break this if the
empty part is first in the path, as then we use the double slashes to
indicate that the user wants to reach the root dir (this exception SHALL
remain even when this bug is fixed).
5. libcurl doesn't treat the content-length of compressed data properly, as 2.3 GnuTLS backend skips really long certificate fields
it seems HTTP servers send the *uncompressed* length in that header and
libcurl thinks of it as the *compressed* length. Some explanations are here:
http://curl.haxx.se/mail/lib-2003-06/0146.html
2. If a HTTP server responds to a HEAD request and includes a body (thus libcurl calls gnutls_x509_crt_get_dn() with a fixed buffer size and if the
violating the RFC2616), curl won't wait to read the response but just stop field is too long in the cert, it'll just return an error and the field will
reading and return back. If a second request (let's assume a GET) is then be displayed blank.
immediately made to the same server again, the connection will be re-used
fine of course, and the second request will be sent off but when the 2.4 DarwinSSL won't import PKCS#12 client certificates without a password
response is to get read, the previous response-body is what curl will read
and havoc is what happens. libcurl calls SecPKCS12Import with the PKCS#12 client certificate, but that
More details on this is found in this libcurl mailing list thread: function rejects certificates that do not have a password.
http://curl.haxx.se/mail/lib-2002-08/0000.html https://github.com/curl/curl/issues/1308
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the
code reveals that pingpong.c contains some truncation code, at line 408, when
it deems the server response to be too large truncating it to 40 characters"
https://curl.haxx.se/bug/view.cgi?id=1366
3.2 No disconnect command
The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3 and
SMTP if a failure occurs during the authentication phase of a connection.
3.3 SMTP to multiple recipients
When sending data to multiple recipients, curl will abort and return failure
if one of the recipients indicate failure (on the "RCPT TO"
command). Ordinary mail programs would proceed and still send to the ones
that can receive data. This is subject for change in the future.
https://curl.haxx.se/bug/view.cgi?id=1116
3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses
You have to tell libcurl not to expect a body, when dealing with one line
response commands. Please see the POP3 examples and test cases which show
this for the NOOP and DELE commands. https://curl.haxx.se/bug/?i=740
4. Command line
4.1 -J with %-encoded file nameas
-J/--remote-header-name doesn't decode %-encoded file names. RFC6266 details
how it should be done. The can of worm is basically that we have no charset
handling in curl and ascii >=128 is a challenge for us. Not to mention that
decoding also means that we need to check for nastiness that is attempted,
like "../" sequences and the like. Probably everything to the left of any
embedded slashes should be cut off.
https://curl.haxx.se/bug/view.cgi?id=1294
4.2 -J with -C - fails
When using -J (with -O), automatically resumed downloading together with "-C
-" fails. Without -J the same command line works! This happens because the
resume logic is worked out before the target file name (and thus its
pre-transfer size) has been figured out!
https://curl.haxx.se/bug/view.cgi?id=1169
4.3 --retry and transfer timeouts
If using --retry and the transfer timeouts (possibly due to using -m or
-y/-Y) the next attempt doesn't resume the transfer properly from what was
downloaded in the previous attempt but will truncate and restart at the
original position where it was at before the previous failed attempt. See
https://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
https://qa.mandriva.com/show_bug.cgi?id=22565
5. Build and portability issues
5.1 Windows Borland compiler
When building with the Windows Borland compiler, it fails because the "tlib"
tool doesn't support hyphens (minus signs) in file names and we have such in
the build. https://curl.haxx.se/bug/view.cgi?id=1222
5.2 curl-config --libs contains private details
"curl-config --libs" will include details set in LDFLAGS when configure is
run that might be needed only for building libcurl. Further, curl-config
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
5.4 AIX shared build with c-ares fails
curl version 7.12.2 fails on AIX if compiled with --enable-ares. The
workaround is to combine --enable-ares with --disable-shared
5.5 can't handle Unicode arguments in Windows
If a URL or filename can't be encoded using the user's current codepage then
it can only be encoded properly in the Unicode character set. Windows uses
UTF-16 encoding for Unicode and stores it in wide characters, however curl
and libcurl are not equipped for that at the moment. And, except for Cygwin,
Windows can't use UTF-8 as a locale.
https://curl.haxx.se/bug/?i=345
https://curl.haxx.se/bug/?i=731
5.6 cmake support gaps
The cmake build setup lacks several features that the autoconf build
offers. This includes:
- use of correct soname for the shared library build
- support for several TLS backends are missing
- the unit tests cause link failures in regular non-static builds
- no nghttp2 check
5.7 Visual Studio project gaps
The Visual Studio projects lack some features that the autoconf and nmake
builds offer, such as the following:
- support for zlib and nghttp2
- use of static runtime libraries
- add the test suite components
In addition to this the following could be implemented:
- support for other development IDEs
- add PATH environment variables for third-party DLLs
5.8 configure finding libs in wrong directory
When the configure script checks for third-party libraries, it adds those
directories to the LDFLAGS variable and then tries linking to see if it
works. When successful, the found directory is kept in the LDFLAGS variable
when the script continues to execute and do more tests and possibly check for
more libraries.
This can make subsequent checks for libraries wrongly detect another
installation in a directory that was previously added to LDFLAGS by another
library check!
A possibly better way to do these checks would be to keep the pristine LDFLAGS
even after successful checks and instead add those verified paths to a
separate variable that only after all library checks have been performed gets
appended to LDFLAGS.
5.9 Utilize Requires.private directives in libcurl.pc
https://github.com/curl/curl/issues/864
6. Authentication
6.1 NTLM authentication and unicode
NTLM authentication involving unicode user name or password only works
properly if built with UNICODE defined together with the WinSSL/schannel
backend. The original problem was mentioned in:
https://curl.haxx.se/mail/lib-2009-10/0024.html
https://curl.haxx.se/bug/view.cgi?id=896
The WinSSL/schannel version verified to work as mentioned in
https://curl.haxx.se/mail/lib-2012-07/0073.html
6.2 MIT Kerberos for Windows build
libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's
library header files exporting symbols/macros that should be kept private to
the KfW library. See ticket #5601 at https://krbdev.mit.edu/rt/
6.3 NTLM in system context uses wrong name
NTLM authentication using SSPI (on Windows) when (lib)curl is running in
"system context" will make it use wrong(?) user name - at least when compared
to what winhttp does. See https://curl.haxx.se/bug/view.cgi?id=535
6.4 Negotiate and Kerberos V5 need a fake user name
In order to get Negotiate (SPNEGO) authentication to work in HTTP or Kerberos
V5 in the e-mail protocols, you need to provide a (fake) user name (this
concerns both curl and the lib) because the code wrongly only considers
authentication if there's a user name provided by setting
conn->bits.user_passwd in url.c https://curl.haxx.se/bug/view.cgi?id=440 How?
https://curl.haxx.se/mail/lib-2004-08/0182.html A possible solution is to
either modify this variable to be set or introduce a variable such as
new conn->bits.want_authentication which is set when any of the authentication
options are set.
7. FTP
7.1 FTP without or slow 220 response
If a connection is made to a FTP server but the server then just never sends
the 220 response or otherwise is dead slow, libcurl will not acknowledge the
connection timeout during that phase but only the "real" timeout - which may
surprise users as it is probably considered to be the connect phase to most
people. Brought up (and is being misunderstood) in:
https://curl.haxx.se/bug/view.cgi?id=856
7.2 FTP with CONNECT and slow server
When doing FTP over a socks proxy or CONNECT through HTTP proxy and the multi
interface is used, libcurl will fail if the (passive) TCP connection for the
data transfer isn't more or less instant as the code does not properly wait
for the connect to be confirmed. See test case 564 for a first shot at a test
case.
7.3 FTP with NOBODY and FAILONERROR
It seems sensible to be able to use CURLOPT_NOBODY and CURLOPT_FAILONERROR
with FTP to detect if a file exists or not, but it is not working:
https://curl.haxx.se/mail/lib-2008-07/0295.html
7.4 FTP with ACCT
When doing an operation over FTP that requires the ACCT command (but not when
logging in), the operation will fail since libcurl doesn't detect this and
thus fails to issue the correct command:
https://curl.haxx.se/bug/view.cgi?id=635
7.5 ASCII FTP
FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
clearly describes how this should be done:
The sender converts the data from an internal character representation to
the standard 8-bit NVT-ASCII representation (see the Telnet
specification). The receiver will convert the data from the standard
form to his own internal form.
Since 7.15.4 at least line endings are converted.
7.6 FTP with NULs in URL parts
FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
<password>, and <fpath> components, encoded as "%00". The problem is that
curl_unescape does not detect this, but instead returns a shortened C string.
From a strict FTP protocol standpoint, NUL is a valid character within RFC
959 <string>, so the way to handle this correctly in curl would be to use a
data structure other than a plain C string, one that can handle embedded NUL
characters. From a practical standpoint, most FTP servers would not
meaningfully support NUL characters within RFC 959 <string>, anyway (e.g.,
Unix pathnames may not contain NUL).
7.7 FTP and empty path parts in the URL
libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
such parts should be sent to the server as 'CWD ' (without an argument). The
only exception to this rule, is that we knowingly break this if the empty
part is first in the path, as then we use the double slashes to indicate that
the user wants to reach the root dir (this exception SHALL remain even when
this bug is fixed).
7.8 Premature transfer end but healthy control channel
When 'multi_done' is called before the transfer has been completed the normal
way, it is considered a "premature" transfer end. In this situation, libcurl
closes the connection assuming it doesn't know the state of the connection so
it can't be reused for subsequent requests.
With FTP however, this isn't necessarily true but there are a bunch of
situations (listed in the ftp_done code) where it *could* keep the connection
alive even in this situation - but the current code doesn't. Fixing this would
allow libcurl to reuse FTP connections better.
8. TELNET
8.1 TELNET and time limtiations don't work
When using telnet, the time limitation options don't work.
https://curl.haxx.se/bug/view.cgi?id=846
8.2 Microsoft telnet server
There seems to be a problem when connecting to the Microsoft telnet server.
https://curl.haxx.se/bug/view.cgi?id=649
9. SFTP and SCP
9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct
When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP server
using the multi interface, the commands are not being sent correctly and
instead the connection is "cancelled" (the operation is considered done)
prematurely. There is a half-baked (busy-looping) patch provided in the bug
report but it cannot be accepted as-is. See
https://curl.haxx.se/bug/view.cgi?id=748
10. SOCKS
10.1 SOCKS proxy connections are done blocking
Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very bad
when used with the multi interface.
10.2 SOCKS don't support timeouts
The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
According to bug #1556528, even the SOCKS5 connect code does not do it right:
https://curl.haxx.se/bug/view.cgi?id=604
When connecting to a SOCK proxy, the (connect) timeout is not properly
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase).
10.3 FTPS over SOCKS
libcurl doesn't support FTPS over a SOCKS proxy.
10.4 active FTP over a SOCKS
libcurl doesn't support active FTP over a SOCKS proxy
11. Internals
11.1 Curl leaks .onion hostnames in DNS
Curl sends DNS requests for hostnames with a .onion TLD. This leaks
information about what the user is attempting to access, and violates this
requirement of RFC7686: https://tools.ietf.org/html/rfc7686
Issue: https://github.com/curl/curl/issues/543
11.2 error buffer not set if connection to multiple addresses fails
If you ask libcurl to resolve a hostname like example.com to IPv6 addresses
only. But you only have IPv4 connectivity. libcurl will correctly fail with
CURLE_COULDNT_CONNECT. But the error buffer set by CURLOPT_ERRORBUFFER
remains empty. Issue: https://github.com/curl/curl/issues/544
11.3 c-ares deviates from stock resolver on http://1346569778
When using the socket resolvers, that URL becomes:
* Rebuilt URL to: http://1346569778/
* Trying 80.67.6.50...
but with c-ares it instead says "Could not resolve: 1346569778 (Domain name
not found)"
See https://github.com/curl/curl/issues/893
11.4 HTTP test server 'connection-monitor' problems
The 'connection-monitor' feature of the sws HTTP test server doesn't work
properly if some tests are run in unexpected order. Like 1509 and then 1525.
See https://github.com/curl/curl/issues/868
12. LDAP and OpenLDAP
12.1 OpenLDAP hangs after returning results
By configuration defaults, openldap automatically chase referrals on
secondary socket descriptors. The OpenLDAP backend is asynchronous and thus
should monitor all socket descriptors involved. Currently, these secondary
descriptors are not monitored, causing openldap library to never receive
data from them.
As a temporary workaround, disable referrals chasing by configuration.
The fix is not easy: proper automatic referrals chasing requires a
synchronous bind callback and monitoring an arbitrary number of socket
descriptors for a single easy handle (currently limited to 5).
Generic LDAP is synchronous: OK.
See https://github.com/curl/curl/issues/622 and
https://curl.haxx.se/mail/lib-2016-01/0101.html
13. TCP/IP
13.1 --interface for ipv6 binds to unusable IP address
Since IPv6 provides a lot of addresses with different scope, binding to an
IPv6 address needs to take the proper care so that it doesn't bind to a
locally scoped address as that is bound to fail.
https://github.com/curl/curl/issues/686

View File

@ -15,6 +15,7 @@ MAIL ETIQUETTE
1.6 Handling trolls and spam 1.6 Handling trolls and spam
1.7 How to unsubscribe 1.7 How to unsubscribe
1.8 I posted, now what? 1.8 I posted, now what?
1.9 Your emails are public
2. Sending mail 2. Sending mail
2.1 Reply or New Mail 2.1 Reply or New Mail
@ -33,22 +34,22 @@ MAIL ETIQUETTE
1.1 Mailing Lists 1.1 Mailing Lists
The mailing lists we have are all listed and described at The mailing lists we have are all listed and described at
http://curl.haxx.se/mail/ https://curl.haxx.se/mail/
Each mailing list is targeted to a specific set of users and subjects, Each mailing list is targeted to a specific set of users and subjects,
please use the one or the ones that suit you the most. please use the one or the ones that suit you the most.
Each mailing list have hundreds up to thousands of readers, meaning that Each mailing list has hundreds up to thousands of readers, meaning that
each mail sent will be received and read by a very large amount of people. each mail sent will be received and read by a very large number of people.
People from various cultures, regions, religions and continents. People from various cultures, regions, religions and continents.
1.2 Netiquette 1.2 Netiquette
Netiquette is a common name for how to behave on the internet. Of course, in Netiquette is a common term for how to behave on the internet. Of course, in
each particular group and subculture there will be differences in what is each particular group and subculture there will be differences in what is
acceptable and what is considered good manners. acceptable and what is considered good manners.
This document outlines what we in the cURL project considers to be good This document outlines what we in the curl project consider to be good
etiquette, and primarily this focus on how to behave on and how to use our etiquette, and primarily this focus on how to behave on and how to use our
mailing lists. mailing lists.
@ -56,7 +57,7 @@ MAIL ETIQUETTE
Many people send one question to one person. One person gets many mails, and Many people send one question to one person. One person gets many mails, and
there is only one person who can give you a reply. The question may be there is only one person who can give you a reply. The question may be
something that other people are also wanting to ask. These other people have something that other people would also like to ask. These other people have
no way to read the reply, but to ask the one person the question. The one no way to read the reply, but to ask the one person the question. The one
person consequently gets overloaded with mail. person consequently gets overloaded with mail.
@ -79,8 +80,8 @@ MAIL ETIQUETTE
1.5 Moderation of new posters 1.5 Moderation of new posters
Several of the curl mailing lists automatically make all posts from new Several of the curl mailing lists automatically make all posts from new
subscribers require moderation. This means that after you've subscribed and subscribers be moderated. This means that after you've subscribed and
send your first mail to a list, that mail will not be let through to the sent your first mail to a list, that mail will not be let through to the
list until a mailing list administrator has verified that it is OK and list until a mailing list administrator has verified that it is OK and
permits it to get posted. permits it to get posted.
@ -104,26 +105,26 @@ MAIL ETIQUETTE
messages" messages"
No matter what, we NEVER EVER respond to trolls or spammers on the list. If No matter what, we NEVER EVER respond to trolls or spammers on the list. If
you believe the list admin should do something particular, contact him/her you believe the list admin should do something in particular, contact him/her
off-list. The subject will be taken care of as good as possible to prevent off-list. The subject will be taken care of as much as possible to prevent
repeated offenses, but responding on the list to such messages never lead to repeated offenses, but responding on the list to such messages never leads to
anything good and only puts the light even more on the offender: which was anything good and only puts the light even more on the offender: which was
the entire purpose of it getting to the list in the first place. the entire purpose of it getting sent to the list in the first place.
Don't feed the trolls! Don't feed the trolls!
1.7 How to unsubscribe 1.7 How to unsubscribe
You unsubscribe the same way you subscribed in the first place. You go to You can unsubscribe the same way you subscribed in the first place. You go
the page for the particular mailing list you're subscribed to and you enter to the page for the particular mailing list you're subscribed to and you enter
your email address and password and press the unsubscribe button. your email address and password and press the unsubscribe button.
Also, this information is included in the headers of every mail that is sent Also, the instructions to unsubscribe are included in the headers of every
out to all curl related mailing lists and there's footer in each mail that mail that is sent out to all curl related mailing lists and there's a footer
links to the "admin" page on which you can unsubscribe and change other in each mail that links to the "admin" page on which you can unsubscribe and
options. change other options.
You NEVER EVER email the mailing list requesting someone else to get you off You NEVER EVER email the mailing list requesting someone else to take you off
the list. the list.
1.8 I posted, now what? 1.8 I posted, now what?
@ -132,35 +133,56 @@ MAIL ETIQUETTE
send the email, your post will just be silently discarded. send the email, your post will just be silently discarded.
If you posted for the first time to the mailing list, you first need to wait If you posted for the first time to the mailing list, you first need to wait
for an administrator to allow your email to go through. This normally for an administrator to allow your email to go through (moderated). This normally
happens very quickly but in case we're asleep, you may have to wait a few happens very quickly but in case we're asleep, you may have to wait a few
hours. hours.
Once your email goes through it is sent out to several hundred or even Once your email goes through it is sent out to several hundred or even
thousand recipients. Your email may cover an area that not that many people thousands of recipients. Your email may cover an area that not that many people
know about or are interested in. Or possibly the person who knows about it know about or are interested in. Or possibly the person who knows about it
is on vacation or under a very heavy work load right now. You have to wait is on vacation or under a very heavy work load right now. You may have to wait
for a response and you must not expect to get a response at all, but for a response and you should not expect to get a response at all, but
hopefully you get an answer within a couple of days. hopefully you get an answer within a couple of days.
You do yourself and all of us a service when you include as many details as You do yourself and all of us a service when you include as many details as
possible already in your first email. Mention your operating system and possible already in your first email. Mention your operating system and
environment. Tell us which curl version you're using and tell us what you environment. Tell us which curl version you're using and tell us what you
did, what happened and what you expected would happen. Preferably, show us did, what happened and what you expected would happen. Preferably, show us
what you did in details enough to allow others to help point out the problem what you did with details enough to allow others to help point out the problem
or repeat the same steps in their places. or repeat the same steps in their locations.
Failing to include details will only delay responses and make people respond Failing to include details will only delay responses and make people respond
and ask for the details and you have to send a follow-up email that includes and ask for more details and you will have to send a follow-up email that
them. includes them.
Expect the responses to primarily help YOU debug the issue, or ask you Expect the responses to primarily help YOU debug the issue, or ask YOU
questions that can lead you or others towards a solution or explanation to questions that can lead you or others towards a solution or explanation to
whatever you experience. whatever you experience.
If you are a repeat offender to the guidelines outlined in this document, If you are a repeat offender to the guidelines outlined in this document,
chances are that people will ignore you at will and your chances to get chances are that people will ignore you at will and your chances to get
responses will greatly diminish. responses in the future will greatly diminish.
1.9 Your emails are public
Your email, its contents and all its headers and the details in those
headers will be received by every subscriber of the mailing list that you
send your email to.
Your email as sent to a curl mailing list will end up in mail archives, on
the curl web site and elsewhere, for others to see and read. Today and in
the future. In addition to the archives, the mail is sent out to thousands
of individuals. There is no way to undo a sent email.
When sending emails to a curl mailing list, do not include sensitive
information such as user names and passwords; use fake ones, temporary ones
or just remove them completely from the mail. Note that this includes base64
encoded HTTP Basic auth headers.
This public nature of the curl mailing lists makes automaticly inserted mail
footers about mails being "private" or "only meant for the receipient" or
similar even more silly than usual. Because they are absolutely not private
when sent to a public mailing list.
2. Sending mail 2. Sending mail
@ -183,7 +205,7 @@ MAIL ETIQUETTE
We're actively discouraging replying back to the single person by setting We're actively discouraging replying back to the single person by setting
the Reply-To: field in outgoing mails back to the mailing list address, the Reply-To: field in outgoing mails back to the mailing list address,
making it harder for people to mail the author only by mistake. making it harder for people to mail the author directly, if only by mistake.
2.3 Use a Sensible Subject 2.3 Use a Sensible Subject
@ -198,10 +220,9 @@ MAIL ETIQUETTE
mail conversation below. It forces users to read the mail in a backwards mail conversation below. It forces users to read the mail in a backwards
order to properly understand it. order to properly understand it.
This is why top posting is so bad: This is why top posting is so bad (in top posting order):
A: Because it messes up the order in which people normally read A: Because it messes up the order in which people normally read text.
text.
Q: Why is top-posting such a bad thing? Q: Why is top-posting such a bad thing?
A: Top-posting. A: Top-posting.
Q: What is the most annoying thing in e-mail? Q: What is the most annoying thing in e-mail?
@ -230,7 +251,7 @@ MAIL ETIQUETTE
Quote as little as possible. Just enough to provide the context you cannot Quote as little as possible. Just enough to provide the context you cannot
leave out. A lengthy description can be found here: leave out. A lengthy description can be found here:
http://www.netmeister.org/news/learn2quote.html https://www.netmeister.org/news/learn2quote.html
2.7 Digest 2.7 Digest
@ -255,11 +276,10 @@ MAIL ETIQUETTE
If you are the one who asks, please consider responding once more in case If you are the one who asks, please consider responding once more in case
one of the hints was what solved your problems. The guys who write answers one of the hints was what solved your problems. The guys who write answers
feel good to know that they provided a good answer and that you fixed the feel good to know that they provided a good answer and that you fixed the
problem. Far too often, the person who asked the question is never heard of problem. Far too often, the person who asked the question is never heard from
again, and we never get to know if he/she is gone because the problem was again, and we never get to know if he/she is gone because the problem was
solved or perhaps because the problem was unsolvable! solved or perhaps because the problem was unsolvable!
Getting the solution posted also helps other users that experience the same Getting the solution posted also helps other users that experience the same
problem(s). They get to see (possibly in the web archives) that the problem(s). They get to see (possibly in the web archives) that the
suggested fixes actually has helped at least one person. suggested fixes actually has helped at least one person.

View File

@ -3,7 +3,7 @@ LATEST VERSION
You always find news about what's going on as well as the latest versions You always find news about what's going on as well as the latest versions
from the curl web pages, located at: from the curl web pages, located at:
http://curl.haxx.se https://curl.haxx.se
SIMPLE USAGE SIMPLE USAGE
@ -815,16 +815,16 @@ LDAP
If you have installed the OpenLDAP library, curl can take advantage of it If you have installed the OpenLDAP library, curl can take advantage of it
and offer ldap:// support. and offer ldap:// support.
On Windows, curl will use WinLDAP from Platform SDK by default.
Default protocol version used by curl is LDAPv3. LDAPv2 will be used as
fallback mechanism in case if LDAPv3 will fail to connect.
LDAP is a complex thing and writing an LDAP query is not an easy task. I do LDAP is a complex thing and writing an LDAP query is not an easy task. I do
advise you to dig up the syntax description for that elsewhere. Two places advise you to dig up the syntax description for that elsewhere. One such
that might suit you are: place might be:
Netscape's "Netscape Directory SDK 3.0 for C Programmer's Guide Chapter 10: RFC 2255, "The LDAP URL Format" https://curl.haxx.se/rfc/rfc2255.txt
Working with LDAP URLs":
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
To show you an example, this is how I can get all people from my local LDAP To show you an example, this is how I can get all people from my local LDAP
server that has a certain sub-domain in their email address: server that has a certain sub-domain in their email address:
@ -834,6 +834,20 @@ LDAP
If I want the same info in HTML format, I can get it by not using the -B If I want the same info in HTML format, I can get it by not using the -B
(enforce ASCII) flag. (enforce ASCII) flag.
You also can use authentication when accessing LDAP catalog:
curl -u user:passwd "ldap://ldap.frontec.se/o=frontec??sub?mail=*"
curl "ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*"
By default, if user and password provided, OpenLDAP/WinLDAP will use basic
authentication. On Windows you can control this behavior by providing
one of --basic, --ntlm or --digest option in curl command line
curl --ntlm "ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*"
On Windows, if no user/password specified, auto-negotiation mechanism will
be used with current logon credentials (SSPI/SPNEGO).
ENVIRONMENT VARIABLES ENVIRONMENT VARIABLES
Curl reads and understands the following environment variables: Curl reads and understands the following environment variables:
@ -852,8 +866,11 @@ ENVIRONMENT VARIABLES
If the host name matches one of these strings, or the host is within the If the host name matches one of these strings, or the host is within the
domain of one of these strings, transactions with that node will not be domain of one of these strings, transactions with that node will not be
proxied. proxied. When a domain is used, it needs to start with a period. A user can
specify that both www.example.com and foo.example.com should not uses a
proxy by setting NO_PROXY to ".example.com". By including the full name you
can exclude specific host names, so to make www.example.com not use a proxy
but still have foo.example.com do it, set NO_PROXY to "www.example.com"
The usage of the -x/--proxy flag overrides the environment variables. The usage of the -x/--proxy flag overrides the environment variables.
@ -1011,7 +1028,7 @@ MAILING LISTS
For your convenience, we have several open mailing lists to discuss curl, For your convenience, we have several open mailing lists to discuss curl,
its development and things relevant to this. Get all info at its development and things relevant to this. Get all info at
http://curl.haxx.se/mail/. Some of the lists available are: https://curl.haxx.se/mail/. Some of the lists available are:
curl-users curl-users

View File

@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -22,33 +22,54 @@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1 # EXTRA_DIST breaks with $(abs_builddir) so build it using this variable
noinst_man_MANS = mk-ca-bundle.1 # but distribute it (using the relative file name) in the next variable
man_MANS = $(abs_builddir)/curl.1
noinst_man_MANS = curl.1 mk-ca-bundle.1
dist_man_MANS = curl-config.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
MANDISTPAGES = curl.1.dist curl-config.1.dist
HTMLPAGES = $(GENHTMLPAGES) index.html HTMLPAGES = $(GENHTMLPAGES) index.html
SUBDIRS = examples libcurl # Build targets in this file (.) before cmdline-opts to ensure that
# the curl.1 rule below runs first
SUBDIRS = . cmdline-opts
DIST_SUBDIRS = $(SUBDIRS) examples libcurl
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES) CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES) $(MANDISTPAGES) curl.1
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \ EXTRA_DIST = MANUAL BUGS CONTRIBUTE.md FAQ FEATURES INTERNALS.md SSLCERTS.md \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \ README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS KNOWN_BUGS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \ BINDINGS.md HISTORY.md INSTALL INSTALL.md LICENSE-MIXING.md \
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \ README.netware MAIL-ETIQUETTE HTTP-COOKIES.md SECURITY.md RELEASE-PROCEDURE \
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS SECURITY RELEASE-PROCEDURE \ SSL-PROBLEMS.md HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md CODE_STYLE.md \
SSL-PROBLEMS CHECKSRC.md CMakeLists.txt README.md CIPHERS.md INSTALL.cmake README.cmake \
$(noinst_man_MANS) HELP-US.md
MAN2HTML= roffit < $< >$@ MAN2HTML= roffit $< >$@
SUFFIXES = .1 .html .pdf SUFFIXES = .1 .html .pdf
# $(abs_builddir) is to disable VPATH when searching for this file, which
# would otherwise find the copy in $(srcdir) which breaks the $(HUGE)
# rule in src/Makefile.am in out-of-tree builds that references the file in the
# build directory.
#
# First, seed the used copy of curl.1 with the prebuilt copy (in an out-of-tree
# build), then run make recursively to rebuild it only if its dependencies
# have changed.
$(abs_builddir)/curl.1:
if test "$(top_builddir)x" != "$(top_srcdir)x" -a -e "$(srcdir)/curl.1"; then \
cp -fp "$(srcdir)/curl.1" $@; fi
cd cmdline-opts && $(MAKE)
html: $(HTMLPAGES) html: $(HTMLPAGES)
cd libcurl; make html cd libcurl && $(MAKE) html
pdf: $(PDFPAGES) pdf: $(PDFPAGES)
cd libcurl; make pdf cd libcurl && $(MAKE) pdf
.1.html: .1.html:
$(MAN2HTML) $(MAN2HTML)

View File

@ -11,17 +11,16 @@ README.netware
Curl has been successfully compiled with gcc / nlmconv on different flavours Curl has been successfully compiled with gcc / nlmconv on different flavours
of Linux as well as with the official Metrowerks CodeWarrior compiler. of Linux as well as with the official Metrowerks CodeWarrior compiler.
While not being the main development target, a continuously growing share of While not being the main development target, a continuously growing share of
curl users are NetWare-based, specially also consuming the lib from PHP. curl users are NetWare-based, especially also consuming the lib from PHP.
The unix-style man pages are tricky to read on windows, so therefore are all The unix-style man pages are tricky to read on windows, so therefore all
those pages converted to HTML as well as pdf, and included in the release those pages are also provided as web pages on the curl web site.
archives.
The main curl.1 man page is also "built-in" in the command line tool. Use a The main curl.1 man page is also "built-in" in the command line tool. Use a
command line similar to this in order to extract a separate text file: command line similar to this in order to extract a separate text file:
curl -M >manual.txt curl -M >manual.txt
Read the INSTALL file for instructions how to compile curl self. Read the INSTALL file for instructions on how to compile curl self.

View File

@ -12,15 +12,14 @@ README.win32
systems. While not being the main develop target, a fair share of curl users systems. While not being the main develop target, a fair share of curl users
are win32-based. are win32-based.
The unix-style man pages are tricky to read on windows, so therefore are all The unix-style man pages are tricky to read on windows, so therefore all
those pages converted to HTML as well as pdf, and included in the release those pages are also provided as web pages on the curl web site.
archives.
The main curl.1 man page is also "built-in" in the command line tool. Use a The main curl.1 man page is also "built-in" in the command line tool. Use a
command line similar to this in order to extract a separate text file: command line similar to this in order to extract a separate text file:
curl -M >manual.txt curl -M >manual.txt
Read the INSTALL file for instructions how to compile curl self. Read the INSTALL file for instructions on how to compile curl self.

View File

@ -1,9 +1,3 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
curl release procedure - how to do a release curl release procedure - how to do a release
============================================ ============================================
@ -17,8 +11,8 @@ in the source code repo
- make sure all relevant changes are committed on the master branch - make sure all relevant changes are committed on the master branch
- tag the git repo in this style: `git tag -a curl-7_34_0`. -a annotates the - tag the git repo in this style: `git tag -a curl-7_34_0`. -a annotates the
tag and we use underscores instead of dots in the version number. tag and we use underscores instead of dots in the version number.
- run "./maketgz 7.34.0" to build the release tarballs. It is important that - run "./maketgz 7.34.0" to build the release tarballs. It is important that
you run this on a machine with the correct set of autotools etc installed you run this on a machine with the correct set of autotools etc installed
as this is what then will be shipped and used by most users on *nix like as this is what then will be shipped and used by most users on *nix like
@ -47,6 +41,11 @@ in the curl-www repo
(the web site then updates its contents automatically) (the web site then updates its contents automatically)
on github
---------
- edit the newly made release tag so that it is listed as the latest release
inform inform
------ ------
@ -84,12 +83,10 @@ Coming dates
Based on the description above, here are some planned release dates (at the Based on the description above, here are some planned release dates (at the
time of this writing): time of this writing):
- February 25, 2015 (version 7.41.0) - June 14, 2017 (version 7.54.1)
- April 22, 2015 - August 9, 2017
- June 17, 2015 - October 4, 2017
- August 12, 2015 - November 29, 2017
- October 7, 2015 - January 24, 2018
- December 2, 2015 - March 21, 2018
- January 27, 2016 - May 16, 2018
- March 23, 2016
- May 18, 2016

View File

@ -36,7 +36,7 @@ This document lists documents and standards used by curl.
RFC 2109 - HTTP State Management Mechanism (cookie stuff) RFC 2109 - HTTP State Management Mechanism (cookie stuff)
- Also, read Netscape's specification at - Also, read Netscape's specification at
http://curl.haxx.se/rfc/cookie_spec.html https://curl.haxx.se/rfc/cookie_spec.html
RFC 2183 - The Content-Disposition Header Field RFC 2183 - The Content-Disposition Header Field

View File

@ -5,86 +5,51 @@ Roadmap of things Daniel Stenberg and Steve Holme want to work on next. It is
intended to serve as a guideline for others for information, feedback and intended to serve as a guideline for others for information, feedback and
possible participation. possible participation.
HTTP/2 QUIC
------ ----
- test suite The standardization process of QUIC has been taken to the IETF and can be
followed on the [IETF QUIC Mailing
list](https://www.ietf.org/mailman/listinfo/quic). I'd like us to get on the
bandwagon. Ideally, this would be done with a separate library/project to
handle the binary/framing layer in a similar fashion to how HTTP/2 is
implemented. This, to allow other projects to benefit from the work and to
thus broaden the interest and chance of others to participate.
Base this on existing nghttp2 server to start with to make functional HTTP cookies
tests. Later on we can adopt that code or work with nghttp2 to provide ways ------------
to have the http2 server respond with broken responses to make sure we deal
with that nicely as well.
To decide: if we need to bundle parts of the nghttp2 stuff that probably Two cookie drafts have been adopted by the httpwg in IETF and we should
won't be shipped by many distros. support them as the popular browsers will as well:
- multiplexing/pipelining [Deprecate modification of 'secure' cookies from non-secure
origins](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-00)
Add a bit to `CURLMOPT_PIPELINING` which then makes libcurl attempt to [Cookie Prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00)
multiplex HTTP/2 connections to the same host, using the HTTP1 pipelining
host matching logic. Doing multiple transfers to the same host using the
multi interface will then make them multiplexed. By default, this will
handle flow-control for the streams in an automatic fashion.
With multiplexed streams, we also need to make sure that we terminate [Firefox bug report about secure cookies](https://bugzilla.mozilla.org/show_bug.cgi?id=976073)
streams correctly when a single easy handle is removed from such a
connection.
Since HTTP/2 is designed to always use a single connection for each host
(origin really), it seems fair that with "pipelining" enabled there will be
no extra checks for number of streams etc added to the connection apart
from the maximum number set over the HTTP/2 protocol (the remote sets a
maximum) and only if that is reached, another connection gets created.
- stream properties API
Provide options for setting priorities and dependencies among the streams
(easy handles). They are mostly information set for the stream and sent to
the server so we don't have to add much logic for this.
- server push
Not exactly clear exactly how to support this API-wise, but by adding
handles without asking for a resource it could be a way to be prepared to
receive pushes in case such are sent. We probably need it to still specify
a URL with host name, port etc but we probably need a special option to
tell libcurl it is for server push purposes.
- provide option for HTTP/2 "prior knowledge" over clear text
As it would avoid the roundtrip-heavy Upgrade: procedures when you _know_
it speaks HTTP/2.
- provide option to allow curl to default to HTTP/2 only when using HTTPS
We could switch on HTTP/2 by-default for HTTPS quite easily and it
shouldn't hurt anyone, while HTTP/2 for HTTP by default could introduce
lots of Upgrade: roundtrips that users won't like. So a separated option
alternative makes sense.
SRV records SRV records
----------- -----------
How to find services for specific domains/hosts. How to find services for specific domains/hosts.
HTTPS to proxy
--------------
To avoid network traffic to/from the proxy getting snooped on.
curl_formadd() curl_formadd()
-------------- --------------
make sure there's an easy handle passed in to `curl_formadd()`, make sure there's an easy handle passed in to `curl_formadd()`,
`curl_formget()` and `curl_formfree()` by adding replacement functions and `curl_formget()` and `curl_formfree()` by adding replacement functions and
deprecating the old ones to allow custom mallocs and more deprecating the old ones to allow custom mallocs and more.
third-party SASL Or perhaps even better: revamp the formpost API completely while we're at it
and making something that is easier to use and understand:
https://github.com/curl/curl/wiki/formpost-API-redesigned
Third-party SASL
---------------- ----------------
add support for third-party SASL libraries such as Cyrus SASL - may need to Add support for third-party SASL libraries such as Cyrus SASL.
move existing native and SSPI based authentication into vsasl folder after
reworking HTTP and SASL code
SASL authentication in LDAP SASL authentication in LDAP
--------------------------- ---------------------------
@ -135,18 +100,14 @@ Improve
2. curl -h output (considered overwhelming to users) 2. curl -h output (considered overwhelming to users)
3. we have > 160 command line options, is there a way to redo things to 3. we have > 200 command line options, is there a way to redo things to
simplify or improve the situation as we are likely to keep adding simplify or improve the situation as we are likely to keep adding
features/options in the future too features/options in the future too
4. docs (considered "bad" by users but how do we make it better?) 4. authentication framework (consider merging HTTP and SASL authentication to
- split up curl.1
5. authentication framework (consider merging HTTP and SASL authentication to
give one API for protocols to call) give one API for protocols to call)
6. Perform some of the clean up from the TODO document, removing old 5. Perform some of the clean up from the TODO document, removing old
definitions and such like that are currently earmarked to be removed years definitions and such like that are currently earmarked to be removed years
ago ago

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -136,7 +136,7 @@ The Art Of Scripting HTTP Requests Using Curl
The Uniform Resource Locator format is how you specify the address of a The Uniform Resource Locator format is how you specify the address of a
particular resource on the Internet. You know these, you've seen URLs like particular resource on the Internet. You know these, you've seen URLs like
http://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the https://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the
canonical spec. And yeah, the formal name is not URL, it is URI. canonical spec. And yeah, the formal name is not URL, it is URI.
2.2 Host 2.2 Host
@ -145,7 +145,7 @@ The Art Of Scripting HTTP Requests Using Curl
address and that's what curl will communicate with. Alternatively you specify address and that's what curl will communicate with. Alternatively you specify
the IP address directly in the URL instead of a name. the IP address directly in the URL instead of a name.
For development and other trying out situation, you can point out a different For development and other trying out situations, you can point to a different
IP address for a host name than what would otherwise be used, by using curl's IP address for a host name than what would otherwise be used, by using curl's
--resolve option: --resolve option:
@ -153,7 +153,7 @@ The Art Of Scripting HTTP Requests Using Curl
2.3 Port number 2.3 Port number
Each protocol curl supports operate on a default port number, be it over TCP Each protocol curl supports operates on a default port number, be it over TCP
or in some cases UDP. Normally you don't have to take that into or in some cases UDP. Normally you don't have to take that into
consideration, but at times you run test servers on other ports or consideration, but at times you run test servers on other ports or
similar. Then you can specify the port number in the URL with a colon and a similar. Then you can specify the port number in the URL with a colon and a
@ -164,7 +164,7 @@ The Art Of Scripting HTTP Requests Using Curl
The port number you specify in the URL is the number that the server uses to The port number you specify in the URL is the number that the server uses to
offer its services. Sometimes you may use a local proxy, and then you may offer its services. Sometimes you may use a local proxy, and then you may
need to specify that proxy's port number separate on what curl needs to need to specify that proxy's port number separately for what curl needs to
connect to locally. Like when using a HTTP proxy on port 4321: connect to locally. Like when using a HTTP proxy on port 4321:
curl --proxy http://proxy.example.org:4321 http://remote.example.org/ curl --proxy http://proxy.example.org:4321 http://remote.example.org/
@ -172,7 +172,7 @@ The Art Of Scripting HTTP Requests Using Curl
2.4 User name and password 2.4 User name and password
Some services are setup to require HTTP authentication and then you need to Some services are setup to require HTTP authentication and then you need to
provide name and password which then is transferred to the remote site in provide name and password which is then transferred to the remote site in
various ways depending on the exact authentication protocol used. various ways depending on the exact authentication protocol used.
You can opt to either insert the user and password in the URL or you can You can opt to either insert the user and password in the URL or you can
@ -198,12 +198,12 @@ The Art Of Scripting HTTP Requests Using Curl
3.1 GET 3.1 GET
The simplest and most common request/operation made using HTTP is to get a The simplest and most common request/operation made using HTTP is to GET a
URL. The URL could itself refer to a web page, an image or a file. The client URL. The URL could itself refer to a web page, an image or a file. The client
issues a GET request to the server and receives the document it asked for. issues a GET request to the server and receives the document it asked for.
If you issue the command line If you issue the command line
curl http://curl.haxx.se curl https://curl.haxx.se
you get a web page returned in your terminal window. The entire HTML document you get a web page returned in your terminal window. The entire HTML document
that that URL holds. that that URL holds.
@ -269,14 +269,14 @@ The Art Of Scripting HTTP Requests Using Curl
4.1 Forms explained 4.1 Forms explained
Forms are the general way a web site can present a HTML page with fields for Forms are the general way a web site can present a HTML page with fields for
the user to enter data in, and then press some kind of 'OK' or 'submit' the user to enter data in, and then press some kind of 'OK' or 'Submit'
button to get that data sent to the server. The server then typically uses button to get that data sent to the server. The server then typically uses
the posted data to decide how to act. Like using the entered words to search the posted data to decide how to act. Like using the entered words to search
in a database, or to add the info in a bug track system, display the entered in a database, or to add the info in a bug tracking system, display the entered
address on a map or using the info as a login-prompt verifying that the user address on a map or using the info as a login-prompt verifying that the user
is allowed to see what it is about to see. is allowed to see what it is about to see.
Of course there has to be some kind of program in the server end to receive Of course there has to be some kind of program on the server end to receive
the data you send. You cannot just invent something out of the air. the data you send. You cannot just invent something out of the air.
4.2 GET 4.2 GET
@ -369,7 +369,7 @@ The Art Of Scripting HTTP Requests Using Curl
4.5 Hidden Fields 4.5 Hidden Fields
A very common way for HTML based application to pass state information A very common way for HTML based applications to pass state information
between pages is to add hidden fields to the forms. Hidden fields are between pages is to add hidden fields to the forms. Hidden fields are
already filled in, they aren't displayed to the user and they get passed already filled in, they aren't displayed to the user and they get passed
along just as all the other fields. along just as all the other fields.
@ -383,7 +383,7 @@ The Art Of Scripting HTTP Requests Using Curl
<input type=submit name="press" value="OK"> <input type=submit name="press" value="OK">
</form> </form>
To post this with curl, you won't have to think about if the fields are To POST this with curl, you won't have to think about if the fields are
hidden or not. To curl they're all the same: hidden or not. To curl they're all the same:
curl --data "birthyear=1905&press=OK&person=daniel" [URL] curl --data "birthyear=1905&press=OK&person=daniel" [URL]
@ -405,7 +405,7 @@ The Art Of Scripting HTTP Requests Using Curl
5.1 PUT 5.1 PUT
The perhaps best way to upload data to a HTTP server is to use PUT. Then Perhaps the best way to upload data to a HTTP server is to use PUT. Then
again, this of course requires that someone put a program or script on the again, this of course requires that someone put a program or script on the
server end that knows how to receive a HTTP PUT stream. server end that knows how to receive a HTTP PUT stream.
@ -446,7 +446,7 @@ The Art Of Scripting HTTP Requests Using Curl
If your proxy requires the authentication to be done using the NTLM method, If your proxy requires the authentication to be done using the NTLM method,
use --proxy-ntlm, if it requires Digest use --proxy-digest. use --proxy-ntlm, if it requires Digest use --proxy-digest.
If you use any one these user+password options but leave out the password If you use any one of these user+password options but leave out the password
part, curl will prompt for the password interactively. part, curl will prompt for the password interactively.
6.4 Hiding credentials 6.4 Hiding credentials
@ -508,7 +508,7 @@ The Art Of Scripting HTTP Requests Using Curl
to redirect is Location:. to redirect is Location:.
Curl does not follow Location: headers by default, but will simply display Curl does not follow Location: headers by default, but will simply display
such pages in the same manner it display all HTTP replies. It does however such pages in the same manner it displays all HTTP replies. It does however
feature an option that will make it attempt to follow the Location: pointers. feature an option that will make it attempt to follow the Location: pointers.
To tell curl to follow a Location: To tell curl to follow a Location:
@ -562,7 +562,7 @@ The Art Of Scripting HTTP Requests Using Curl
(Take note that the --cookie-jar option described below is a better way to (Take note that the --cookie-jar option described below is a better way to
store cookies.) store cookies.)
Curl has a full blown cookie parsing engine built-in that comes to use if you Curl has a full blown cookie parsing engine built-in that comes in use if you
want to reconnect to a server and use cookies that were stored from a want to reconnect to a server and use cookies that were stored from a
previous connection (or hand-crafted manually to fool the server into previous connection (or hand-crafted manually to fool the server into
believing you had a previous connection). To use previously stored cookies, believing you had a previous connection). To use previously stored cookies,
@ -592,7 +592,7 @@ The Art Of Scripting HTTP Requests Using Curl
10.1 HTTPS is HTTP secure 10.1 HTTPS is HTTP secure
There are a few ways to do secure HTTP transfers. The by far most common There are a few ways to do secure HTTP transfers. By far the most common
protocol for doing this is what is generally known as HTTPS, HTTP over protocol for doing this is what is generally known as HTTPS, HTTP over
SSL. SSL encrypts all the data that is sent and received over the network and SSL. SSL encrypts all the data that is sent and received over the network and
thus makes it harder for attackers to spy on sensitive information. thus makes it harder for attackers to spy on sensitive information.
@ -628,7 +628,7 @@ The Art Of Scripting HTTP Requests Using Curl
More about server certificate verification and ca cert bundles can be read More about server certificate verification and ca cert bundles can be read
in the SSLCERTS document, available online here: in the SSLCERTS document, available online here:
http://curl.haxx.se/docs/sslcerts.html https://curl.haxx.se/docs/sslcerts.html
At times you may end up with your own CA cert store and then you can tell At times you may end up with your own CA cert store and then you can tell
curl to use that to verify the server's certificate: curl to use that to verify the server's certificate:
@ -680,7 +680,7 @@ The Art Of Scripting HTTP Requests Using Curl
12.1 Some login tricks 12.1 Some login tricks
While not strictly just HTTP related, it still cause a lot of people problems While not strictly just HTTP related, it still causes a lot of people problems
so here's the executive run-down of how the vast majority of all login forms so here's the executive run-down of how the vast majority of all login forms
work and how to login to them using curl. work and how to login to them using curl.
@ -693,7 +693,7 @@ The Art Of Scripting HTTP Requests Using Curl
make sure you got there through their login page) so you should make a habit make sure you got there through their login page) so you should make a habit
of first getting the login-form page to capture the cookies set there. of first getting the login-form page to capture the cookies set there.
Some web-based login systems features various amounts of javascript, and Some web-based login systems feature various amounts of javascript, and
sometimes they use such code to set or modify cookie contents. Possibly they sometimes they use such code to set or modify cookie contents. Possibly they
do that to prevent programmed logins, like this manual describes how to... do that to prevent programmed logins, like this manual describes how to...
Anyway, if reading the code isn't enough to let you repeat the behavior Anyway, if reading the code isn't enough to let you repeat the behavior
@ -755,4 +755,4 @@ The Art Of Scripting HTTP Requests Using Curl
14.2 Sites 14.2 Sites
http://curl.haxx.se is the home of the cURL project https://curl.haxx.se is the home of the curl project

View File

@ -1,22 +1,18 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Version Numbers and Releases Version Numbers and Releases
============================
Curl is not only curl. Curl is also libcurl. They're actually individually Curl is not only curl. Curl is also libcurl. They're actually individually
versioned, but they mostly follow each other rather closely. versioned, but they mostly follow each other rather closely.
The version numbering is always built up using the same system: The version numbering is always built up using the same system:
X.Y[.Z] X.Y.Z
Where - X is main version number
X is main version number - Y is release number
Y is release number - Z is patch number
Z is patch number
## Bumping numbers
One of these numbers will get bumped in each new release. The numbers to the One of these numbers will get bumped in each new release. The numbers to the
right of a bumped number will be reset to zero. If Z is zero, it may not be right of a bumped number will be reset to zero. If Z is zero, it may not be
@ -57,4 +53,4 @@ Version Numbers and Releases
release. It makes comparisons with greater than and less than work. release. It makes comparisons with greater than and less than work.
This number is also available as three separate defines: This number is also available as three separate defines:
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH. `LIBCURL_VERSION_MAJOR`, `LIBCURL_VERSION_MINOR` and `LIBCURL_VERSION_PATCH`.

View File

@ -9,7 +9,7 @@
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
.\" * are also available at http://curl.haxx.se/docs/copyright.html. .\" * are also available at https://curl.haxx.se/docs/copyright.html.
.\" * .\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell .\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is .\" * copies of the Software, and permit persons to whom the Software is
@ -20,7 +20,8 @@
.\" * .\" *
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual" .TH curl-config 1 "February 03, 2016" "Curl 7.56.0" "curl-config manual"
.SH NAME .SH NAME
curl-config \- Get information about a libcurl installation curl-config \- Get information about a libcurl installation
.SH SYNOPSIS .SH SYNOPSIS

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,9 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Example application source code using the multi interface to download many /* <DESC>
* files, but with a capped maximum amount of simultaneous transfers. * Source code using the multi interface to download many
* * files, with a capped maximum amount of simultaneous transfers.
* </DESC>
* Written by Michael Wallner * Written by Michael Wallner
*/ */
@ -85,7 +86,7 @@ static const char *urls[] = {
}; };
#define MAX 10 /* number of simultaneous transfers */ #define MAX 10 /* number of simultaneous transfers */
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */ #define CNT sizeof(urls)/sizeof(char *) /* total number of transfers to do */
static size_t cb(char *d, size_t n, size_t l, void *p) static size_t cb(char *d, size_t n, size_t l, void *p)
{ {
@ -113,7 +114,7 @@ int main(void)
CURLM *cm; CURLM *cm;
CURLMsg *msg; CURLMsg *msg;
long L; long L;
unsigned int C=0; unsigned int C = 0;
int M, Q, U = -1; int M, Q, U = -1;
fd_set R, W, E; fd_set R, W, E;
struct timeval T; struct timeval T;
@ -126,50 +127,51 @@ int main(void)
uses */ uses */
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX); curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);
for (C = 0; C < MAX; ++C) { for(C = 0; C < MAX; ++C) {
init(cm, C); init(cm, C);
} }
while (U) { while(U) {
curl_multi_perform(cm, &U); curl_multi_perform(cm, &U);
if (U) { if(U) {
FD_ZERO(&R); FD_ZERO(&R);
FD_ZERO(&W); FD_ZERO(&W);
FD_ZERO(&E); FD_ZERO(&E);
if (curl_multi_fdset(cm, &R, &W, &E, &M)) { if(curl_multi_fdset(cm, &R, &W, &E, &M)) {
fprintf(stderr, "E: curl_multi_fdset\n"); fprintf(stderr, "E: curl_multi_fdset\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (curl_multi_timeout(cm, &L)) { if(curl_multi_timeout(cm, &L)) {
fprintf(stderr, "E: curl_multi_timeout\n"); fprintf(stderr, "E: curl_multi_timeout\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (L == -1) if(L == -1)
L = 100; L = 100;
if (M == -1) { if(M == -1) {
#ifdef WIN32 #ifdef WIN32
Sleep(L); Sleep(L);
#else #else
sleep(L / 1000); sleep((unsigned int)L / 1000);
#endif #endif
} else { }
else {
T.tv_sec = L/1000; T.tv_sec = L/1000;
T.tv_usec = (L%1000)*1000; T.tv_usec = (L%1000)*1000;
if (0 > select(M+1, &R, &W, &E, &T)) { if(0 > select(M + 1, &R, &W, &E, &T)) {
fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n", fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n",
M+1, L, errno, strerror(errno)); M + 1, L, errno, strerror(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
} }
while ((msg = curl_multi_info_read(cm, &Q))) { while((msg = curl_multi_info_read(cm, &Q))) {
if (msg->msg == CURLMSG_DONE) { if(msg->msg == CURLMSG_DONE) {
char *url; char *url;
CURL *e = msg->easy_handle; CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url); curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
@ -181,7 +183,7 @@ int main(void)
else { else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg); fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
} }
if (C < CNT) { if(C < CNT) {
init(cm, C++); init(cm, C++);
U++; /* just to prevent it from remaining at 0 if there are more U++; /* just to prevent it from remaining at 0 if there are more
URLs to get */ URLs to get */

View File

@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -30,13 +30,9 @@ EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
# being currently built and tested are searched before the library which # being currently built and tested are searched before the library which
# might possibly already be installed in the system. # might possibly already be installed in the system.
# #
# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h
# $(top_builddir)/include for generated curlbuild.h inc. from lib/curl_setup.h
# $(top_srcdir)/include is for libcurl's external include files # $(top_srcdir)/include is for libcurl's external include files
AM_CPPFLAGS = -I$(top_builddir)/include/curl \ AM_CPPFLAGS = -I$(top_srcdir)/include
-I$(top_builddir)/include \
-I$(top_srcdir)/include
LIBDIR = $(top_builddir)/lib LIBDIR = $(top_builddir)/lib
@ -61,3 +57,6 @@ endif
include Makefile.inc include Makefile.inc
all: $(check_PROGRAMS) all: $(check_PROGRAMS)
checksrc:
@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c

View File

@ -9,7 +9,7 @@
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is

View File

@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -26,17 +26,19 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
https multi-app multi-debugcallback multi-double multi-post multi-single \ https multi-app multi-debugcallback multi-double multi-post multi-single \
persistant post-callback postit2 sepheaders simple simplepost simplessl \ persistant post-callback postit2 sepheaders simple simplepost simplessl \
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \ sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
smtp-mail smtp-multi smtp-ssl smtp-tls smtp-vrfy smtp-expn rtsp \ smtp-mail smtp-mime smtp-multi smtp-ssl smtp-tls smtp-vrfy smtp-expn \
externalsocket resolve progressfunc pop3-retr pop3-list pop3-uidl \ rtsp externalsocket resolve progressfunc pop3-retr pop3-list pop3-uidl \
pop3-dele pop3-top pop3-stat pop3-noop pop3-ssl pop3-tls pop3-multi \ pop3-dele pop3-top pop3-stat pop3-noop pop3-ssl pop3-tls pop3-multi \
imap-list imap-lsub imap-fetch imap-store imap-append imap-examine \ imap-list imap-lsub imap-fetch imap-store imap-append imap-examine \
imap-search imap-create imap-delete imap-copy imap-noop imap-ssl \ imap-search imap-create imap-delete imap-copy imap-noop imap-ssl \
imap-tls imap-multi url2file sftpget ftpsget postinmemory imap-tls imap-multi url2file sftpget ftpsget postinmemory http2-download \
http2-upload http2-serverpush getredirect ftpuploadfrommem \
ftpuploadresume sslbackend postit2-formadd multi-formadd
# These examples require external dependencies that may not be commonly # These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here. # available on POSIX systems, so don't bother attempting to compile them here.
COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \ ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \ opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \ smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
multi-uv.c xmlstream.c usercertinmem.c sessioninfo.c multi-uv.c xmlstream.c usercertinmem.c sessioninfo.c

View File

@ -9,7 +9,7 @@
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -50,7 +50,7 @@ LIBRTMP_PATH = ../../../librtmp-2.4
endif endif
# Edit the path below to point to the base of your libidn package. # Edit the path below to point to the base of your libidn package.
ifndef LIBIDN_PATH ifndef LIBIDN_PATH
LIBIDN_PATH = ../../../libidn-1.30 LIBIDN_PATH = ../../../libidn-1.32
endif endif
# Edit the path below to point to the base of your MS IDN package. # Edit the path below to point to the base of your MS IDN package.
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 # Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
@ -64,7 +64,7 @@ LDAP_SDK = c:/novell/ndk/cldapsdk/win32
endif endif
# Edit the path below to point to the base of your nghttp2 package. # Edit the path below to point to the base of your nghttp2 package.
ifndef NGHTTP2_PATH ifndef NGHTTP2_PATH
NGHTTP2_PATH = ../../../nghttp2-0.7.13 NGHTTP2_PATH = ../../../nghttp2-1.0.0
endif endif
PROOT = ../.. PROOT = ../..
@ -84,7 +84,7 @@ endif
endif endif
CC = $(CROSSPREFIX)gcc CC = $(CROSSPREFIX)gcc
CFLAGS = -g -O2 -Wall CFLAGS = -g -O2 -Wall -W
CFLAGS += -fno-strict-aliasing CFLAGS += -fno-strict-aliasing
ifeq ($(ARCH),w64) ifeq ($(ARCH),w64)
CFLAGS += -m64 -D_AMD64_ CFLAGS += -m64 -D_AMD64_

View File

@ -34,7 +34,7 @@ endif
# Edit the path below to point to the base of your libidn package. # Edit the path below to point to the base of your libidn package.
ifndef LIBIDN_PATH ifndef LIBIDN_PATH
LIBIDN_PATH = ../../../libidn-1.30 LIBIDN_PATH = ../../../libidn-1.32
endif endif
# Edit the path below to point to the base of your librtmp package. # Edit the path below to point to the base of your librtmp package.
@ -60,11 +60,11 @@ endif
TARGET = examples TARGET = examples
VERSION = $(LIBCURL_VERSION) VERSION = $(LIBCURL_VERSION)
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR) COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
DESCR = cURL ($(LIBARCH)) DESCR = curl ($(LIBARCH))
MTSAFE = YES MTSAFE = YES
STACK = 8192 STACK = 8192
SCREEN = Example Program SCREEN = Example Program
# Comment the line below if you dont want to load protected automatically. # Comment the line below if you don't want to load protected automatically.
# LDRING = 3 # LDRING = 3
# Uncomment the next line to enable linking with POSIX semantics. # Uncomment the next line to enable linking with POSIX semantics.
@ -136,7 +136,7 @@ endif
CFLAGS += -align 4 CFLAGS += -align 4
else else
# PRELUDE = $(NDK_CLIB)/imports/clibpre.o # PRELUDE = $(NDK_CLIB)/imports/clibpre.o
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK # to avoid the __init_* / __deinit_* whoes don't use prelude from NDK
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
CFLAGS += -align 1 CFLAGS += -align 1
@ -159,7 +159,7 @@ else
endif endif
else else
# PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o # PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK # to avoid the __init_* / __deinit_* whoes don't use prelude from NDK
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip # http://www.gknw.net/development/mk_nlm/gcc_pre.zip
PRELUDE = $(NDK_ROOT)/pre/prelude.o PRELUDE = $(NDK_ROOT)/pre/prelude.o
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h

View File

@ -32,51 +32,7 @@ actually torture our web site with your tests! Thanks.
EXAMPLES EXAMPLES
anyauthput.c - HTTP PUT using "any" authentication method Each example source code file is designed to be and work stand-alone and
cacertinmem.c - Use a built-in PEM certificate to retrieve a https page rather self-explanatory. The examples may at times lack the level of error
cookie_interface.c - shows usage of simple cookie interface checks you need in a real world, but that is then only for the sake of
curlgtk.c - download using a GTK progress bar readability: to make the code smaller and easier to follow.
curlx.c - getting file info from the remote cert data
debug.c - showing how to use the debug callback
fileupload.c - uploading to a file:// URL
fopen.c - fopen() layer that supports opening URLs and files
ftpget.c - simple getting a file from FTP
ftpgetresp.c - get the response strings from the FTP server
ftpupload.c - upload a file to an FTP server
ftpuploadresume.c - resume an upload to an FTP server
getinfo.c - get the Content-Type from the recent transfer
getinmemory.c - download a file to memory only
ghiper.c - curl_multi_socket() using code with glib-2
hiperfifo.c - downloads all URLs written to the fifo, using
curl_multi_socket() and libevent
htmltidy.c - download a document and use libtidy to parse the HTML
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
page using libxml
http-post.c - HTTP POST
httpput.c - HTTP PUT a local file
https.c - simple HTTPS transfer
imap.c - simple IMAP transfer
multi-app.c - a multi-interface app
multi-debugcallback.c - a multi-interface app using the debug callback
multi-double.c - a multi-interface app doing two simultaneous transfers
multi-post.c - a multi-interface app doing a multipart formpost
multi-single.c - a multi-interface app getting a single file
multi-uv.c - a multi-interface app using libuv
multithread.c - an example using multi-treading transferring multiple files
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
persistant.c - request two URLs with a persistent connection
pop3s.c - POP3S transfer
pop3slist.c - POP3S LIST
post-callback.c - send a HTTP POST using a callback
postit2.c - send a HTTP multipart formpost
sampleconv.c - showing how a program on a non-ASCII platform would invoke
callbacks to do its own codeset conversions instead of using
the built-in iconv functions in libcurl
sepheaders.c - download headers to a separate file
simple.c - the most simple download a URL source
simplepost.c - HTTP POST
simplessl.c - HTTPS example with certificates many options set
synctime.c - Sync local time by extracting date from remote HTTP servers
url2file.c - download a document and store it in a file
xmlstream.c - Stream-parse a document using the streaming Expat parser
10-at-a-time.c - Download many files simultaneously, 10 at a time.

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,46 +19,27 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* HTTP PUT upload with authentiction using "any" method. libcurl picks the
* one the server supports/wants.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#ifdef WIN32 #ifdef WIN32
# include <io.h> # include <io.h>
#else #else
# ifdef __VMS
typedef int intptr_t;
# endif
# if !defined(_AIX) && !defined(__sgi) && !defined(__osf__)
# include <stdint.h>
# endif
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef _MSC_VER
# ifdef _WIN64
typedef __int64 intptr_t;
# else
typedef int intptr_t;
# endif
#endif
#include <curl/curl.h> #include <curl/curl.h>
#if LIBCURL_VERSION_NUM < 0x070c03 #if LIBCURL_VERSION_NUM < 0x070c03
#error "upgrade your libcurl to no less than 7.12.3" #error "upgrade your libcurl to no less than 7.12.3"
#endif #endif
#ifndef TRUE
#define TRUE 1
#endif
#if defined(_AIX) || defined(__sgi) || defined(__osf__)
#ifndef intptr_t
#define intptr_t long
#endif
#endif
/* /*
* This example shows a HTTP PUT operation with authentiction using "any" * This example shows a HTTP PUT operation with authentiction using "any"
* type. It PUTs a file given as a command line argument to the URL also given * type. It PUTs a file given as a command line argument to the URL also given
@ -73,7 +54,8 @@
/* ioctl callback function */ /* ioctl callback function */
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp) static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
{ {
intptr_t fd = (intptr_t)userp; int *fdp = (int *)userp;
int fd = *fdp;
(void)handle; /* not used in here */ (void)handle; /* not used in here */
@ -95,10 +77,11 @@ static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
/* read callback function, fread() look alike */ /* read callback function, fread() look alike */
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{ {
size_t retcode; ssize_t retcode;
curl_off_t nread; curl_off_t nread;
intptr_t fd = (intptr_t)stream; int *fdp = (int *)stream;
int fd = *fdp;
retcode = read(fd, ptr, size * nmemb); retcode = read(fd, ptr, size * nmemb);
@ -114,7 +97,7 @@ int main(int argc, char **argv)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
intptr_t hd ; int hd;
struct stat file_info; struct stat file_info;
char *file; char *file;
@ -123,11 +106,11 @@ int main(int argc, char **argv)
if(argc < 3) if(argc < 3)
return 1; return 1;
file= argv[1]; file = argv[1];
url = argv[2]; url = argv[2];
/* get the file size of the local file */ /* get the file size of the local file */
hd = open(file, O_RDONLY) ; hd = open(file, O_RDONLY);
fstat(hd, &file_info); fstat(hd, &file_info);
/* In windows, this will init the winsock stuff */ /* In windows, this will init the winsock stuff */
@ -140,20 +123,20 @@ int main(int argc, char **argv)
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* which file to upload */ /* which file to upload */
curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd); curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&hd);
/* set the ioctl function */ /* set the ioctl function */
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl); curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
/* pass the file descriptor to the ioctl callback as well */ /* pass the file descriptor to the ioctl callback as well */
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd); curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void *)&hd);
/* enable "uploading" (which means PUT when doing HTTP) */ /* enable "uploading" (which means PUT when doing HTTP) */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L) ; curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target URL, and note that this URL should also include a file /* specify target URL, and note that this URL should also include a file
name, not only a directory (as you can do with GTP uploads) */ name, not only a directory (as you can do with GTP uploads) */
curl_easy_setopt(curl,CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
/* and give the size of the upload, this supports large file sizes /* and give the size of the upload, this supports large file sizes
on systems that have general support for it */ on systems that have general support for it */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -20,11 +20,11 @@
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* demonstrate the use of multi socket interface with boost::asio
* </DESC>
*/
/* /*
* file: asiohiper.cpp
* Example program to demonstrate the use of multi socket interface
* with boost::asio
*
* This program is in c++ and uses boost::asio instead of libevent/libev. * This program is in c++ and uses boost::asio instead of libevent/libev.
* Requires boost::asio, boost::bind and boost::system * Requires boost::asio, boost::bind and boost::system
* *
@ -40,14 +40,15 @@
* Note: * Note:
* For the sake of simplicity, URL is hard coded to "www.google.com" * For the sake of simplicity, URL is hard coded to "www.google.com"
* *
* This is purely a demo app, all retrieved data is simply discarded by the write * This is purely a demo app, all retrieved data is simply discarded by the
* callback. * write callback.
*/ */
#include <curl/curl.h> #include <curl/curl.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <iostream>
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */ #define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
@ -84,14 +85,12 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
/* cancel running timer */ /* cancel running timer */
timer.cancel(); timer.cancel();
if(timeout_ms > 0) if(timeout_ms > 0) {
{
/* update timer */ /* update timer */
timer.expires_from_now(boost::posix_time::millisec(timeout_ms)); timer.expires_from_now(boost::posix_time::millisec(timeout_ms));
timer.async_wait(boost::bind(&timer_cb, _1, g)); timer.async_wait(boost::bind(&timer_cb, _1, g));
} }
else else if(timeout_ms == 0) {
{
/* call timeout function immediately */ /* call timeout function immediately */
boost::system::error_code error; /*success*/ boost::system::error_code error; /*success*/
timer_cb(error, g); timer_cb(error, g);
@ -103,11 +102,9 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
/* Die if we get a bad CURLMcode somewhere */ /* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(const char *where, CURLMcode code) static void mcode_or_die(const char *where, CURLMcode code)
{ {
if(CURLM_OK != code) if(CURLM_OK != code) {
{
const char *s; const char *s;
switch(code) switch(code) {
{
case CURLM_CALL_MULTI_PERFORM: case CURLM_CALL_MULTI_PERFORM:
s = "CURLM_CALL_MULTI_PERFORM"; s = "CURLM_CALL_MULTI_PERFORM";
break; break;
@ -157,10 +154,8 @@ static void check_multi_info(GlobalInfo *g)
fprintf(MSG_OUT, "\nREMAINING: %d", g->still_running); fprintf(MSG_OUT, "\nREMAINING: %d", g->still_running);
while((msg = curl_multi_info_read(g->multi, &msgs_left))) while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
{ if(msg->msg == CURLMSG_DONE) {
if(msg->msg == CURLMSG_DONE)
{
easy = msg->easy_handle; easy = msg->easy_handle;
res = msg->data.result; res = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
@ -175,34 +170,62 @@ static void check_multi_info(GlobalInfo *g)
} }
/* Called by asio when there is an action on a socket */ /* Called by asio when there is an action on a socket */
static void event_cb(GlobalInfo *g, boost::asio::ip::tcp::socket *tcp_socket, static void event_cb(GlobalInfo *g, curl_socket_t s,
int action) int action, const boost::system::error_code & error,
int *fdp)
{ {
fprintf(MSG_OUT, "\nevent_cb: action=%d", action); fprintf(MSG_OUT, "\nevent_cb: action=%d", action);
CURLMcode rc; if(socket_map.find(s) == socket_map.end()) {
rc = curl_multi_socket_action(g->multi, tcp_socket->native_handle(), action, fprintf(MSG_OUT, "\nevent_cb: socket already closed");
&g->still_running); return;
}
mcode_or_die("event_cb: curl_multi_socket_action", rc); /* make sure the event matches what are wanted */
check_multi_info(g); if(*fdp == action || *fdp == CURL_POLL_INOUT) {
CURLMcode rc;
if(error)
action = CURL_CSELECT_ERR;
rc = curl_multi_socket_action(g->multi, s, action, &g->still_running);
if(g->still_running <= 0) mcode_or_die("event_cb: curl_multi_socket_action", rc);
{ check_multi_info(g);
fprintf(MSG_OUT, "\nlast transfer done, kill timeout");
timer.cancel(); if(g->still_running <= 0) {
fprintf(MSG_OUT, "\nlast transfer done, kill timeout");
timer.cancel();
}
/* keep on watching.
* the socket may have been closed and/or fdp may have been changed
* in curl_multi_socket_action(), so check them both */
if(!error && socket_map.find(s) != socket_map.end() &&
(*fdp == action || *fdp == CURL_POLL_INOUT)) {
boost::asio::ip::tcp::socket *tcp_socket = socket_map.find(s)->second;
if(action == CURL_POLL_IN) {
tcp_socket->async_read_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, s,
action, _1, fdp));
}
if(action == CURL_POLL_OUT) {
tcp_socket->async_write_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, s,
action, _1, fdp));
}
}
} }
} }
/* Called by asio when our timeout expires */ /* Called by asio when our timeout expires */
static void timer_cb(const boost::system::error_code & error, GlobalInfo *g) static void timer_cb(const boost::system::error_code & error, GlobalInfo *g)
{ {
if(!error) if(!error) {
{
fprintf(MSG_OUT, "\ntimer_cb: "); fprintf(MSG_OUT, "\ntimer_cb: ");
CURLMcode rc; CURLMcode rc;
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running); rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
&g->still_running);
mcode_or_die("timer_cb: curl_multi_socket_action", rc); mcode_or_die("timer_cb: curl_multi_socket_action", rc);
check_multi_info(g); check_multi_info(g);
@ -214,22 +237,21 @@ static void remsock(int *f, GlobalInfo *g)
{ {
fprintf(MSG_OUT, "\nremsock: "); fprintf(MSG_OUT, "\nremsock: ");
if(f) if(f) {
{
free(f); free(f);
} }
} }
static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo*g) static void setsock(int *fdp, curl_socket_t s, CURL *e, int act, int oldact,
GlobalInfo *g)
{ {
fprintf(MSG_OUT, "\nsetsock: socket=%d, act=%d, fdp=%p", s, act, fdp); fprintf(MSG_OUT, "\nsetsock: socket=%d, act=%d, fdp=%p", s, act, fdp);
std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(s); std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it =
socket_map.find(s);
if(it == socket_map.end()) if(it == socket_map.end()) {
{
fprintf(MSG_OUT, "\nsocket %d is a c-ares socket, ignoring", s); fprintf(MSG_OUT, "\nsocket %d is a c-ares socket, ignoring", s);
return; return;
} }
@ -237,29 +259,34 @@ static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
*fdp = act; *fdp = act;
if(act == CURL_POLL_IN) if(act == CURL_POLL_IN) {
{
fprintf(MSG_OUT, "\nwatching for socket to become readable"); fprintf(MSG_OUT, "\nwatching for socket to become readable");
if(oldact != CURL_POLL_IN && oldact != CURL_POLL_INOUT) {
tcp_socket->async_read_some(boost::asio::null_buffers(), tcp_socket->async_read_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, tcp_socket, act)); boost::bind(&event_cb, g, s,
CURL_POLL_IN, _1, fdp));
}
} }
else if (act == CURL_POLL_OUT) else if(act == CURL_POLL_OUT) {
{
fprintf(MSG_OUT, "\nwatching for socket to become writable"); fprintf(MSG_OUT, "\nwatching for socket to become writable");
if(oldact != CURL_POLL_OUT && oldact != CURL_POLL_INOUT) {
tcp_socket->async_write_some(boost::asio::null_buffers(), tcp_socket->async_write_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, tcp_socket, act)); boost::bind(&event_cb, g, s,
CURL_POLL_OUT, _1, fdp));
}
} }
else if(act == CURL_POLL_INOUT) else if(act == CURL_POLL_INOUT) {
{
fprintf(MSG_OUT, "\nwatching for socket to become readable & writable"); fprintf(MSG_OUT, "\nwatching for socket to become readable & writable");
if(oldact != CURL_POLL_IN && oldact != CURL_POLL_INOUT) {
tcp_socket->async_read_some(boost::asio::null_buffers(), tcp_socket->async_read_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, tcp_socket, act)); boost::bind(&event_cb, g, s,
CURL_POLL_IN, _1, fdp));
tcp_socket->async_write_some(boost::asio::null_buffers(), }
boost::bind(&event_cb, g, tcp_socket, act)); if(oldact != CURL_POLL_OUT && oldact != CURL_POLL_INOUT) {
tcp_socket->async_write_some(boost::asio::null_buffers(),
boost::bind(&event_cb, g, s,
CURL_POLL_OUT, _1, fdp));
}
} }
} }
@ -268,7 +295,7 @@ static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
/* fdp is used to store current action */ /* fdp is used to store current action */
int *fdp = (int *) calloc(sizeof(int), 1); int *fdp = (int *) calloc(sizeof(int), 1);
setsock(fdp, s, easy, action, g); setsock(fdp, s, easy, action, 0, g);
curl_multi_assign(g->multi, s, fdp); curl_multi_assign(g->multi, s, fdp);
} }
@ -284,24 +311,20 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
fprintf(MSG_OUT, fprintf(MSG_OUT,
"\nsocket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); "\nsocket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if(what == CURL_POLL_REMOVE) if(what == CURL_POLL_REMOVE) {
{
fprintf(MSG_OUT, "\n"); fprintf(MSG_OUT, "\n");
remsock(actionp, g); remsock(actionp, g);
} }
else else {
{ if(!actionp) {
if(!actionp)
{
fprintf(MSG_OUT, "\nAdding data: %s", whatstr[what]); fprintf(MSG_OUT, "\nAdding data: %s", whatstr[what]);
addsock(s, e, what, g); addsock(s, e, what, g);
} }
else else {
{
fprintf(MSG_OUT, fprintf(MSG_OUT,
"\nChanging action from %s to %s", "\nChanging action from %s to %s",
whatstr[*actionp], whatstr[what]); whatstr[*actionp], whatstr[what]);
setsock(actionp, s, e, what, g); setsock(actionp, s, e, what, *actionp, g);
} }
} }
@ -311,9 +334,8 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
/* CURLOPT_WRITEFUNCTION */ /* CURLOPT_WRITEFUNCTION */
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{ {
size_t written = size * nmemb; size_t written = size * nmemb;
char* pBuffer = (char *) malloc(written + 1); char *pBuffer = (char *)malloc(written + 1);
strncpy(pBuffer, (const char *)ptr, written); strncpy(pBuffer, (const char *)ptr, written);
pBuffer[written] = '\0'; pBuffer[written] = '\0';
@ -349,28 +371,28 @@ static curl_socket_t opensocket(void *clientp, curlsocktype purpose,
curl_socket_t sockfd = CURL_SOCKET_BAD; curl_socket_t sockfd = CURL_SOCKET_BAD;
/* restrict to IPv4 */ /* restrict to IPv4 */
if(purpose == CURLSOCKTYPE_IPCXN && address->family == AF_INET) if(purpose == CURLSOCKTYPE_IPCXN && address->family == AF_INET) {
{
/* create a tcp socket object */ /* create a tcp socket object */
boost::asio::ip::tcp::socket *tcp_socket = new boost::asio::ip::tcp::socket(io_service); boost::asio::ip::tcp::socket *tcp_socket =
new boost::asio::ip::tcp::socket(io_service);
/* open it and get the native handle*/ /* open it and get the native handle*/
boost::system::error_code ec; boost::system::error_code ec;
tcp_socket->open(boost::asio::ip::tcp::v4(), ec); tcp_socket->open(boost::asio::ip::tcp::v4(), ec);
if(ec) if(ec) {
{
/* An error occurred */ /* An error occurred */
std::cout << std::endl << "Couldn't open socket [" << ec << "][" << ec.message() << "]"; std::cout << std::endl << "Couldn't open socket [" << ec << "][" <<
ec.message() << "]";
fprintf(MSG_OUT, "\nERROR: Returning CURL_SOCKET_BAD to signal error"); fprintf(MSG_OUT, "\nERROR: Returning CURL_SOCKET_BAD to signal error");
} }
else else {
{
sockfd = tcp_socket->native_handle(); sockfd = tcp_socket->native_handle();
fprintf(MSG_OUT, "\nOpened socket %d", sockfd); fprintf(MSG_OUT, "\nOpened socket %d", sockfd);
/* save it for monitoring */ /* save it for monitoring */
socket_map.insert(std::pair<curl_socket_t, boost::asio::ip::tcp::socket *>(sockfd, tcp_socket)); socket_map.insert(std::pair<curl_socket_t,
boost::asio::ip::tcp::socket *>(sockfd, tcp_socket));
} }
} }
@ -378,14 +400,14 @@ static curl_socket_t opensocket(void *clientp, curlsocktype purpose,
} }
/* CURLOPT_CLOSESOCKETFUNCTION */ /* CURLOPT_CLOSESOCKETFUNCTION */
static int closesocket(void *clientp, curl_socket_t item) static int close_socket(void *clientp, curl_socket_t item)
{ {
fprintf(MSG_OUT, "\nclosesocket : %d", item); fprintf(MSG_OUT, "\nclose_socket : %d", item);
std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(item); std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it =
socket_map.find(item);
if(it != socket_map.end()) if(it != socket_map.end()) {
{
delete it->second; delete it->second;
socket_map.erase(it); socket_map.erase(it);
} }
@ -402,10 +424,8 @@ static void new_conn(char *url, GlobalInfo *g)
conn = (ConnInfo *) calloc(1, sizeof(ConnInfo)); conn = (ConnInfo *) calloc(1, sizeof(ConnInfo));
conn->easy = curl_easy_init(); conn->easy = curl_easy_init();
if(!conn->easy) if(!conn->easy) {
{
fprintf(MSG_OUT, "\ncurl_easy_init() failed, exiting!"); fprintf(MSG_OUT, "\ncurl_easy_init() failed, exiting!");
exit(2); exit(2);
} }
@ -427,7 +447,7 @@ static void new_conn(char *url, GlobalInfo *g)
curl_easy_setopt(conn->easy, CURLOPT_OPENSOCKETFUNCTION, opensocket); curl_easy_setopt(conn->easy, CURLOPT_OPENSOCKETFUNCTION, opensocket);
/* call this function to close a socket */ /* call this function to close a socket */
curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, closesocket); curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, close_socket);
fprintf(MSG_OUT, fprintf(MSG_OUT,
"\nAdding easy %p to multi %p (%s)", conn->easy, g->multi, url); "\nAdding easy %p to multi %p (%s)", conn->easy, g->multi, url);
@ -441,7 +461,6 @@ static void new_conn(char *url, GlobalInfo *g)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
GlobalInfo g; GlobalInfo g;
CURLMcode rc;
(void)argc; (void)argc;
(void)argv; (void)argv;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,33 +19,27 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Example using a "in core" PEM certificate to retrieve a https page. /* <DESC>
* Written by Theo Borm * CA cert in memory with OpenSSL to get a HTTPS page.
* </DESC>
*/ */
/* on a netBSD system with OPENSSL& LIBCURL installed from
* pkgsrc (using default paths) this program can be compiled using:
* gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
* -lcrypto -lz -o curlcacerttest curlcacerttest.c
* on other operating systems you may want to change paths to headers
* and libraries
*/
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <stdio.h> #include <stdio.h>
size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream) size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
{ {
fwrite(ptr,size,nmemb,stream); fwrite(ptr, size, nmemb, stream);
return(nmemb*size); return (nmemb*size);
} }
static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm) static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{ {
X509_STORE * store; X509_STORE *store;
X509 * cert=NULL; X509 *cert = NULL;
BIO * bio; BIO *bio;
char * mypem = /* www.cacert.org */ char *mypem = /* www.cacert.org */
"-----BEGIN CERTIFICATE-----\n"\ "-----BEGIN CERTIFICATE-----\n"\
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\ "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\ "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
@ -88,19 +82,19 @@ static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\ "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
"-----END CERTIFICATE-----\n"; "-----END CERTIFICATE-----\n";
/* get a BIO */ /* get a BIO */
bio=BIO_new_mem_buf(mypem, -1); bio = BIO_new_mem_buf(mypem, -1);
/* use it to read the PEM formatted certificate from memory into an X509 /* use it to read the PEM formatted certificate from memory into an X509
* structure that SSL can use * structure that SSL can use
*/ */
PEM_read_bio_X509(bio, &cert, 0, NULL); PEM_read_bio_X509(bio, &cert, 0, NULL);
if (cert == NULL) if(cert == NULL)
printf("PEM_read_bio_X509 failed...\n"); printf("PEM_read_bio_X509 failed...\n");
/* get a pointer to the X509 certificate store (which may be empty!) */ /* get a pointer to the X509 certificate store (which may be empty!) */
store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx); store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
/* add our certificate to this store */ /* add our certificate to this store */
if (X509_STORE_add_cert(store, cert)==0) if(X509_STORE_add_cert(store, cert) == 0)
printf("error adding certificate\n"); printf("error adding certificate\n");
/* decrease reference counts */ /* decrease reference counts */
@ -108,43 +102,43 @@ static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
BIO_free(bio); BIO_free(bio);
/* all set to go */ /* all set to go */
return CURLE_OK ; return CURLE_OK;
} }
int main(void) int main(void)
{ {
CURL * ch; CURL *ch;
CURLcode rv; CURLcode rv;
rv=curl_global_init(CURL_GLOBAL_ALL); rv = curl_global_init(CURL_GLOBAL_ALL);
ch=curl_easy_init(); ch = curl_easy_init();
rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L); rv = curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L);
rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L); rv = curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L); rv = curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L);
rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L); rv = curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction); rv = curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, *writefunction);
rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout); rv = curl_easy_setopt(ch, CURLOPT_WRITEDATA, stdout);
rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction); rv = curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, *writefunction);
rv=curl_easy_setopt(ch,CURLOPT_HEADERDATA, stderr); rv = curl_easy_setopt(ch, CURLOPT_HEADERDATA, stderr);
rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM"); rv = curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L); rv = curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L);
rv=curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/"); rv = curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
/* first try: retrieve page without cacerts' certificate -> will fail /* first try: retrieve page without cacerts' certificate -> will fail
*/ */
rv=curl_easy_perform(ch); rv = curl_easy_perform(ch);
if (rv==CURLE_OK) if(rv == CURLE_OK)
printf("*** transfer succeeded ***\n"); printf("*** transfer succeeded ***\n");
else else
printf("*** transfer failed ***\n"); printf("*** transfer failed ***\n");
/* second try: retrieve page using cacerts' certificate -> will succeed /* second try: retrieve page using cacerts' certificate -> will succeed
* load the certificate by installing a function doing the nescessary * load the certificate by installing a function doing the necessary
* "modifications" to the SSL CONTEXT just before link init * "modifications" to the SSL CONTEXT just before link init
*/ */
rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function); rv = curl_easy_setopt(ch, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
rv=curl_easy_perform(ch); rv = curl_easy_perform(ch);
if (rv==CURLE_OK) if(rv == CURLE_OK)
printf("*** transfer succeeded ***\n"); printf("*** transfer succeeded ***\n");
else else
printf("*** transfer failed ***\n"); printf("*** transfer failed ***\n");

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Extract lots of TLS certificate info.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -52,24 +56,19 @@ int main(void)
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(!res) { if(!res) {
union { struct curl_certinfo *certinfo;
struct curl_slist *to_info;
struct curl_certinfo *to_certinfo;
} ptr;
ptr.to_info = NULL; res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &certinfo);
res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ptr.to_info); if(!res && certinfo) {
if(!res && ptr.to_info) {
int i; int i;
printf("%d certs!\n", ptr.to_certinfo->num_of_certs); printf("%d certs!\n", certinfo->num_of_certs);
for(i = 0; i < ptr.to_certinfo->num_of_certs; i++) { for(i = 0; i < certinfo->num_of_certs; i++) {
struct curl_slist *slist; struct curl_slist *slist;
for(slist = ptr.to_certinfo->certinfo[i]; slist; slist = slist->next) for(slist = certinfo->certinfo[i]; slist; slist = slist->next)
printf("%s\n", slist->data); printf("%s\n", slist->data);
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Show transfer timing info after download completes.
* </DESC>
*/
/* Example source code to show how the callback function can be used to /* Example source code to show how the callback function can be used to
* download data into a chunk of memory instead of storing it in a file. * download data into a chunk of memory instead of storing it in a file.
* After successful download we use curl_easy_getinfo() calls to get the * After successful download we use curl_easy_getinfo() calls to get the
@ -64,63 +68,78 @@ int main(int argc, char *argv[])
const char *url = URL_1M; const char *url = URL_1M;
char *appname = argv[0]; char *appname = argv[0];
if (argc > 1) { if(argc > 1) {
/* parse input parameters */ /* parse input parameters */
for (argc--, argv++; *argv; argc--, argv++) { for(argc--, argv++; *argv; argc--, argv++) {
if (strncasecmp(*argv, "-", 1) == 0) { if(strncasecmp(*argv, "-", 1) == 0) {
if (strncasecmp(*argv, "-H", 2) == 0) { if(strncasecmp(*argv, "-H", 2) == 0) {
fprintf(stderr, fprintf(stderr,
"\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n", "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
appname); appname);
exit(1); exit(1);
} else if (strncasecmp(*argv, "-V", 2) == 0) { }
else if(strncasecmp(*argv, "-V", 2) == 0) {
fprintf(stderr, "\r%s %s - %s\n", fprintf(stderr, "\r%s %s - %s\n",
appname, CHKSPEED_VERSION, curl_version()); appname, CHKSPEED_VERSION, curl_version());
exit(1); exit(1);
} else if (strncasecmp(*argv, "-A", 2) == 0) { }
else if(strncasecmp(*argv, "-A", 2) == 0) {
prtall = 1; prtall = 1;
} else if (strncasecmp(*argv, "-X", 2) == 0) { }
else if(strncasecmp(*argv, "-X", 2) == 0) {
prtsep = 1; prtsep = 1;
} else if (strncasecmp(*argv, "-T", 2) == 0) { }
else if(strncasecmp(*argv, "-T", 2) == 0) {
prttime = 1; prttime = 1;
} else if (strncasecmp(*argv, "-M=", 3) == 0) { }
long m = strtol((*argv)+3, NULL, 10); else if(strncasecmp(*argv, "-M=", 3) == 0) {
long m = strtol((*argv) + 3, NULL, 10);
switch(m) { switch(m) {
case 1: url = URL_1M; case 1:
break; url = URL_1M;
case 2: url = URL_2M; break;
break; case 2:
case 5: url = URL_5M; url = URL_2M;
break; break;
case 10: url = URL_10M; case 5:
break; url = URL_5M;
case 20: url = URL_20M; break;
break; case 10:
case 50: url = URL_50M; url = URL_10M;
break; break;
case 100: url = URL_100M; case 20:
break; url = URL_20M;
default: fprintf(stderr, "\r%s: invalid parameter %s\n", break;
appname, *argv + 3); case 50:
exit(1); url = URL_50M;
break;
case 100:
url = URL_100M;
break;
default:
fprintf(stderr, "\r%s: invalid parameter %s\n",
appname, *argv + 3);
exit(1);
} }
} else { }
else {
fprintf(stderr, "\r%s: invalid or unknown option %s\n", fprintf(stderr, "\r%s: invalid or unknown option %s\n",
appname, *argv); appname, *argv);
exit(1); exit(1);
} }
} else { }
else {
url = *argv; url = *argv;
} }
} }
} }
/* print separator line */ /* print separator line */
if (prtsep) { if(prtsep) {
printf("-------------------------------------------------\n"); printf("-------------------------------------------------\n");
} }
/* print localtime */ /* print localtime */
if (prttime) { if(prttime) {
time_t t = time(NULL); time_t t = time(NULL);
printf("Localtime: %s", ctime(&t)); printf("Localtime: %s", ctime(&t));
} }
@ -163,7 +182,7 @@ int main(int argc, char *argv[])
if((CURLE_OK == res) && (val>0)) if((CURLE_OK == res) && (val>0))
printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024); printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024);
if (prtall) { if(prtall) {
/* check for name resolution time */ /* check for name resolution time */
res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME, &val); res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME, &val);
if((CURLE_OK == res) && (val>0)) if((CURLE_OK == res) && (val>0))
@ -174,8 +193,8 @@ int main(int argc, char *argv[])
if((CURLE_OK == res) && (val>0)) if((CURLE_OK == res) && (val>0))
printf("Connect time: %0.3f sec.\n", val); printf("Connect time: %0.3f sec.\n", val);
} }
}
} else { else {
fprintf(stderr, "Error while fetching '%s' : %s\n", fprintf(stderr, "Error while fetching '%s' : %s\n",
url, curl_easy_strerror(res)); url, curl_easy_strerror(res));
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,7 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* This example shows usage of simple cookie interface. */ /* <DESC>
* Import and export cookies with COOKIELIST.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -39,17 +42,19 @@ print_cookies(CURL *curl)
printf("Cookies, curl knows:\n"); printf("Cookies, curl knows:\n");
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
if (res != CURLE_OK) { if(res != CURLE_OK) {
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n",
curl_easy_strerror(res));
exit(1); exit(1);
} }
nc = cookies, i = 1; nc = cookies;
while (nc) { i = 1;
while(nc) {
printf("[%d]: %s\n", i, nc->data); printf("[%d]: %s\n", i, nc->data);
nc = nc->next; nc = nc->next;
i++; i++;
} }
if (i == 1) { if(i == 1) {
printf("(none)\n"); printf("(none)\n");
} }
curl_slist_free_all(cookies); curl_slist_free_all(cookies);
@ -63,14 +68,14 @@ main(void)
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if(curl) {
char nline[256]; char nline[256];
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/"); curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* just to start the cookie engine */ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* start cookie engine */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if (res != CURLE_OK) { if(res != CURLE_OK) {
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
return 1; return 1;
} }
@ -89,30 +94,41 @@ main(void)
#endif #endif
/* Netscape format cookie */ /* Netscape format cookie */
snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s", snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s",
".google.com", "TRUE", "/", "FALSE", (unsigned long)time(NULL) + 31337UL, "PREF", "hello google, i like you very much!"); ".example.com", "TRUE", "/", "FALSE",
(unsigned long)time(NULL) + 31337UL,
"PREF", "hello example, i like you very much!");
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline); res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
if (res != CURLE_OK) { if(res != CURLE_OK) {
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "Curl curl_easy_setopt failed: %s\n",
curl_easy_strerror(res));
return 1; return 1;
} }
/* HTTP-header style cookie */ /* HTTP-header style cookie. If you use the Set-Cookie format and don't
specify a domain then the cookie is sent for any domain and will not be
modified, likely not what you intended. Starting in 7.43.0 any-domain
cookies will not be exported either. For more information refer to the
CURLOPT_COOKIELIST documentation.
*/
snprintf(nline, sizeof(nline), snprintf(nline, sizeof(nline),
"Set-Cookie: OLD_PREF=3d141414bf4209321; " "Set-Cookie: OLD_PREF=3d141414bf4209321; "
"expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com"); "expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.example.com");
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline); res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
if (res != CURLE_OK) { if(res != CURLE_OK) {
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "Curl curl_easy_setopt failed: %s\n",
curl_easy_strerror(res));
return 1; return 1;
} }
print_cookies(curl); print_cookies(curl);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if (res != CURLE_OK) { if(res != CURLE_OK) {
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
return 1; return 1;
} }
curl_easy_cleanup(curl);
} }
else { else {
fprintf(stderr, "Curl init failed!\n"); fprintf(stderr, "Curl init failed!\n");

View File

@ -5,9 +5,12 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft
*/
/* <DESC>
* use the libcurl in a gtk-threaded application
* </DESC>
*/ */
/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */
/* an attempt to use the curl library in concert with a gtk-threaded application */
#include <stdio.h> #include <stdio.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -47,9 +50,9 @@ void *my_thread(void *ptr)
gchar *url = ptr; gchar *url = ptr;
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) if(curl) {
{ const char *filename = "test.curl";
outfile = fopen("test.curl", "w"); outfile = fopen(filename, "wb");
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
@ -94,7 +97,7 @@ int main(int argc, char **argv)
gtk_container_add(GTK_CONTAINER(Frame2), Bar); gtk_container_add(GTK_CONTAINER(Frame2), Bar);
gtk_widget_show_all(Window); gtk_widget_show_all(Window);
if (!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0) if(!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
g_warning("can't create the thread"); g_warning("can't create the thread");

View File

@ -9,7 +9,10 @@
certificate presented during ssl session establishment. certificate presented during ssl session establishment.
*/ */
/* <DESC>
* demonstrates use of SSL context callback, requires OpenSSL
* </DESC>
*/
/* /*
* Copyright (c) 2003 The OpenEvidence Project. All rights reserved. * Copyright (c) 2003 The OpenEvidence Project. All rights reserved.
@ -33,7 +36,7 @@
* "This product includes software developed by the Openevidence Project * "This product includes software developed by the Openevidence Project
* for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)" * for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)"
* This product includes software developed by the OpenSSL Project * This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" * for use in the OpenSSL Toolkit (https://www.openssl.org/)"
* This product includes cryptographic software written by Eric Young * This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim * (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com)." * Hudson (tjh@cryptsoft.com)."
@ -52,7 +55,7 @@
* "This product includes software developed by the OpenEvidence Project * "This product includes software developed by the OpenEvidence Project
* for use in the OpenEvidence Toolkit (http://www.openevidence.org/) * for use in the OpenEvidence Toolkit (http://www.openevidence.org/)
* This product includes software developed by the OpenSSL Project * This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" * for use in the OpenSSL Toolkit (https://www.openssl.org/)"
* This product includes cryptographic software written by Eric Young * This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim * (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com)." * Hudson (tjh@cryptsoft.com)."
@ -72,7 +75,7 @@
* ==================================================================== * ====================================================================
* *
* This product includes software developed by the OpenSSL Project * This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/) * for use in the OpenSSL Toolkit (https://www.openssl.org/)
* This product includes cryptographic software written by Eric Young * This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim * (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). * Hudson (tjh@cryptsoft.com).
@ -98,13 +101,18 @@
static const char *curlx_usage[]={ static const char *curlx_usage[]={
"usage: curlx args\n", "usage: curlx args\n",
" -p12 arg - tia file ", " -p12 arg - tia file ",
" -envpass arg - environement variable which content the tia private key password", " -envpass arg - environment variable which content the tia private"
" key password",
" -out arg - output file (response)- default stdout", " -out arg - output file (response)- default stdout",
" -in arg - input file (request)- default stdin", " -in arg - input file (request)- default stdin",
" -connect arg - URL of the server for the connection ex: www.openevidence.org", " -connect arg - URL of the server for the connection ex:"
" -mimetype arg - MIME type for data in ex : application/timestamp-query or application/dvcs -default application/timestamp-query", " www.openevidence.org",
" -acceptmime arg - MIME type acceptable for the response ex : application/timestamp-response or application/dvcs -default none", " -mimetype arg - MIME type for data in ex : application/timestamp-query"
" -accesstype arg - an Object identifier in an AIA/SIA method, e.g. AD_DVCS or ad_timestamping", " or application/dvcs -default application/timestamp-query",
" -acceptmime arg - MIME type acceptable for the response ex : "
"application/timestamp-response or application/dvcs -default none",
" -accesstype arg - an Object identifier in an AIA/SIA method, e.g."
" AD_DVCS or ad_timestamping",
NULL NULL
}; };
@ -125,22 +133,22 @@ static const char *curlx_usage[]={
/* This is a context that we pass to all callbacks */ /* This is a context that we pass to all callbacks */
typedef struct sslctxparm_st { typedef struct sslctxparm_st {
unsigned char * p12file ; unsigned char *p12file;
const char * pst ; const char *pst;
PKCS12 * p12 ; PKCS12 *p12;
EVP_PKEY * pkey ; EVP_PKEY *pkey;
X509 * usercert ; X509 *usercert;
STACK_OF(X509) * ca ; STACK_OF(X509) * ca;
CURL * curl; CURL *curl;
BIO * errorbio; BIO *errorbio;
int accesstype ; int accesstype;
int verbose; int verbose;
} sslctxparm; } sslctxparm;
/* some helper function. */ /* some helper function. */
static char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5) static char *ia5string(ASN1_IA5STRING *ia5)
{ {
char *tmp; char *tmp;
if(!ia5 || !ia5->length) if(!ia5 || !ia5->length)
@ -152,20 +160,20 @@ static char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5)
} }
/* A conveniance routine to get an access URI. */ /* A conveniance routine to get an access URI. */
static unsigned char *my_get_ext(X509 *cert, const int type,
static unsigned char *my_get_ext(X509 * cert, const int type, int extensiontype) { int extensiontype)
{
int i; int i;
STACK_OF(ACCESS_DESCRIPTION) * accessinfo ; STACK_OF(ACCESS_DESCRIPTION) * accessinfo;
accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL) ; accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL);
if (!sk_ACCESS_DESCRIPTION_num(accessinfo)) if(!sk_ACCESS_DESCRIPTION_num(accessinfo))
return NULL; return NULL;
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) { for(i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) {
ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i); ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i);
if (OBJ_obj2nid(ad->method) == type) { if(OBJ_obj2nid(ad->method) == type) {
if (ad->location->type == GEN_URI) { if(ad->location->type == GEN_URI) {
return i2s_ASN1_IA5STRING(ad->location->d.ia5); return ia5string(ad->location->d.ia5);
} }
return NULL; return NULL;
} }
@ -184,106 +192,110 @@ static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
sslctxparm * p = (sslctxparm *) arg; sslctxparm * p = (sslctxparm *) arg;
int ok; int ok;
if (p->verbose > 2) if(p->verbose > 2)
BIO_printf(p->errorbio,"entering ssl_app_verify_callback\n"); BIO_printf(p->errorbio, "entering ssl_app_verify_callback\n");
if ((ok= X509_verify_cert(ctx)) && ctx->cert) { ok = X509_verify_cert(ctx);
unsigned char * accessinfo ; if(ok && ctx->cert) {
if (p->verbose > 1) unsigned char *accessinfo;
X509_print_ex(p->errorbio,ctx->cert,0,0); if(p->verbose > 1)
X509_print_ex(p->errorbio, ctx->cert, 0, 0);
if (accessinfo = my_get_ext(ctx->cert,p->accesstype ,NID_sinfo_access)) { accessinfo = my_get_ext(ctx->cert, p->accesstype, NID_sinfo_access);
if (p->verbose) if(accessinfo) {
BIO_printf(p->errorbio,"Setting URL from SIA to: %s\n", accessinfo); if(p->verbose)
BIO_printf(p->errorbio, "Setting URL from SIA to: %s\n", accessinfo);
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo); curl_easy_setopt(p->curl, CURLOPT_URL, accessinfo);
} }
else if (accessinfo = my_get_ext(ctx->cert,p->accesstype, else if(accessinfo = my_get_ext(ctx->cert, p->accesstype,
NID_info_access)) { NID_info_access)) {
if (p->verbose) if(p->verbose)
BIO_printf(p->errorbio,"Setting URL from AIA to: %s\n", accessinfo); BIO_printf(p->errorbio, "Setting URL from AIA to: %s\n", accessinfo);
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo); curl_easy_setopt(p->curl, CURLOPT_URL, accessinfo);
} }
} }
if (p->verbose > 2) if(p->verbose > 2)
BIO_printf(p->errorbio,"leaving ssl_app_verify_callback with %d\n", ok); BIO_printf(p->errorbio, "leaving ssl_app_verify_callback with %d\n", ok);
return(ok);
return ok;
} }
/* This is an example of an curl SSL initialisation call back. The callback sets: /* The SSL initialisation callback. The callback sets:
- a private key and certificate - a private key and certificate
- a trusted ca certificate - a trusted ca certificate
- a preferred cipherlist - a preferred cipherlist
- an application verification callback (the function above) - an application verification callback (the function above)
*/ */
static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) { static CURLcode sslctxfun(CURL *curl, void *sslctx, void *parm)
{
sslctxparm *p = (sslctxparm *) parm;
SSL_CTX *ctx = (SSL_CTX *) sslctx;
sslctxparm * p = (sslctxparm *) parm; if(!SSL_CTX_use_certificate(ctx, p->usercert)) {
SSL_CTX * ctx = (SSL_CTX *) sslctx ; BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n");
goto err;
if (!SSL_CTX_use_certificate(ctx,p->usercert)) {
BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n"); goto err;
} }
if (!SSL_CTX_use_PrivateKey(ctx,p->pkey)) { if(!SSL_CTX_use_PrivateKey(ctx, p->pkey)) {
BIO_printf(p->errorbio, "SSL_CTX_use_PrivateKey\n"); goto err; BIO_printf(p->errorbio, "SSL_CTX_use_PrivateKey\n");
goto err;
} }
if (!SSL_CTX_check_private_key(ctx)) { if(!SSL_CTX_check_private_key(ctx)) {
BIO_printf(p->errorbio, "SSL_CTX_check_private_key\n"); goto err; BIO_printf(p->errorbio, "SSL_CTX_check_private_key\n");
goto err;
} }
SSL_CTX_set_quiet_shutdown(ctx,1); SSL_CTX_set_quiet_shutdown(ctx, 1);
SSL_CTX_set_cipher_list(ctx,"RC4-MD5"); SSL_CTX_set_cipher_list(ctx, "RC4-MD5");
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), sk_X509_value(p->ca, sk_X509_num(p->ca)-1)); X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx),
sk_X509_value(p->ca, sk_X509_num(p->ca)-1));
SSL_CTX_set_verify_depth(ctx,2);
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
SSL_CTX_set_verify_depth(ctx, 2);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ZERO_NULL);
SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm); SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
return CURLE_OK;
return CURLE_OK ;
err: err:
ERR_print_errors(p->errorbio); ERR_print_errors(p->errorbio);
return CURLE_SSL_CERTPROBLEM; return CURLE_SSL_CERTPROBLEM;
} }
int main(int argc, char **argv) { int main(int argc, char **argv)
{
BIO* in = NULL;
BIO* out = NULL;
BIO* in=NULL; char *outfile = NULL;
BIO* out=NULL; char *infile = NULL;
char * outfile = NULL; int tabLength = 100;
char * infile = NULL ;
int tabLength=100;
char *binaryptr; char *binaryptr;
char* mimetype; char *mimetype;
char* mimetypeaccept=NULL; char *mimetypeaccept = NULL;
char* contenttype; char *contenttype;
const char** pp; const char **pp;
unsigned char* hostporturl = NULL; unsigned char *hostporturl = NULL;
BIO * p12bio ; BIO *p12bio;
char **args = argv + 1; char **args = argv + 1;
unsigned char * serverurl; unsigned char *serverurl;
sslctxparm p; sslctxparm p;
char *response; char *response;
CURLcode res; CURLcode res;
struct curl_slist * headers=NULL; struct curl_slist *headers = NULL;
int badarg=0; int badarg = 0;
binaryptr = malloc(tabLength); binaryptr = malloc(tabLength);
p.verbose = 0; p.verbose = 0;
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); p.errorbio = BIO_new_fp(stderr, BIO_NOCLOSE);
curl_global_init(CURL_GLOBAL_DEFAULT); curl_global_init(CURL_GLOBAL_DEFAULT);
@ -293,66 +305,93 @@ int main(int argc, char **argv) {
OpenSSL_add_all_digests(); OpenSSL_add_all_digests();
ERR_load_crypto_strings(); ERR_load_crypto_strings();
while(*args && *args[0] == '-') {
if(!strcmp (*args, "-in")) {
while (*args && *args[0] == '-') { if(args[1]) {
if (!strcmp (*args, "-in")) { infile = *(++args);
if (args[1]) { }
infile=*(++args); else
} else badarg=1; badarg = 1;
} else if (!strcmp (*args, "-out")) { }
if (args[1]) { else if(!strcmp (*args, "-out")) {
outfile=*(++args); if(args[1]) {
} else badarg=1; outfile = *(++args);
} else if (!strcmp (*args, "-p12")) { }
if (args[1]) { else
badarg = 1;
}
else if(!strcmp (*args, "-p12")) {
if(args[1]) {
p.p12file = *(++args); p.p12file = *(++args);
} else badarg=1; }
} else if (strcmp(*args,"-envpass") == 0) { else
if (args[1]) { badarg = 1;
}
else if(strcmp(*args, "-envpass") == 0) {
if(args[1]) {
p.pst = getenv(*(++args)); p.pst = getenv(*(++args));
} else badarg=1; }
} else if (strcmp(*args,"-connect") == 0) { else
if (args[1]) { badarg = 1;
}
else if(strcmp(*args, "-connect") == 0) {
if(args[1]) {
hostporturl = *(++args); hostporturl = *(++args);
} else badarg=1; }
} else if (strcmp(*args,"-mimetype") == 0) { else
if (args[1]) { badarg = 1;
}
else if(strcmp(*args, "-mimetype") == 0) {
if(args[1]) {
mimetype = *(++args); mimetype = *(++args);
} else badarg=1; }
} else if (strcmp(*args,"-acceptmime") == 0) { else
if (args[1]) { badarg = 1;
}
else if(strcmp(*args, "-acceptmime") == 0) {
if(args[1]) {
mimetypeaccept = *(++args); mimetypeaccept = *(++args);
} else badarg=1; }
} else if (strcmp(*args,"-accesstype") == 0) { else
if (args[1]) { badarg = 1;
if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1; }
} else badarg=1; else if(strcmp(*args, "-accesstype") == 0) {
} else if (strcmp(*args,"-verbose") == 0) { if(args[1]) {
p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args, 0));
if(p.accesstype == 0)
badarg = 1;
}
else
badarg = 1;
}
else if(strcmp(*args, "-verbose") == 0) {
p.verbose++; p.verbose++;
} else badarg=1; }
else
badarg = 1;
args++; args++;
} }
if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1; if(mimetype == NULL || mimetypeaccept == NULL)
badarg = 1;
if (badarg) { if(badarg) {
for (pp=curlx_usage; (*pp != NULL); pp++) for(pp = curlx_usage; (*pp != NULL); pp++)
BIO_printf(p.errorbio,"%s\n",*pp); BIO_printf(p.errorbio, "%s\n", *pp);
BIO_printf(p.errorbio,"\n"); BIO_printf(p.errorbio, "\n");
goto err; goto err;
} }
/* set input */ /* set input */
if ((in=BIO_new(BIO_s_file())) == NULL) { in = BIO_new(BIO_s_file());
if(in == NULL) {
BIO_printf(p.errorbio, "Error setting input bio\n"); BIO_printf(p.errorbio, "Error setting input bio\n");
goto err; goto err;
} else if (infile == NULL) }
BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else if(infile == NULL)
else if (BIO_read_filename(in,infile) <= 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE|BIO_FP_TEXT);
else if(BIO_read_filename(in, infile) <= 0) {
BIO_printf(p.errorbio, "Error opening input file %s\n", infile); BIO_printf(p.errorbio, "Error opening input file %s\n", infile);
BIO_free(in); BIO_free(in);
goto err; goto err;
@ -360,76 +399,88 @@ int main(int argc, char **argv) {
/* set output */ /* set output */
if ((out=BIO_new(BIO_s_file())) == NULL) { out = BIO_new(BIO_s_file());
if(out == NULL) {
BIO_printf(p.errorbio, "Error setting output bio.\n"); BIO_printf(p.errorbio, "Error setting output bio.\n");
goto err; goto err;
} else if (outfile == NULL) }
BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); else if(outfile == NULL)
else if (BIO_write_filename(out,outfile) <= 0) { BIO_set_fp(out, stdout, BIO_NOCLOSE|BIO_FP_TEXT);
else if(BIO_write_filename(out, outfile) <= 0) {
BIO_printf(p.errorbio, "Error opening output file %s\n", outfile); BIO_printf(p.errorbio, "Error opening output file %s\n", outfile);
BIO_free(out); BIO_free(out);
goto err; goto err;
} }
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); p.errorbio = BIO_new_fp(stderr, BIO_NOCLOSE);
if (!(p.curl = curl_easy_init())) { p.curl = curl_easy_init();
if(!p.curl) {
BIO_printf(p.errorbio, "Cannot init curl lib\n"); BIO_printf(p.errorbio, "Cannot init curl lib\n");
goto err; goto err;
} }
p12bio = BIO_new_file(p.p12file, "rb");
if(!p12bio) {
if (!(p12bio = BIO_new_file(p.p12file , "rb"))) { BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file);
BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err; goto err;
} }
if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) { p.p12 = d2i_PKCS12_bio(p12bio, NULL);
BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err; if(!p.p12) {
BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file);
goto err;
} }
p.ca= NULL; p.ca = NULL;
if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) { if(!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) {
BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err; BIO_printf(p.errorbio, "Invalid P12 structure in %s\n", p.p12file);
goto err;
} }
if (sk_X509_num(p.ca) <= 0) { if(sk_X509_num(p.ca) <= 0) {
BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err; BIO_printf(p.errorbio, "No trustworthy CA given.%s\n", p.p12file);
goto err;
} }
if (p.verbose > 1) if(p.verbose > 1)
X509_print_ex(p.errorbio,p.usercert,0,0); X509_print_ex(p.errorbio, p.usercert, 0, 0);
/* determine URL to go */ /* determine URL to go */
if (hostporturl) { if(hostporturl) {
serverurl = malloc(9+strlen(hostporturl)); size_t len = strlen(hostporturl) + 9;
sprintf(serverurl,"https://%s",hostporturl); serverurl = malloc(len);
snprintf(serverurl, len, "https://%s", hostporturl);
} }
else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */ else if(p.accesstype != 0) { /* see whether we can find an AIA or SIA for a
if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) { given access type */
int j=0; serverurl = my_get_ext(p.usercert, p.accesstype, NID_info_access);
BIO_printf(p.errorbio,"no service URL in user cert " if(!serverurl) {
int j = 0;
BIO_printf(p.errorbio, "no service URL in user cert "
"cherching in others certificats\n"); "cherching in others certificats\n");
for (j=0;j<sk_X509_num(p.ca);j++) { for(j = 0; j<sk_X509_num(p.ca); j++) {
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, serverurl = my_get_ext(sk_X509_value(p.ca, j), p.accesstype,
NID_info_access))) NID_info_access);
if(serverurl)
break; break;
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, serverurl = my_get_ext(sk_X509_value(p.ca, j), p.accesstype,
NID_sinfo_access))) NID_sinfo_access);
if(serverurl)
break; break;
} }
} }
} }
if (!serverurl) { if(!serverurl) {
BIO_printf(p.errorbio, "no service URL in certificats," BIO_printf(p.errorbio, "no service URL in certificats,"
" check '-accesstype (AD_DVCS | ad_timestamping)'" " check '-accesstype (AD_DVCS | ad_timestamping)'"
" or use '-connect'\n"); " or use '-connect'\n");
goto err; goto err;
} }
if (p.verbose) if(p.verbose)
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
curl_easy_setopt(p.curl, CURLOPT_URL, serverurl); curl_easy_setopt(p.curl, CURLOPT_URL, serverurl);
@ -437,38 +488,39 @@ int main(int argc, char **argv) {
/* Now specify the POST binary data */ /* Now specify the POST binary data */
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE, (long)tabLength);
/* pass our list of custom made headers */ /* pass our list of custom made headers */
contenttype = malloc(15+strlen(mimetype)); contenttype = malloc(15 + strlen(mimetype));
sprintf(contenttype,"Content-type: %s",mimetype); snprintf(contenttype, 15 + strlen(mimetype), "Content-type: %s", mimetype);
headers = curl_slist_append(headers,contenttype); headers = curl_slist_append(headers, contenttype);
curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers);
if (p.verbose) if(p.verbose)
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
{ {
FILE *outfp; FILE *outfp;
BIO_get_fp(out,&outfp); BIO_get_fp(out, &outfp);
curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp); curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp);
} }
res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ; res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun);
if (res != CURLE_OK) if(res != CURLE_OK)
BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res); BIO_printf(p.errorbio, "%d %s=%d %d\n", __LINE__,
"CURLOPT_SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, res);
curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p); curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);
{ {
int lu; int i=0; int lu; int i = 0;
while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) { while((lu = BIO_read(in, &binaryptr[i], tabLength-i)) >0) {
i+=lu; i += lu;
if (i== tabLength) { if(i == tabLength) {
tabLength+=100; tabLength += 100;
binaryptr=realloc(binaryptr,tabLength); /* should be more careful */ binaryptr = realloc(binaryptr, tabLength); /* should be more careful */
} }
} }
tabLength = i; tabLength = i;
@ -476,23 +528,23 @@ int main(int argc, char **argv) {
/* Now specify the POST binary data */ /* Now specify the POST binary data */
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE, (long)tabLength);
/* Perform the request, res will get the return code */ /* Perform the request, res will get the return code */
BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform", BIO_printf(p.errorbio, "%d %s %d\n", __LINE__, "curl_easy_perform",
res = curl_easy_perform(p.curl)); res = curl_easy_perform(p.curl));
{ {
int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response); int result = curl_easy_getinfo(p.curl, CURLINFO_CONTENT_TYPE, &response);
if( mimetypeaccept && p.verbose) if(mimetypeaccept && p.verbose)
if(!strcmp(mimetypeaccept,response)) if(!strcmp(mimetypeaccept, response))
BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n", BIO_printf(p.errorbio, "the response has a correct mimetype : %s\n",
response); response);
else else
BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable " BIO_printf(p.errorbio, "the response doesn\'t have an acceptable "
"mime type, it is %s instead of %s\n", "mime type, it is %s instead of %s\n",
response,mimetypeaccept); response, mimetypeaccept);
} }
/*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/ /*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/
@ -508,6 +560,6 @@ int main(int argc, char **argv) {
BIO_free(out); BIO_free(out);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
err: BIO_printf(p.errorbio,"error"); err: BIO_printf(p.errorbio, "error");
exit(1); exit(1);
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Show how CURLOPT_DEBUGFUNCTION can be used.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -34,7 +38,7 @@ void dump(const char *text,
size_t i; size_t i;
size_t c; size_t c;
unsigned int width=0x10; unsigned int width = 0x10;
if(nohex) if(nohex)
/* without the hex output, we can fit more on screen */ /* without the hex output, we can fit more on screen */
@ -43,30 +47,32 @@ void dump(const char *text,
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
text, (long)size, (long)size); text, (long)size, (long)size);
for(i=0; i<size; i+= width) { for(i = 0; i<size; i += width) {
fprintf(stream, "%4.4lx: ", (long)i); fprintf(stream, "%4.4lx: ", (long)i);
if(!nohex) { if(!nohex) {
/* hex not disabled, show it */ /* hex not disabled, show it */
for(c = 0; c < width; c++) for(c = 0; c < width; c++)
if(i+c < size) if(i + c < size)
fprintf(stream, "%02x ", ptr[i+c]); fprintf(stream, "%02x ", ptr[i + c]);
else else
fputs(" ", stream); fputs(" ", stream);
} }
for(c = 0; (c < width) && (i+c < size); c++) { for(c = 0; (c < width) && (i + c < size); c++) {
/* check for 0D0A; if found, skip past and start a new line of output */ /* check for 0D0A; if found, skip past and start a new line of output */
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { if(nohex && (i + c + 1 < size) && ptr[i + c] == 0x0D &&
i+=(c+2-width); ptr[i + c + 1] == 0x0A) {
i += (c + 2 - width);
break; break;
} }
fprintf(stream, "%c", fprintf(stream, "%c",
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); (ptr[i + c] >= 0x20) && (ptr[i + c]<0x80)?ptr[i + c]:'.');
/* check again for 0D0A, to avoid an extra \n if it's at width */ /* check again for 0D0A, to avoid an extra \n if it's at width */
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D &&
i+=(c+3-width); ptr[i + c + 2] == 0x0A) {
i += (c + 3 - width);
break; break;
} }
} }
@ -84,9 +90,10 @@ int my_trace(CURL *handle, curl_infotype type,
const char *text; const char *text;
(void)handle; /* prevent compiler warning */ (void)handle; /* prevent compiler warning */
switch (type) { switch(type) {
case CURLINFO_TEXT: case CURLINFO_TEXT:
fprintf(stderr, "== Info: %s", data); fprintf(stderr, "== Info: %s", data);
/* FALLTHROUGH */
default: /* in case a new one is introduced to shock us */ default: /* in case a new one is introduced to shock us */
return 0; return 0;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* multi socket interface together with libev
* </DESC>
*/
/* Example application source code using the multi socket interface to /* Example application source code using the multi socket interface to
* download many files at once. * download many files at once.
* *
@ -82,7 +86,7 @@ typedef struct _GlobalInfo
struct ev_timer timer_event; struct ev_timer timer_event;
CURLM *multi; CURLM *multi;
int still_running; int still_running;
FILE* input; FILE *input;
} GlobalInfo; } GlobalInfo;
@ -115,12 +119,12 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{ {
DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms); DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
ev_timer_stop(g->loop, &g->timer_event); ev_timer_stop(g->loop, &g->timer_event);
if (timeout_ms > 0) if(timeout_ms > 0) {
{
double t = timeout_ms / 1000; double t = timeout_ms / 1000;
ev_timer_init(&g->timer_event, timer_cb, t, 0.); ev_timer_init(&g->timer_event, timer_cb, t, 0.);
ev_timer_start(g->loop, &g->timer_event); ev_timer_start(g->loop, &g->timer_event);
}else }
else if(timeout_ms == 0)
timer_cb(g->loop, &g->timer_event, 0); timer_cb(g->loop, &g->timer_event, 0);
return 0; return 0;
} }
@ -128,20 +132,32 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
/* Die if we get a bad CURLMcode somewhere */ /* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(const char *where, CURLMcode code) static void mcode_or_die(const char *where, CURLMcode code)
{ {
if ( CURLM_OK != code ) if(CURLM_OK != code) {
{
const char *s; const char *s;
switch ( code ) switch(code) {
{ case CURLM_BAD_HANDLE:
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; s = "CURLM_BAD_HANDLE";
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
case CURLM_LAST: s="CURLM_LAST"; break;
default: s="CURLM_unknown";
break; break;
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; case CURLM_BAD_EASY_HANDLE:
s = "CURLM_BAD_EASY_HANDLE";
break;
case CURLM_OUT_OF_MEMORY:
s = "CURLM_OUT_OF_MEMORY";
break;
case CURLM_INTERNAL_ERROR:
s = "CURLM_INTERNAL_ERROR";
break;
case CURLM_UNKNOWN_OPTION:
s = "CURLM_UNKNOWN_OPTION";
break;
case CURLM_LAST:
s = "CURLM_LAST";
break;
default:
s = "CURLM_unknown";
break;
case CURLM_BAD_SOCKET:
s = "CURLM_BAD_SOCKET";
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
/* ignore this error */ /* ignore this error */
return; return;
@ -164,8 +180,8 @@ static void check_multi_info(GlobalInfo *g)
CURLcode res; CURLcode res;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running); fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) { if(msg->msg == CURLMSG_DONE) {
easy = msg->easy_handle; easy = msg->easy_handle;
res = msg->data.result; res = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
@ -193,8 +209,7 @@ static void event_cb(EV_P_ struct ev_io *w, int revents)
rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running); rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running);
mcode_or_die("event_cb: curl_multi_socket_action", rc); mcode_or_die("event_cb: curl_multi_socket_action", rc);
check_multi_info(g); check_multi_info(g);
if ( g->still_running <= 0 ) if(g->still_running <= 0) {
{
fprintf(MSG_OUT, "last transfer done, kill timeout\n"); fprintf(MSG_OUT, "last transfer done, kill timeout\n");
ev_timer_stop(g->loop, &g->timer_event); ev_timer_stop(g->loop, &g->timer_event);
} }
@ -208,7 +223,8 @@ static void timer_cb(EV_P_ struct ev_timer *w, int revents)
GlobalInfo *g = (GlobalInfo *)w->data; GlobalInfo *g = (GlobalInfo *)w->data;
CURLMcode rc; CURLMcode rc;
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running); rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
&g->still_running);
mcode_or_die("timer_cb: curl_multi_socket_action", rc); mcode_or_die("timer_cb: curl_multi_socket_action", rc);
check_multi_info(g); check_multi_info(g);
} }
@ -217,9 +233,8 @@ static void timer_cb(EV_P_ struct ev_timer *w, int revents)
static void remsock(SockInfo *f, GlobalInfo *g) static void remsock(SockInfo *f, GlobalInfo *g)
{ {
printf("%s \n", __PRETTY_FUNCTION__); printf("%s \n", __PRETTY_FUNCTION__);
if ( f ) if(f) {
{ if(f->evset)
if ( f->evset )
ev_io_stop(g->loop, &f->ev); ev_io_stop(g->loop, &f->ev);
free(f); free(f);
} }
@ -228,7 +243,8 @@ static void remsock(SockInfo *f, GlobalInfo *g)
/* Assign information to a SockInfo structure */ /* Assign information to a SockInfo structure */
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
GlobalInfo *g)
{ {
printf("%s \n", __PRETTY_FUNCTION__); printf("%s \n", __PRETTY_FUNCTION__);
@ -237,11 +253,11 @@ static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
f->sockfd = s; f->sockfd = s;
f->action = act; f->action = act;
f->easy = e; f->easy = e;
if ( f->evset ) if(f->evset)
ev_io_stop(g->loop, &f->ev); ev_io_stop(g->loop, &f->ev);
ev_io_init(&f->ev, event_cb, f->sockfd, kind); ev_io_init(&f->ev, event_cb, f->sockfd, kind);
f->ev.data = g; f->ev.data = g;
f->evset=1; f->evset = 1;
ev_io_start(g->loop, &f->ev); ev_io_start(g->loop, &f->ev);
} }
@ -269,18 +285,16 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
fprintf(MSG_OUT, fprintf(MSG_OUT,
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if ( what == CURL_POLL_REMOVE ) if(what == CURL_POLL_REMOVE) {
{
fprintf(MSG_OUT, "\n"); fprintf(MSG_OUT, "\n");
remsock(fdp, g); remsock(fdp, g);
} else }
{ else {
if ( !fdp ) if(!fdp) {
{
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]); fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
addsock(s, e, what, g); addsock(s, e, what, g);
} else }
{ else {
fprintf(MSG_OUT, fprintf(MSG_OUT,
"Changing action from %s to %s\n", "Changing action from %s to %s\n",
whatstr[fdp->action], whatstr[what]); whatstr[fdp->action], whatstr[what]);
@ -303,8 +317,8 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
/* CURLOPT_PROGRESSFUNCTION */ /* CURLOPT_PROGRESSFUNCTION */
static int prog_cb (void *p, double dltotal, double dlnow, double ult, static int prog_cb(void *p, double dltotal, double dlnow, double ult,
double uln) double uln)
{ {
ConnInfo *conn = (ConnInfo *)p; ConnInfo *conn = (ConnInfo *)p;
(void)ult; (void)ult;
@ -316,7 +330,7 @@ static int prog_cb (void *p, double dltotal, double dlnow, double ult,
/* Create a new easy handle, and add it to the global curl_multi */ /* Create a new easy handle, and add it to the global curl_multi */
static void new_conn(char *url, GlobalInfo *g ) static void new_conn(char *url, GlobalInfo *g)
{ {
ConnInfo *conn; ConnInfo *conn;
CURLMcode rc; CURLMcode rc;
@ -326,8 +340,7 @@ static void new_conn(char *url, GlobalInfo *g )
conn->error[0]='\0'; conn->error[0]='\0';
conn->easy = curl_easy_init(); conn->easy = curl_easy_init();
if ( !conn->easy ) if(!conn->easy) {
{
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n"); fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
exit(2); exit(2);
} }
@ -358,57 +371,53 @@ static void new_conn(char *url, GlobalInfo *g )
static void fifo_cb(EV_P_ struct ev_io *w, int revents) static void fifo_cb(EV_P_ struct ev_io *w, int revents)
{ {
char s[1024]; char s[1024];
long int rv=0; long int rv = 0;
int n=0; int n = 0;
GlobalInfo *g = (GlobalInfo *)w->data; GlobalInfo *g = (GlobalInfo *)w->data;
do do {
{
s[0]='\0'; s[0]='\0';
rv=fscanf(g->input, "%1023s%n", s, &n); rv = fscanf(g->input, "%1023s%n", s, &n);
s[n]='\0'; s[n]='\0';
if ( n && s[0] ) if(n && s[0]) {
{ new_conn(s, g); /* if we read a URL, go get it! */
new_conn(s,g); /* if we read a URL, go get it! */ }
} else break; else
} while ( rv != EOF ); break;
} while(rv != EOF);
} }
/* Create a named pipe and tell libevent to monitor it */ /* Create a named pipe and tell libevent to monitor it */
static int init_fifo (GlobalInfo *g) static int init_fifo(GlobalInfo *g)
{ {
struct stat st; struct stat st;
static const char *fifo = "hiper.fifo"; static const char *fifo = "hiper.fifo";
curl_socket_t sockfd; curl_socket_t sockfd;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo); fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if ( lstat (fifo, &st) == 0 ) if(lstat (fifo, &st) == 0) {
{ if((st.st_mode & S_IFMT) == S_IFREG) {
if ( (st.st_mode & S_IFMT) == S_IFREG )
{
errno = EEXIST; errno = EEXIST;
perror("lstat"); perror("lstat");
exit (1); exit(1);
} }
} }
unlink(fifo); unlink(fifo);
if ( mkfifo (fifo, 0600) == -1 ) if(mkfifo (fifo, 0600) == -1) {
{
perror("mkfifo"); perror("mkfifo");
exit (1); exit(1);
} }
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0); sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
if ( sockfd == -1 ) if(sockfd == -1) {
{
perror("open"); perror("open");
exit (1); exit(1);
} }
g->input = fdopen(sockfd, "r"); g->input = fdopen(sockfd, "r");
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo); fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ); ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ);
ev_io_start(g->loop, &g->fifo_event); ev_io_start(g->loop, &g->fifo_event);
return(0); return (0);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,9 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* /* <DESC>
* This is an example demonstrating how an application can pass in a custom * An example demonstrating how an application can pass in a custom
* socket to libcurl to use. This example also handles the connect itself. * socket to libcurl to use. This example also handles the connect itself.
* </DESC>
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -37,7 +38,7 @@
#include <sys/types.h> /* socket types */ #include <sys/types.h> /* socket types */
#include <sys/socket.h> /* socket definitions */ #include <sys/socket.h> /* socket definitions */
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> /* inet (3) funtions */ #include <arpa/inet.h> /* inet (3) functions */
#include <unistd.h> /* misc. Unix functions */ #include <unistd.h> /* misc. Unix functions */
#endif #endif
@ -53,10 +54,17 @@
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{ {
int written = fwrite(ptr, size, nmemb, (FILE *)stream); size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written; return written;
} }
static int closecb(void *clientp, curl_socket_t item)
{
(void)clientp;
printf("libcurl wants to close %d now\n", (int)item);
return 0;
}
static curl_socket_t opensocket(void *clientp, static curl_socket_t opensocket(void *clientp,
curlsocktype purpose, curlsocktype purpose,
struct curl_sockaddr *address) struct curl_sockaddr *address)
@ -89,9 +97,8 @@ int main(void)
#ifdef WIN32 #ifdef WIN32
WSADATA wsaData; WSADATA wsaData;
int initwsa; int initwsa = WSAStartup(MAKEWORD(2, 0), &wsaData);
if(initwsa != 0) {
if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) {
printf("WSAStartup failed: %d\n", initwsa); printf("WSAStartup failed: %d\n", initwsa);
return 1; return 1;
} }
@ -106,7 +113,8 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
/* Create the socket "manually" */ /* Create the socket "manually" */
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == CURL_SOCKET_BAD ) { sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == CURL_SOCKET_BAD) {
printf("Error creating listening socket.\n"); printf("Error creating listening socket.\n");
return 3; return 3;
} }
@ -115,10 +123,11 @@ int main(void)
servaddr.sin_family = AF_INET; servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORTNUM); servaddr.sin_port = htons(PORTNUM);
if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR))) servaddr.sin_addr.s_addr = inet_addr(IPADDR);
if(INADDR_NONE == servaddr.sin_addr.s_addr)
return 2; return 2;
if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) == if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) ==
-1) { -1) {
close(sockfd); close(sockfd);
printf("client error: connect: %s\n", strerror(errno)); printf("client error: connect: %s\n", strerror(errno));
@ -135,6 +144,10 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
/* call this function to close sockets */
curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closecb);
curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd);
/* call this function to set options for the socket */ /* call this function to set options for the socket */
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Upload to a file:// URL
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -33,16 +37,12 @@ int main(void)
FILE *fd; FILE *fd;
fd = fopen("debugit", "rb"); /* open file to upload */ fd = fopen("debugit", "rb"); /* open file to upload */
if(!fd) { if(!fd)
return 1; /* can't continue */ return 1; /* can't continue */
}
/* to get the file size */ /* to get the file size */
if(fstat(fileno(fd), &file_info) != 0) { if(fstat(fileno(fd), &file_info) != 0)
return 1; /* can't continue */ return 1; /* can't continue */
}
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {
@ -82,5 +82,6 @@ int main(void)
/* always cleanup */ /* always cleanup */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }
fclose(fd);
return 0; return 0;
} }

View File

@ -10,10 +10,10 @@
* instead of (only) local files. Local files (ie those that can be directly * instead of (only) local files. Local files (ie those that can be directly
* fopened) will drop back to using the underlying clib implementations * fopened) will drop back to using the underlying clib implementations
* *
* See the main() function at the bottom that shows an app that retrives from a * See the main() function at the bottom that shows an app that retrieves from
* specified url using fgets() and fread() and saves as two output files. * a specified url using fgets() and fread() and saves as two output files.
* *
* Copyright (c) 2003 Simtec Electronics * Copyright (c) 2003, 2017 Simtec Electronics
* *
* Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive * Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
* reference to original curl example code * reference to original curl example code
@ -42,6 +42,10 @@
* *
* This example requires libcurl 7.9.7 or later. * This example requires libcurl 7.9.7 or later.
*/ */
/* <DESC>
* implements an fopen() abstraction allowing reading from URLs
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -54,9 +58,9 @@
#include <curl/curl.h> #include <curl/curl.h>
enum fcurl_type_e { enum fcurl_type_e {
CFTYPE_NONE=0, CFTYPE_NONE = 0,
CFTYPE_FILE=1, CFTYPE_FILE = 1,
CFTYPE_CURL=2 CFTYPE_CURL = 2
}; };
struct fcurl_data struct fcurl_data
@ -76,15 +80,15 @@ struct fcurl_data
typedef struct fcurl_data URL_FILE; typedef struct fcurl_data URL_FILE;
/* exported functions */ /* exported functions */
URL_FILE *url_fopen(const char *url,const char *operation); URL_FILE *url_fopen(const char *url, const char *operation);
int url_fclose(URL_FILE *file); int url_fclose(URL_FILE *file);
int url_feof(URL_FILE *file); int url_feof(URL_FILE *file);
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file); size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
char * url_fgets(char *ptr, size_t size, URL_FILE *file); char *url_fgets(char *ptr, size_t size, URL_FILE *file);
void url_rewind(URL_FILE *file); void url_rewind(URL_FILE *file);
/* we use a global one for convenience */ /* we use a global one for convenience */
CURLM *multi_handle; static CURLM *multi_handle;
/* curl calls this routine to get more data */ /* curl calls this routine to get more data */
static size_t write_callback(char *buffer, static size_t write_callback(char *buffer,
@ -98,19 +102,19 @@ static size_t write_callback(char *buffer,
URL_FILE *url = (URL_FILE *)userp; URL_FILE *url = (URL_FILE *)userp;
size *= nitems; size *= nitems;
rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */ rembuff = url->buffer_len - url->buffer_pos; /* remaining space in buffer */
if(size > rembuff) { if(size > rembuff) {
/* not enough space in buffer */ /* not enough space in buffer */
newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff)); newbuff = realloc(url->buffer, url->buffer_len + (size - rembuff));
if(newbuff==NULL) { if(newbuff == NULL) {
fprintf(stderr,"callback buffer grow failed\n"); fprintf(stderr, "callback buffer grow failed\n");
size=rembuff; size = rembuff;
} }
else { else {
/* realloc suceeded increase buffer size*/ /* realloc succeeded increase buffer size*/
url->buffer_len+=size - rembuff; url->buffer_len += size - rembuff;
url->buffer=newbuff; url->buffer = newbuff;
} }
} }
@ -131,7 +135,7 @@ static int fill_buffer(URL_FILE *file, size_t want)
CURLMcode mc; /* curl_multi_fdset() return code */ CURLMcode mc; /* curl_multi_fdset() return code */
/* only attempt to fill buffer if transactions still running and buffer /* only attempt to fill buffer if transactions still running and buffer
* doesnt exceed required size already * doesn't exceed required size already
*/ */
if((!file->still_running) || (file->buffer_pos > want)) if((!file->still_running) || (file->buffer_pos > want))
return 0; return 0;
@ -161,8 +165,7 @@ static int fill_buffer(URL_FILE *file, size_t want)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -186,7 +189,7 @@ static int fill_buffer(URL_FILE *file, size_t want)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
switch(rc) { switch(rc) {
@ -205,15 +208,15 @@ static int fill_buffer(URL_FILE *file, size_t want)
} }
/* use to remove want bytes from the front of a files buffer */ /* use to remove want bytes from the front of a files buffer */
static int use_buffer(URL_FILE *file,int want) static int use_buffer(URL_FILE *file, size_t want)
{ {
/* sort out buffer */ /* sort out buffer */
if((file->buffer_pos - want) <=0) { if((file->buffer_pos - want) <= 0) {
/* ditch buffer - write will recreate */ /* ditch buffer - write will recreate */
free(file->buffer); free(file->buffer);
file->buffer=NULL; file->buffer = NULL;
file->buffer_pos=0; file->buffer_pos = 0;
file->buffer_len=0; file->buffer_len = 0;
} }
else { else {
/* move rest down make it available for later */ /* move rest down make it available for later */
@ -226,10 +229,10 @@ static int use_buffer(URL_FILE *file,int want)
return 0; return 0;
} }
URL_FILE *url_fopen(const char *url,const char *operation) URL_FILE *url_fopen(const char *url, const char *operation)
{ {
/* this code could check for URLs or types in the 'url' and /* this code could check for URLs or types in the 'url' and
basicly use the real fopen() for standard files */ basically use the real fopen() for standard files */
URL_FILE *file; URL_FILE *file;
(void)operation; (void)operation;
@ -240,7 +243,8 @@ URL_FILE *url_fopen(const char *url,const char *operation)
memset(file, 0, sizeof(URL_FILE)); memset(file, 0, sizeof(URL_FILE));
if((file->handle.file=fopen(url,operation))) file->handle.file = fopen(url, operation);
if(file->handle.file)
file->type = CFTYPE_FILE; /* marked as URL */ file->type = CFTYPE_FILE; /* marked as URL */
else { else {
@ -279,11 +283,11 @@ URL_FILE *url_fopen(const char *url,const char *operation)
int url_fclose(URL_FILE *file) int url_fclose(URL_FILE *file)
{ {
int ret=0;/* default is good return */ int ret = 0;/* default is good return */
switch(file->type) { switch(file->type) {
case CFTYPE_FILE: case CFTYPE_FILE:
ret=fclose(file->handle.file); /* passthrough */ ret = fclose(file->handle.file); /* passthrough */
break; break;
case CFTYPE_CURL: case CFTYPE_CURL:
@ -295,8 +299,8 @@ int url_fclose(URL_FILE *file)
break; break;
default: /* unknown or supported type - oh dear */ default: /* unknown or supported type - oh dear */
ret=EOF; ret = EOF;
errno=EBADF; errno = EBADF;
break; break;
} }
@ -308,11 +312,11 @@ int url_fclose(URL_FILE *file)
int url_feof(URL_FILE *file) int url_feof(URL_FILE *file)
{ {
int ret=0; int ret = 0;
switch(file->type) { switch(file->type) {
case CFTYPE_FILE: case CFTYPE_FILE:
ret=feof(file->handle.file); ret = feof(file->handle.file);
break; break;
case CFTYPE_CURL: case CFTYPE_CURL:
@ -321,8 +325,8 @@ int url_feof(URL_FILE *file)
break; break;
default: /* unknown or supported type - oh dear */ default: /* unknown or supported type - oh dear */
ret=-1; ret = -1;
errno=EBADF; errno = EBADF;
break; break;
} }
return ret; return ret;
@ -334,15 +338,15 @@ size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
switch(file->type) { switch(file->type) {
case CFTYPE_FILE: case CFTYPE_FILE:
want=fread(ptr,size,nmemb,file->handle.file); want = fread(ptr, size, nmemb, file->handle.file);
break; break;
case CFTYPE_CURL: case CFTYPE_CURL:
want = nmemb * size; want = nmemb * size;
fill_buffer(file,want); fill_buffer(file, want);
/* check if theres data in the buffer - if not fill_buffer() /* check if there's data in the buffer - if not fill_buffer()
* either errored or EOF */ * either errored or EOF */
if(!file->buffer_pos) if(!file->buffer_pos)
return 0; return 0;
@ -354,14 +358,14 @@ size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
/* xfer data to caller */ /* xfer data to caller */
memcpy(ptr, file->buffer, want); memcpy(ptr, file->buffer, want);
use_buffer(file,want); use_buffer(file, want);
want = want / size; /* number of items */ want = want / size; /* number of items */
break; break;
default: /* unknown or supported type - oh dear */ default: /* unknown or supported type - oh dear */
want=0; want = 0;
errno=EBADF; errno = EBADF;
break; break;
} }
@ -375,13 +379,13 @@ char *url_fgets(char *ptr, size_t size, URL_FILE *file)
switch(file->type) { switch(file->type) {
case CFTYPE_FILE: case CFTYPE_FILE:
ptr = fgets(ptr,size,file->handle.file); ptr = fgets(ptr, (int)size, file->handle.file);
break; break;
case CFTYPE_CURL: case CFTYPE_CURL:
fill_buffer(file,want); fill_buffer(file, want);
/* check if theres data in the buffer - if not fill either errored or /* check if there's data in the buffer - if not fill either errored or
* EOF */ * EOF */
if(!file->buffer_pos) if(!file->buffer_pos)
return NULL; return NULL;
@ -392,24 +396,24 @@ char *url_fgets(char *ptr, size_t size, URL_FILE *file)
/*buffer contains data */ /*buffer contains data */
/* look for newline or eof */ /* look for newline or eof */
for(loop=0;loop < want;loop++) { for(loop = 0; loop < want; loop++) {
if(file->buffer[loop] == '\n') { if(file->buffer[loop] == '\n') {
want=loop+1;/* include newline */ want = loop + 1;/* include newline */
break; break;
} }
} }
/* xfer data to caller */ /* xfer data to caller */
memcpy(ptr, file->buffer, want); memcpy(ptr, file->buffer, want);
ptr[want]=0;/* allways null terminate */ ptr[want] = 0;/* always null terminate */
use_buffer(file,want); use_buffer(file, want);
break; break;
default: /* unknown or supported type - oh dear */ default: /* unknown or supported type - oh dear */
ptr=NULL; ptr = NULL;
errno=EBADF; errno = EBADF;
break; break;
} }
@ -432,9 +436,9 @@ void url_rewind(URL_FILE *file)
/* ditch buffer - write will recreate - resets stream pos*/ /* ditch buffer - write will recreate - resets stream pos*/
free(file->buffer); free(file->buffer);
file->buffer=NULL; file->buffer = NULL;
file->buffer_pos=0; file->buffer_pos = 0;
file->buffer_len=0; file->buffer_len = 0;
break; break;
@ -443,7 +447,11 @@ void url_rewind(URL_FILE *file)
} }
} }
/* Small main program to retrive from a url using fgets and fread saving the #define FGETSFILE "fgets.test"
#define FREADFILE "fread.test"
#define REWINDFILE "rewind.test"
/* Small main program to retrieve from a url using fgets and fread saving the
* output to two test files (note the fgets method will corrupt binary files if * output to two test files (note the fgets method will corrupt binary files if
* they contain 0 chars */ * they contain 0 chars */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -451,17 +459,17 @@ int main(int argc, char *argv[])
URL_FILE *handle; URL_FILE *handle;
FILE *outf; FILE *outf;
int nread; size_t nread;
char buffer[256]; char buffer[256];
const char *url; const char *url;
if(argc < 2) if(argc < 2)
url="http://192.168.7.3/testfile";/* default to testurl */ url = "http://192.168.7.3/testfile";/* default to testurl */
else else
url=argv[1];/* use passed url */ url = argv[1];/* use passed url */
/* copy from url line by line with fgets */ /* copy from url line by line with fgets */
outf=fopen("fgets.test","w+"); outf = fopen(FGETSFILE, "wb+");
if(!outf) { if(!outf) {
perror("couldn't open fgets output file\n"); perror("couldn't open fgets output file\n");
return 1; return 1;
@ -475,8 +483,8 @@ int main(int argc, char *argv[])
} }
while(!url_feof(handle)) { while(!url_feof(handle)) {
url_fgets(buffer,sizeof(buffer),handle); url_fgets(buffer, sizeof(buffer), handle);
fwrite(buffer,1,strlen(buffer),outf); fwrite(buffer, 1, strlen(buffer), outf);
} }
url_fclose(handle); url_fclose(handle);
@ -485,7 +493,7 @@ int main(int argc, char *argv[])
/* Copy from url with fread */ /* Copy from url with fread */
outf=fopen("fread.test","w+"); outf = fopen(FREADFILE, "wb+");
if(!outf) { if(!outf) {
perror("couldn't open fread output file\n"); perror("couldn't open fread output file\n");
return 1; return 1;
@ -499,8 +507,8 @@ int main(int argc, char *argv[])
} }
do { do {
nread = url_fread(buffer, 1,sizeof(buffer), handle); nread = url_fread(buffer, 1, sizeof(buffer), handle);
fwrite(buffer,1,nread,outf); fwrite(buffer, 1, nread, outf);
} while(nread); } while(nread);
url_fclose(handle); url_fclose(handle);
@ -509,7 +517,7 @@ int main(int argc, char *argv[])
/* Test rewind */ /* Test rewind */
outf=fopen("rewind.test","w+"); outf = fopen(REWINDFILE, "wb+");
if(!outf) { if(!outf) {
perror("couldn't open fread output file\n"); perror("couldn't open fread output file\n");
return 1; return 1;
@ -522,21 +530,19 @@ int main(int argc, char *argv[])
return 2; return 2;
} }
nread = url_fread(buffer, 1,sizeof(buffer), handle); nread = url_fread(buffer, 1, sizeof(buffer), handle);
fwrite(buffer,1,nread,outf); fwrite(buffer, 1, nread, outf);
url_rewind(handle); url_rewind(handle);
buffer[0]='\n'; buffer[0]='\n';
fwrite(buffer,1,1,outf); fwrite(buffer, 1, 1, outf);
nread = url_fread(buffer, 1,sizeof(buffer), handle);
fwrite(buffer,1,nread,outf);
nread = url_fread(buffer, 1, sizeof(buffer), handle);
fwrite(buffer, 1, nread, outf);
url_fclose(handle); url_fclose(handle);
fclose(outf); fclose(outf);
return 0;/* all done */ return 0;/* all done */
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* FTP wildcard pattern matching
* </DESC>
*/
#include <curl/curl.h> #include <curl/curl.h>
#include <stdio.h> #include <stdio.h>
@ -115,7 +119,7 @@ static long file_is_coming(struct curl_fileinfo *finfo,
return CURL_CHUNK_BGN_FUNC_SKIP; return CURL_CHUNK_BGN_FUNC_SKIP;
} }
data->output = fopen(finfo->filename, "w"); data->output = fopen(finfo->filename, "wb");
if(!data->output) { if(!data->output) {
return CURL_CHUNK_BGN_FUNC_FAIL; return CURL_CHUNK_BGN_FUNC_FAIL;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -23,11 +23,9 @@
#include <curl/curl.h> #include <curl/curl.h>
/* /* <DESC>
* This is an example showing how to get a single file from an FTP server. * Get a single file from an FTP server.
* It delays the actual destination file creation until the first write * </DESC>
* callback so that it won't create an empty file in case the remote file
* doesn't exist or something else fails.
*/ */
struct FtpFile { struct FtpFile {
@ -37,10 +35,10 @@ struct FtpFile {
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{ {
struct FtpFile *out=(struct FtpFile *)stream; struct FtpFile *out = (struct FtpFile *)stream;
if(out && !out->stream) { if(out && !out->stream) {
/* open file for writing */ /* open file for writing */
out->stream=fopen(out->filename, "wb"); out->stream = fopen(out->filename, "wb");
if(!out->stream) if(!out->stream)
return -1; /* failure, can't open file to write */ return -1; /* failure, can't open file to write */
} }
@ -52,8 +50,8 @@ int main(void)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct FtpFile ftpfile={ struct FtpFile ftpfile = {
"curl.tar.gz", /* name to store the file as if succesful */ "curl.tar.gz", /* name to store the file as if successful */
NULL NULL
}; };
@ -65,7 +63,7 @@ int main(void)
* You better replace the URL with one that works! * You better replace the URL with one that works!
*/ */
curl_easy_setopt(curl, CURLOPT_URL, curl_easy_setopt(curl, CURLOPT_URL,
"ftp://ftp.example.com/pub/www/utilities/curl/curl-7.9.2.tar.gz"); "ftp://ftp.example.com/curl/curl-7.9.2.tar.gz");
/* Define our callback to get called when there's data to be written */ /* Define our callback to get called when there's data to be written */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
/* Set a pointer to our struct to pass to the callback */ /* Set a pointer to our struct to pass to the callback */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -24,9 +24,9 @@
#include <curl/curl.h> #include <curl/curl.h>
/* /* <DESC>
* This is an example showing how to check a single file's size and mtime * Checks a single file's size and mtime from an FTP server.
* from an FTP server. * </DESC>
*/ */
static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data) static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
@ -65,16 +65,18 @@ int main(void)
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(CURLE_OK == res) { if(CURLE_OK == res) {
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */ /* https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
if((CURLE_OK == res) && (filetime >= 0)) { if((CURLE_OK == res) && (filetime >= 0)) {
time_t file_time = (time_t)filetime; time_t file_time = (time_t)filetime;
printf("filetime %s: %s", filename, ctime(&file_time)); printf("filetime %s: %s", filename, ctime(&file_time));
} }
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize); res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD,
&filesize);
if((CURLE_OK == res) && (filesize>0.0)) if((CURLE_OK == res) && (filesize>0.0))
printf("filesize %s: %0.0f bytes\n", filename, filesize); printf("filesize %s: %0.0f bytes\n", filename, filesize);
} else { }
else {
/* we failed */ /* we failed */
fprintf(stderr, "curl told us %d\n", res); fprintf(stderr, "curl told us %d\n", res);
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -23,13 +23,11 @@
#include <curl/curl.h> #include <curl/curl.h>
/* /* <DESC>
* Similar to ftpget.c but this also stores the received response-lines * Similar to ftpget.c but also stores the received response-lines
* in a separate file using our own callback! * in a separate file using our own callback!
* * </DESC>
* This functionality was introduced in libcurl 7.9.3.
*/ */
static size_t static size_t
write_response(void *ptr, size_t size, size_t nmemb, void *data) write_response(void *ptr, size_t size, size_t nmemb, void *data)
{ {
@ -37,6 +35,9 @@ write_response(void *ptr, size_t size, size_t nmemb, void *data)
return fwrite(ptr, size, nmemb, writehere); return fwrite(ptr, size, nmemb, writehere);
} }
#define FTPBODY "ftp-list"
#define FTPHEADERS "ftp-responses"
int main(void) int main(void)
{ {
CURL *curl; CURL *curl;
@ -45,10 +46,10 @@ int main(void)
FILE *respfile; FILE *respfile;
/* local file name to store the file as */ /* local file name to store the file as */
ftpfile = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */ ftpfile = fopen(FTPBODY, "wb"); /* b is binary, needed on win32 */
/* local file name to store the FTP server's response lines in */ /* local file name to store the FTP server's response lines in */
respfile = fopen("ftp-responses", "wb"); /* b is binary, needed on win32 */ respfile = fopen(FTPHEADERS, "wb"); /* b is binary, needed on win32 */
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -24,11 +24,9 @@
#include <curl/curl.h> #include <curl/curl.h>
/* /* <DESC>
* This is an example showing how to get a single file from an FTPS server. * Get a single file from an FTPS server.
* It delays the actual destination file creation until the first write * </DESC>
* callback so that it won't create an empty file in case the remote file
* doesn't exist or something else fails.
*/ */
struct FtpFile { struct FtpFile {
@ -39,10 +37,10 @@ struct FtpFile {
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
void *stream) void *stream)
{ {
struct FtpFile *out=(struct FtpFile *)stream; struct FtpFile *out = (struct FtpFile *)stream;
if(out && !out->stream) { if(out && !out->stream) {
/* open file for writing */ /* open file for writing */
out->stream=fopen(out->filename, "wb"); out->stream = fopen(out->filename, "wb");
if(!out->stream) if(!out->stream)
return -1; /* failure, can't open file to write */ return -1; /* failure, can't open file to write */
} }
@ -54,8 +52,8 @@ int main(void)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct FtpFile ftpfile={ struct FtpFile ftpfile = {
"yourfile.bin", /* name to store the file as if succesful */ "yourfile.bin", /* name to store the file as if successful */
NULL NULL
}; };

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -33,11 +33,10 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
/* /* <DESC>
* This example shows an FTP upload, with a rename of the file just after * Performs an FTP upload and renames the file just after a successful
* a successful upload. * transfer.
* * </DESC>
* Example based on source code provided by Erick Nuwendam. Thanks!
*/ */
#define LOCAL_FILE "/tmp/uploadthis.txt" #define LOCAL_FILE "/tmp/uploadthis.txt"
@ -72,7 +71,7 @@ int main(void)
struct stat file_info; struct stat file_info;
curl_off_t fsize; curl_off_t fsize;
struct curl_slist *headerlist=NULL; struct curl_slist *headerlist = NULL;
static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS; static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
static const char buf_2 [] = "RNTO " RENAME_FILE_TO; static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
@ -105,7 +104,7 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */ /* specify target */
curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL); curl_easy_setopt(curl, CURLOPT_URL, REMOTE_URL);
/* pass in that last of FTP commands to run after the transfer */ /* pass in that last of FTP commands to run after the transfer */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
@ -128,7 +127,7 @@ int main(void)
curl_easy_strerror(res)); curl_easy_strerror(res));
/* clean up the FTP commands list */ /* clean up the FTP commands list */
curl_slist_free_all (headerlist); curl_slist_free_all(headerlist);
/* always cleanup */ /* always cleanup */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,59 +19,44 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Upload to FTP, resuming failed transfers /* <DESC>
* * Upload to FTP, resuming failed transfers.
* Compile for MinGW like this: * </DESC>
* gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
* -lcurl -lmsvcr70
*
* Written by Philip Bock
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
#if defined(_MSC_VER) && (_MSC_VER < 1300)
# error _snscanf requires MSVC 7.0 or later.
#endif
/* The MinGW headers are missing a few Win32 function definitions,
you shouldn't need this if you use VC++ */
#if defined(__MINGW32__) && !defined(__MINGW64__)
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
#endif
/* parse headers for Content-Length */ /* parse headers for Content-Length */
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) static size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb,
void *stream)
{ {
int r; int r;
long len = 0; long len = 0;
/* _snscanf() is Win32 specific */ r = sscanf(ptr, "Content-Length: %ld\n", &len);
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len); if(r)
if (r) /* Microsoft: we don't read the specs */
*((long *) stream) = len; *((long *) stream) = len;
return size * nmemb; return size * nmemb;
} }
/* discard downloaded data */ /* discard downloaded data */
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream) static size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{ {
(void)ptr;
(void)stream;
return size * nmemb; return size * nmemb;
} }
/* read data to upload */ /* read data to upload */
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream) static size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{ {
FILE *f = stream; FILE *f = stream;
size_t n; size_t n;
if (ferror(f)) if(ferror(f))
return CURL_READFUNC_ABORT; return CURL_READFUNC_ABORT;
n = fread(ptr, size, nmemb, f) * size; n = fread(ptr, size, nmemb, f) * size;
@ -80,8 +65,8 @@ size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
} }
int upload(CURL *curlhandle, const char * remotepath, const char * localpath, static int upload(CURL *curlhandle, const char *remotepath,
long timeout, long tries) const char *localpath, long timeout, long tries)
{ {
FILE *f; FILE *f;
long uploaded_len = 0; long uploaded_len = 0;
@ -89,7 +74,7 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
int c; int c;
f = fopen(localpath, "rb"); f = fopen(localpath, "rb");
if (f == NULL) { if(!f) {
perror(NULL); perror(NULL);
return 0; return 0;
} }
@ -98,7 +83,7 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath); curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
if (timeout) if(timeout)
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout); curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc); curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
@ -109,14 +94,15 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc); curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f); curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */ /* disable passive mode */
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-");
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
for (c = 0; (r != CURLE_OK) && (c < tries); c++) { for(c = 0; (r != CURLE_OK) && (c < tries); c++) {
/* are we resuming? */ /* are we resuming? */
if (c) { /* yes */ if(c) { /* yes */
/* determine the length of the file already written */ /* determine the length of the file already written */
/* /*
@ -131,7 +117,7 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L); curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
r = curl_easy_perform(curlhandle); r = curl_easy_perform(curlhandle);
if (r != CURLE_OK) if(r != CURLE_OK)
continue; continue;
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L); curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
@ -150,7 +136,7 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
fclose(f); fclose(f);
if (r == CURLE_OK) if(r == CURLE_OK)
return 1; return 1;
else { else {
fprintf(stderr, "%s\n", curl_easy_strerror(r)); fprintf(stderr, "%s\n", curl_easy_strerror(r));
@ -158,14 +144,15 @@ int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
} }
} }
int main(int c, char **argv) int main(void)
{ {
CURL *curlhandle = NULL; CURL *curlhandle = NULL;
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
curlhandle = curl_easy_init(); curlhandle = curl_easy_init();
upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file", 0, 3); upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file",
0, 3);
curl_easy_cleanup(curlhandle); curl_easy_cleanup(curlhandle);
curl_global_cleanup(); curl_global_cleanup();

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Use getinfo to get content-type after completed transfer.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -27,18 +31,14 @@ int main(void)
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
/* http://curl.haxx.se/libcurl/c/curl_easy_init.html */
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {
/* http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL */
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/"); curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
/* http://curl.haxx.se/libcurl/c/curl_easy_perform.html */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(CURLE_OK == res) { if(CURLE_OK == res) {
char *ct; char *ct;
/* ask for the content-type */ /* ask for the content-type */
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
if((CURLE_OK == res) && ct) if((CURLE_OK == res) && ct)
@ -46,7 +46,6 @@ int main(void)
} }
/* always cleanup */ /* always cleanup */
/* http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }
return 0; return 0;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,8 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Example source code to show how the callback function can be used to /* <DESC>
* download data into a chunk of memory instead of storing it in a file. * Shows how the write callback function can be used to download data into a
* chunk of memory instead of storing it in a file.
* </DESC>
*/ */
#include <stdio.h> #include <stdio.h>
@ -34,7 +36,6 @@ struct MemoryStruct {
size_t size; size_t size;
}; };
static size_t static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{ {
@ -55,7 +56,6 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
return realsize; return realsize;
} }
int main(void) int main(void)
{ {
CURL *curl_handle; CURL *curl_handle;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,38 +19,41 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* multi socket API usage together with with glib2
* </DESC>
*/
/* Example application source code using the multi socket interface to /* Example application source code using the multi socket interface to
* download many files at once. * download many files at once.
* *
* Written by Jeff Pohlmeyer * Written by Jeff Pohlmeyer
Requires glib-2.x and a (POSIX?) system that has mkfifo(). Requires glib-2.x and a (POSIX?) system that has mkfifo().
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
sample programs, adapted to use glib's g_io_channel in place of libevent. sample programs, adapted to use glib's g_io_channel in place of libevent.
When running, the program creates the named pipe "hiper.fifo" When running, the program creates the named pipe "hiper.fifo"
Whenever there is input into the fifo, the program reads the input as a list Whenever there is input into the fifo, the program reads the input as a list
of URL's and creates some new easy handles to fetch each URL via the of URL's and creates some new easy handles to fetch each URL via the
curl_multi "hiper" API. curl_multi "hiper" API.
Thus, you can try a single URL: Thus, you can try a single URL:
% echo http://www.yahoo.com > hiper.fifo % echo http://www.yahoo.com > hiper.fifo
Or a whole bunch of them: Or a whole bunch of them:
% cat my-url-list > hiper.fifo % cat my-url-list > hiper.fifo
The fifo buffer is handled almost instantly, so you can even add more URL's The fifo buffer is handled almost instantly, so you can even add more URL's
while the previous requests are still being downloaded. while the previous requests are still being downloaded.
This is purely a demo app, all retrieved data is simply discarded by the write This is purely a demo app, all retrieved data is simply discarded by the write
callback. callback.
*/ */
#include <glib.h> #include <glib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -60,13 +63,10 @@ callback.
#include <errno.h> #include <errno.h>
#include <curl/curl.h> #include <curl/curl.h>
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */ #define MSG_OUT g_print /* Change to "g_error" to write to stderr */
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */ #define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */ #define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
/* Global information, common to all connections */ /* Global information, common to all connections */
typedef struct _GlobalInfo { typedef struct _GlobalInfo {
CURLM *multi; CURLM *multi;
@ -74,8 +74,6 @@ typedef struct _GlobalInfo {
int still_running; int still_running;
} GlobalInfo; } GlobalInfo;
/* Information associated with a specific easy handle */ /* Information associated with a specific easy handle */
typedef struct _ConnInfo { typedef struct _ConnInfo {
CURL *easy; CURL *easy;
@ -84,7 +82,6 @@ typedef struct _ConnInfo {
char error[CURL_ERROR_SIZE]; char error[CURL_ERROR_SIZE];
} ConnInfo; } ConnInfo;
/* Information associated with a specific socket */ /* Information associated with a specific socket */
typedef struct _SockInfo { typedef struct _SockInfo {
curl_socket_t sockfd; curl_socket_t sockfd;
@ -96,30 +93,26 @@ typedef struct _SockInfo {
GlobalInfo *global; GlobalInfo *global;
} SockInfo; } SockInfo;
/* Die if we get a bad CURLMcode somewhere */ /* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(const char *where, CURLMcode code) { static void mcode_or_die(const char *where, CURLMcode code)
if ( CURLM_OK != code ) { {
if(CURLM_OK != code) {
const char *s; const char *s;
switch (code) { switch(code) {
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; case CURLM_BAD_HANDLE: s = "CURLM_BAD_HANDLE"; break;
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break; case CURLM_BAD_EASY_HANDLE: s = "CURLM_BAD_EASY_HANDLE"; break;
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break; case CURLM_OUT_OF_MEMORY: s = "CURLM_OUT_OF_MEMORY"; break;
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break; case CURLM_INTERNAL_ERROR: s = "CURLM_INTERNAL_ERROR"; break;
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break; case CURLM_BAD_SOCKET: s = "CURLM_BAD_SOCKET"; break;
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break; case CURLM_UNKNOWN_OPTION: s = "CURLM_UNKNOWN_OPTION"; break;
case CURLM_LAST: s="CURLM_LAST"; break; case CURLM_LAST: s = "CURLM_LAST"; break;
default: s="CURLM_unknown"; default: s = "CURLM_unknown";
} }
MSG_OUT("ERROR: %s returns %s\n", where, s); MSG_OUT("ERROR: %s returns %s\n", where, s);
exit(code); exit(code);
} }
} }
/* Check for completed transfers, and remove their easy handles */ /* Check for completed transfers, and remove their easy handles */
static void check_multi_info(GlobalInfo *g) static void check_multi_info(GlobalInfo *g)
{ {
@ -131,8 +124,8 @@ static void check_multi_info(GlobalInfo *g)
CURLcode res; CURLcode res;
MSG_OUT("REMAINING: %d\n", g->still_running); MSG_OUT("REMAINING: %d\n", g->still_running);
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) { if(msg->msg == CURLMSG_DONE) {
easy = msg->easy_handle; easy = msg->easy_handle;
res = msg->data.result; res = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
@ -146,8 +139,6 @@ static void check_multi_info(GlobalInfo *g)
} }
} }
/* Called by glib when our timeout expires */ /* Called by glib when our timeout expires */
static gboolean timer_cb(gpointer data) static gboolean timer_cb(gpointer data)
{ {
@ -155,38 +146,42 @@ static gboolean timer_cb(gpointer data)
CURLMcode rc; CURLMcode rc;
rc = curl_multi_socket_action(g->multi, rc = curl_multi_socket_action(g->multi,
CURL_SOCKET_TIMEOUT, 0, &g->still_running); CURL_SOCKET_TIMEOUT, 0, &g->still_running);
mcode_or_die("timer_cb: curl_multi_socket_action", rc); mcode_or_die("timer_cb: curl_multi_socket_action", rc);
check_multi_info(g); check_multi_info(g);
return FALSE; return FALSE;
} }
/* Update the event timer after curl_multi library calls */ /* Update the event timer after curl_multi library calls */
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
{ {
struct timeval timeout; struct timeval timeout;
GlobalInfo *g=(GlobalInfo *)userp; GlobalInfo *g = (GlobalInfo *)userp;
timeout.tv_sec = timeout_ms/1000; timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000; timeout.tv_usec = (timeout_ms%1000)*1000;
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n", MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
timeout_ms, timeout.tv_sec, timeout.tv_usec); timeout_ms, timeout.tv_sec, timeout.tv_usec);
/* TODO
*
* if timeout_ms is 0, call curl_multi_socket_action() at once!
*
* if timeout_ms is -1, just delete the timer
*
* for all other values of timeout_ms, this should set or *update*
* the timer to the new value
*/
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g); g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
return 0; return 0;
} }
/* Called by glib when we get action on a multi socket */ /* Called by glib when we get action on a multi socket */
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
{ {
GlobalInfo *g = (GlobalInfo*) data; GlobalInfo *g = (GlobalInfo*) data;
CURLMcode rc; CURLMcode rc;
int fd=g_io_channel_unix_get_fd(ch); int fd = g_io_channel_unix_get_fd(ch);
int action = int action =
(condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
@ -198,54 +193,55 @@ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
check_multi_info(g); check_multi_info(g);
if(g->still_running) { if(g->still_running) {
return TRUE; return TRUE;
} else { }
else {
MSG_OUT("last transfer done, kill timeout\n"); MSG_OUT("last transfer done, kill timeout\n");
if (g->timer_event) { g_source_remove(g->timer_event); } if(g->timer_event) {
g_source_remove(g->timer_event);
}
return FALSE; return FALSE;
} }
} }
/* Clean up the SockInfo structure */ /* Clean up the SockInfo structure */
static void remsock(SockInfo *f) static void remsock(SockInfo *f)
{ {
if (!f) { return; } if(!f) {
if (f->ev) { g_source_remove(f->ev); } return;
}
if(f->ev) {
g_source_remove(f->ev);
}
g_free(f); g_free(f);
} }
/* Assign information to a SockInfo structure */ /* Assign information to a SockInfo structure */
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
GlobalInfo *g)
{ {
GIOCondition kind = GIOCondition kind =
(act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0); (act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
f->sockfd = s; f->sockfd = s;
f->action = act; f->action = act;
f->easy = e; f->easy = e;
if (f->ev) { g_source_remove(f->ev); } if(f->ev) {
f->ev=g_io_add_watch(f->ch, kind, event_cb,g); g_source_remove(f->ev);
}
f->ev = g_io_add_watch(f->ch, kind, event_cb, g);
} }
/* Initialize a new SockInfo structure */ /* Initialize a new SockInfo structure */
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
{ {
SockInfo *fdp = g_malloc0(sizeof(SockInfo)); SockInfo *fdp = g_malloc0(sizeof(SockInfo));
fdp->global = g; fdp->global = g;
fdp->ch=g_io_channel_unix_new(s); fdp->ch = g_io_channel_unix_new(s);
setsock(fdp, s, easy, action, g); setsock(fdp, s, easy, action, g);
curl_multi_assign(g->multi, s, fdp); curl_multi_assign(g->multi, s, fdp);
} }
/* CURLMOPT_SOCKETFUNCTION */ /* CURLMOPT_SOCKETFUNCTION */
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
{ {
@ -254,14 +250,15 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if (what == CURL_POLL_REMOVE) { if(what == CURL_POLL_REMOVE) {
MSG_OUT("\n"); MSG_OUT("\n");
remsock(fdp); remsock(fdp);
} else { }
if (!fdp) { else {
if(!fdp) {
MSG_OUT("Adding data: %s%s\n", MSG_OUT("Adding data: %s%s\n",
what&CURL_POLL_IN?"READ":"", what&CURL_POLL_IN?"READ":"",
what&CURL_POLL_OUT?"WRITE":"" ); what&CURL_POLL_OUT?"WRITE":"");
addsock(s, e, what, g); addsock(s, e, what, g);
} }
else { else {
@ -273,8 +270,6 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
return 0; return 0;
} }
/* CURLOPT_WRITEFUNCTION */ /* CURLOPT_WRITEFUNCTION */
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{ {
@ -285,30 +280,25 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
return realsize; return realsize;
} }
/* CURLOPT_PROGRESSFUNCTION */ /* CURLOPT_PROGRESSFUNCTION */
static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln) static int prog_cb(void *p, double dltotal, double dlnow, double ult,
double uln)
{ {
ConnInfo *conn = (ConnInfo *)p; ConnInfo *conn = (ConnInfo *)p;
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal); MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
return 0; return 0;
} }
/* Create a new easy handle, and add it to the global curl_multi */ /* Create a new easy handle, and add it to the global curl_multi */
static void new_conn(char *url, GlobalInfo *g ) static void new_conn(char *url, GlobalInfo *g)
{ {
ConnInfo *conn; ConnInfo *conn;
CURLMcode rc; CURLMcode rc;
conn = g_malloc0(sizeof(ConnInfo)); conn = g_malloc0(sizeof(ConnInfo));
conn->error[0]='\0'; conn->error[0]='\0';
conn->easy = curl_easy_init(); conn->easy = curl_easy_init();
if (!conn->easy) { if(!conn->easy) {
MSG_OUT("curl_easy_init() failed, exiting!\n"); MSG_OUT("curl_easy_init() failed, exiting!\n");
exit(2); exit(2);
} }
@ -329,100 +319,97 @@ static void new_conn(char *url, GlobalInfo *g )
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
rc =curl_multi_add_handle(g->multi, conn->easy); rc = curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc); mcode_or_die("new_conn: curl_multi_add_handle", rc);
/* note that the add_handle() will set a time-out to trigger very soon so /* note that the add_handle() will set a time-out to trigger very soon so
that the necessary socket_action() call will be called by this app */ that the necessary socket_action() call will be called by this app */
} }
/* This gets called by glib whenever data is received from the fifo */ /* This gets called by glib whenever data is received from the fifo */
static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data) static gboolean fifo_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
{ {
#define BUF_SIZE 1024 #define BUF_SIZE 1024
gsize len, tp; gsize len, tp;
gchar *buf, *tmp, *all=NULL; gchar *buf, *tmp, *all = NULL;
GIOStatus rv; GIOStatus rv;
do { do {
GError *err=NULL; GError *err = NULL;
rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err); rv = g_io_channel_read_line(ch, &buf, &len, &tp, &err);
if ( buf ) { if(buf) {
if (tp) { buf[tp]='\0'; } if(tp) {
new_conn(buf,(GlobalInfo*)data); buf[tp]='\0';
}
new_conn(buf, (GlobalInfo*)data);
g_free(buf); g_free(buf);
} else { }
buf = g_malloc(BUF_SIZE+1); else {
while (TRUE) { buf = g_malloc(BUF_SIZE + 1);
while(TRUE) {
buf[BUF_SIZE]='\0'; buf[BUF_SIZE]='\0';
g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err); g_io_channel_read_chars(ch, buf, BUF_SIZE, &len, &err);
if (len) { if(len) {
buf[len]='\0'; buf[len]='\0';
if (all) { if(all) {
tmp=all; tmp = all;
all=g_strdup_printf("%s%s", tmp, buf); all = g_strdup_printf("%s%s", tmp, buf);
g_free(tmp); g_free(tmp);
} else { }
else {
all = g_strdup(buf); all = g_strdup(buf);
} }
} else { }
break; else {
break;
} }
} }
if (all) { if(all) {
new_conn(all,(GlobalInfo*)data); new_conn(all, (GlobalInfo*)data);
g_free(all); g_free(all);
} }
g_free(buf); g_free(buf);
} }
if ( err ) { if(err) {
g_error("fifo_cb: %s", err->message); g_error("fifo_cb: %s", err->message);
g_free(err); g_free(err);
break; break;
} }
} while ( (len) && (rv == G_IO_STATUS_NORMAL) ); } while((len) && (rv == G_IO_STATUS_NORMAL));
return TRUE; return TRUE;
} }
int init_fifo(void) int init_fifo(void)
{ {
struct stat st; struct stat st;
const char *fifo = "hiper.fifo"; const char *fifo = "hiper.fifo";
int socket; int socket;
if (lstat (fifo, &st) == 0) { if(lstat (fifo, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFREG) { if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST; errno = EEXIST;
perror("lstat"); perror("lstat");
exit (1); exit(1);
}
} }
}
unlink (fifo); unlink(fifo);
if (mkfifo (fifo, 0600) == -1) { if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo"); perror("mkfifo");
exit (1); exit(1);
} }
socket = open (fifo, O_RDWR | O_NONBLOCK, 0); socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
if (socket == -1) { if(socket == -1) {
perror("open"); perror("open");
exit (1); exit(1);
} }
MSG_OUT("Now, pipe some URL's into > %s\n", fifo); MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
return socket;
return socket;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
GlobalInfo *g; GlobalInfo *g;
@ -430,12 +417,12 @@ int main(int argc, char **argv)
GMainLoop*gmain; GMainLoop*gmain;
int fd; int fd;
GIOChannel* ch; GIOChannel* ch;
g=g_malloc0(sizeof(GlobalInfo)); g = g_malloc0(sizeof(GlobalInfo));
fd=init_fifo(); fd = init_fifo();
ch=g_io_channel_unix_new(fd); ch = g_io_channel_unix_new(fd);
g_io_add_watch(ch,G_IO_IN,fifo_cb,g); g_io_add_watch(ch, G_IO_IN, fifo_cb, g);
gmain=g_main_loop_new(NULL,FALSE); gmain = g_main_loop_new(NULL, FALSE);
g->multi = curl_multi_init(); g->multi = curl_multi_init();
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g); curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* multi socket API usage with libevent 2
* </DESC>
*/
/* Example application source code using the multi socket interface to /* Example application source code using the multi socket interface to
download many files at once. download many files at once.
@ -78,7 +82,7 @@ typedef struct _GlobalInfo
struct event *timer_event; struct event *timer_event;
CURLM *multi; CURLM *multi;
int still_running; int still_running;
FILE* input; FILE *input;
} GlobalInfo; } GlobalInfo;
@ -104,8 +108,6 @@ typedef struct _SockInfo
GlobalInfo *global; GlobalInfo *global;
} SockInfo; } SockInfo;
/* Update the event timer after curl_multi library calls */ /* Update the event timer after curl_multi library calls */
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{ {
@ -115,6 +117,16 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
timeout.tv_sec = timeout_ms/1000; timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000; timeout.tv_usec = (timeout_ms%1000)*1000;
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms); fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
/* TODO
*
* if timeout_ms is 0, call curl_multi_socket_action() at once!
*
* if timeout_ms is -1, just delete the timer
*
* for all other values of timeout_ms, this should set or *update*
* the timer to the new value
*/
evtimer_add(g->timer_event, &timeout); evtimer_add(g->timer_event, &timeout);
return 0; return 0;
} }
@ -122,18 +134,18 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
/* Die if we get a bad CURLMcode somewhere */ /* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(const char *where, CURLMcode code) static void mcode_or_die(const char *where, CURLMcode code)
{ {
if ( CURLM_OK != code ) { if(CURLM_OK != code) {
const char *s; const char *s;
switch (code) { switch(code) {
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; case CURLM_BAD_HANDLE: s = "CURLM_BAD_HANDLE"; break;
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break; case CURLM_BAD_EASY_HANDLE: s = "CURLM_BAD_EASY_HANDLE"; break;
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break; case CURLM_OUT_OF_MEMORY: s = "CURLM_OUT_OF_MEMORY"; break;
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break; case CURLM_INTERNAL_ERROR: s = "CURLM_INTERNAL_ERROR"; break;
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break; case CURLM_UNKNOWN_OPTION: s = "CURLM_UNKNOWN_OPTION"; break;
case CURLM_LAST: s="CURLM_LAST"; break; case CURLM_LAST: s = "CURLM_LAST"; break;
default: s="CURLM_unknown"; default: s = "CURLM_unknown";
break; break;
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; case CURLM_BAD_SOCKET: s = "CURLM_BAD_SOCKET";
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
/* ignore this error */ /* ignore this error */
return; return;
@ -156,8 +168,8 @@ static void check_multi_info(GlobalInfo *g)
CURLcode res; CURLcode res;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running); fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) { if(msg->msg == CURLMSG_DONE) {
easy = msg->easy_handle; easy = msg->easy_handle;
res = msg->data.result; res = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
@ -187,9 +199,9 @@ static void event_cb(int fd, short kind, void *userp)
mcode_or_die("event_cb: curl_multi_socket_action", rc); mcode_or_die("event_cb: curl_multi_socket_action", rc);
check_multi_info(g); check_multi_info(g);
if ( g->still_running <= 0 ) { if(g->still_running <= 0) {
fprintf(MSG_OUT, "last transfer done, kill timeout\n"); fprintf(MSG_OUT, "last transfer done, kill timeout\n");
if (evtimer_pending(g->timer_event, NULL)) { if(evtimer_pending(g->timer_event, NULL)) {
evtimer_del(g->timer_event); evtimer_del(g->timer_event);
} }
} }
@ -216,8 +228,8 @@ static void timer_cb(int fd, short kind, void *userp)
/* Clean up the SockInfo structure */ /* Clean up the SockInfo structure */
static void remsock(SockInfo *f) static void remsock(SockInfo *f)
{ {
if (f) { if(f) {
if (f->evset) if(f->evset)
event_free(f->ev); event_free(f->ev);
free(f); free(f);
} }
@ -226,7 +238,8 @@ static void remsock(SockInfo *f)
/* Assign information to a SockInfo structure */ /* Assign information to a SockInfo structure */
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
GlobalInfo *g)
{ {
int kind = int kind =
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST; (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
@ -234,7 +247,7 @@ static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
f->sockfd = s; f->sockfd = s;
f->action = act; f->action = act;
f->easy = e; f->easy = e;
if (f->evset) if(f->evset)
event_free(f->ev); event_free(f->ev);
f->ev = event_new(g->evbase, f->sockfd, kind, event_cb, g); f->ev = event_new(g->evbase, f->sockfd, kind, event_cb, g);
f->evset = 1; f->evset = 1;
@ -262,12 +275,12 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
fprintf(MSG_OUT, fprintf(MSG_OUT,
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if (what == CURL_POLL_REMOVE) { if(what == CURL_POLL_REMOVE) {
fprintf(MSG_OUT, "\n"); fprintf(MSG_OUT, "\n");
remsock(fdp); remsock(fdp);
} }
else { else {
if (!fdp) { if(!fdp) {
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]); fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
addsock(s, e, what, g); addsock(s, e, what, g);
} }
@ -295,8 +308,8 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
/* CURLOPT_PROGRESSFUNCTION */ /* CURLOPT_PROGRESSFUNCTION */
static int prog_cb (void *p, double dltotal, double dlnow, double ult, static int prog_cb(void *p, double dltotal, double dlnow, double ult,
double uln) double uln)
{ {
ConnInfo *conn = (ConnInfo *)p; ConnInfo *conn = (ConnInfo *)p;
(void)ult; (void)ult;
@ -308,7 +321,7 @@ static int prog_cb (void *p, double dltotal, double dlnow, double ult,
/* Create a new easy handle, and add it to the global curl_multi */ /* Create a new easy handle, and add it to the global curl_multi */
static void new_conn(char *url, GlobalInfo *g ) static void new_conn(char *url, GlobalInfo *g)
{ {
ConnInfo *conn; ConnInfo *conn;
CURLMcode rc; CURLMcode rc;
@ -318,7 +331,7 @@ static void new_conn(char *url, GlobalInfo *g )
conn->error[0]='\0'; conn->error[0]='\0';
conn->easy = curl_easy_init(); conn->easy = curl_easy_init();
if (!conn->easy) { if(!conn->easy) {
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n"); fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
exit(2); exit(2);
} }
@ -326,7 +339,7 @@ static void new_conn(char *url, GlobalInfo *g )
conn->url = strdup(url); conn->url = strdup(url);
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L); curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
@ -346,46 +359,48 @@ static void new_conn(char *url, GlobalInfo *g )
static void fifo_cb(int fd, short event, void *arg) static void fifo_cb(int fd, short event, void *arg)
{ {
char s[1024]; char s[1024];
long int rv=0; long int rv = 0;
int n=0; int n = 0;
GlobalInfo *g = (GlobalInfo *)arg; GlobalInfo *g = (GlobalInfo *)arg;
(void)fd; /* unused */ (void)fd; /* unused */
(void)event; /* unused */ (void)event; /* unused */
do { do {
s[0]='\0'; s[0]='\0';
rv=fscanf(g->input, "%1023s%n", s, &n); rv = fscanf(g->input, "%1023s%n", s, &n);
s[n]='\0'; s[n]='\0';
if ( n && s[0] ) { if(n && s[0]) {
new_conn(s,arg); /* if we read a URL, go get it! */ new_conn(s, arg); /* if we read a URL, go get it! */
} else break; }
} while ( rv != EOF); else
break;
} while(rv != EOF);
} }
/* Create a named pipe and tell libevent to monitor it */ /* Create a named pipe and tell libevent to monitor it */
static const char *fifo = "hiper.fifo"; static const char *fifo = "hiper.fifo";
static int init_fifo (GlobalInfo *g) static int init_fifo(GlobalInfo *g)
{ {
struct stat st; struct stat st;
curl_socket_t sockfd; curl_socket_t sockfd;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo); fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if (lstat (fifo, &st) == 0) { if(lstat (fifo, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFREG) { if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST; errno = EEXIST;
perror("lstat"); perror("lstat");
exit (1); exit(1);
} }
} }
unlink(fifo); unlink(fifo);
if (mkfifo (fifo, 0600) == -1) { if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo"); perror("mkfifo");
exit (1); exit(1);
} }
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0); sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
if (sockfd == -1) { if(sockfd == -1) {
perror("open"); perror("open");
exit (1); exit(1);
} }
g->input = fdopen(sockfd, "r"); g->input = fdopen(sockfd, "r");

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -20,13 +20,13 @@
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Uses the "Streaming HTML parser" to extract the href pieces in a streaming
* manner from a downloaded HTML.
* </DESC>
*/
/* /*
* This example uses the "Streaming HTML parser" to extract the href pieces in * The HTML parser is found at http://code.google.com/p/htmlstreamparser/
* a streaming manner from a downloaded HTML. Kindly donated by Michał
* Kowalczyk.
*
* The parser is found at
* http://code.google.com/p/htmlstreamparser/
*/ */
#include <stdio.h> #include <stdio.h>
@ -38,11 +38,11 @@ static size_t write_callback(void *buffer, size_t size, size_t nmemb,
void *hsp) void *hsp)
{ {
size_t realsize = size * nmemb, p; size_t realsize = size * nmemb, p;
for (p = 0; p < realsize; p++) { for(p = 0; p < realsize; p++) {
html_parser_char_parse(hsp, ((char *)buffer)[p]); html_parser_char_parse(hsp, ((char *)buffer)[p]);
if (html_parser_cmp_tag(hsp, "a", 1)) if(html_parser_cmp_tag(hsp, "a", 1))
if (html_parser_cmp_attr(hsp, "href", 4)) if(html_parser_cmp_attr(hsp, "href", 4))
if (html_parser_is_in(hsp, HTML_VALUE_ENDED)) { if(html_parser_is_in(hsp, HTML_VALUE_ENDED)) {
html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0'; html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0';
printf("%s\n", html_parser_val(hsp)); printf("%s\n", html_parser_val(hsp));
} }
@ -56,7 +56,7 @@ int main(int argc, char *argv[])
CURL *curl; CURL *curl;
HTMLSTREAMPARSER *hsp; HTMLSTREAMPARSER *hsp;
if (argc != 2) { if(argc != 2) {
printf("Usage: %s URL\n", argv[0]); printf("Usage: %s URL\n", argv[0]);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,13 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Download a document and use libtidy to parse the HTML. /* <DESC>
* Written by Jeff Pohlmeyer * Download a document and use libtidy to parse the HTML.
* * </DESC>
*/
/*
* LibTidy => http://tidy.sourceforge.net * LibTidy => http://tidy.sourceforge.net
*
* gcc -Wall -I/usr/local/include tidycurl.c -lcurl -ltidy -o tidycurl
*
*/ */
#include <stdio.h> #include <stdio.h>
@ -38,29 +37,27 @@ uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
{ {
uint r; uint r;
r = size * nmemb; r = size * nmemb;
tidyBufAppend( out, in, r ); tidyBufAppend(out, in, r);
return(r); return r;
} }
/* Traverse the document tree */ /* Traverse the document tree */
void dumpNode(TidyDoc doc, TidyNode tnod, int indent ) void dumpNode(TidyDoc doc, TidyNode tnod, int indent)
{ {
TidyNode child; TidyNode child;
for ( child = tidyGetChild(tnod); child; child = tidyGetNext(child) ) for(child = tidyGetChild(tnod); child; child = tidyGetNext(child) ) {
{ ctmbstr name = tidyNodeGetName(child);
ctmbstr name = tidyNodeGetName( child ); if(name) {
if ( name )
{
/* if it has a name, then it's an HTML tag ... */ /* if it has a name, then it's an HTML tag ... */
TidyAttr attr; TidyAttr attr;
printf( "%*.*s%s ", indent, indent, "<", name); printf("%*.*s%s ", indent, indent, "<", name);
/* walk the attribute list */ /* walk the attribute list */
for ( attr=tidyAttrFirst(child); attr; attr=tidyAttrNext(attr) ) { for(attr = tidyAttrFirst(child); attr; attr = tidyAttrNext(attr) ) {
printf(tidyAttrName(attr)); printf(tidyAttrName(attr));
tidyAttrValue(attr)?printf("=\"%s\" ", tidyAttrValue(attr)?printf("=\"%s\" ",
tidyAttrValue(attr)):printf(" "); tidyAttrValue(attr)):printf(" ");
} }
printf( ">\n"); printf(">\n");
} }
else { else {
/* if it doesn't have a name, then it's probably text, cdata, etc... */ /* if it doesn't have a name, then it's probably text, cdata, etc... */
@ -70,12 +67,12 @@ void dumpNode(TidyDoc doc, TidyNode tnod, int indent )
printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:""); printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
tidyBufFree(&buf); tidyBufFree(&buf);
} }
dumpNode( doc, child, indent + 4 ); /* recursive */ dumpNode(doc, child, indent + 4); /* recursive */
} }
} }
int main(int argc, char **argv ) int main(int argc, char **argv)
{ {
CURL *curl; CURL *curl;
char curl_errbuf[CURL_ERROR_SIZE]; char curl_errbuf[CURL_ERROR_SIZE];
@ -83,7 +80,7 @@ int main(int argc, char **argv )
TidyBuffer docbuf = {0}; TidyBuffer docbuf = {0};
TidyBuffer tidy_errbuf = {0}; TidyBuffer tidy_errbuf = {0};
int err; int err;
if ( argc == 2) { if(argc == 2) {
curl = curl_easy_init(); curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, argv[1]); curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
@ -94,19 +91,19 @@ int main(int argc, char **argv )
tdoc = tidyCreate(); tdoc = tidyCreate();
tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */ tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
tidyOptSetInt(tdoc, TidyWrapLen, 4096); tidyOptSetInt(tdoc, TidyWrapLen, 4096);
tidySetErrorBuffer( tdoc, &tidy_errbuf ); tidySetErrorBuffer(tdoc, &tidy_errbuf);
tidyBufInit(&docbuf); tidyBufInit(&docbuf);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
err=curl_easy_perform(curl); err = curl_easy_perform(curl);
if ( !err ) { if(!err) {
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */ err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
if ( err >= 0 ) { if(err >= 0) {
err = tidyCleanAndRepair(tdoc); /* fix any problems */ err = tidyCleanAndRepair(tdoc); /* fix any problems */
if ( err >= 0 ) { if(err >= 0) {
err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */ err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
if ( err >= 0 ) { if(err >= 0) {
dumpNode( tdoc, tidyGetRoot(tdoc), 0 ); /* walk the tree */ dumpNode(tdoc, tidyGetRoot(tdoc), 0); /* walk the tree */
fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */ fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
} }
} }
@ -120,11 +117,11 @@ int main(int argc, char **argv )
tidyBufFree(&docbuf); tidyBufFree(&docbuf);
tidyBufFree(&tidy_errbuf); tidyBufFree(&tidy_errbuf);
tidyRelease(tdoc); tidyRelease(tdoc);
return(err); return err;
} }
else else
printf( "usage: %s <url>\n", argv[0] ); printf("usage: %s <url>\n", argv[0]);
return(0); return 0;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,15 +19,17 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
// Get a web page, parse it with libxml. /* <DESC>
// * Get a web page, extract the title with libxml.
// Written by Lars Nilsson * </DESC>
//
// GNU C++ compile command line suggestion (edit paths accordingly):
//
// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cpp \
// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
Written by Lars Nilsson
GNU C++ compile command line suggestion (edit paths accordingly):
g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cpp \
-o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -40,7 +42,7 @@
// //
#ifdef _MSC_VER #ifdef _MSC_VER
#define COMPARE(a, b) (!stricmp((a), (b))) #define COMPARE(a, b) (!_stricmp((a), (b)))
#else #else
#define COMPARE(a, b) (!strcasecmp((a), (b))) #define COMPARE(a, b) (!strcasecmp((a), (b)))
#endif #endif
@ -70,7 +72,7 @@ static std::string buffer;
static int writer(char *data, size_t size, size_t nmemb, static int writer(char *data, size_t size, size_t nmemb,
std::string *writerData) std::string *writerData)
{ {
if (writerData == NULL) if(writerData == NULL)
return 0; return 0;
writerData->append(data, size*nmemb); writerData->append(data, size*nmemb);
@ -88,50 +90,38 @@ static bool init(CURL *&conn, char *url)
conn = curl_easy_init(); conn = curl_easy_init();
if (conn == NULL) if(conn == NULL) {
{
fprintf(stderr, "Failed to create CURL connection\n"); fprintf(stderr, "Failed to create CURL connection\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer); code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to set error buffer [%d]\n", code); fprintf(stderr, "Failed to set error buffer [%d]\n", code);
return false; return false;
} }
code = curl_easy_setopt(conn, CURLOPT_URL, url); code = curl_easy_setopt(conn, CURLOPT_URL, url);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer); fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
return false; return false;
} }
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L); code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer); fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
return false; return false;
} }
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer); code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer); fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
return false; return false;
} }
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer); code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer); fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
return false; return false;
} }
@ -148,8 +138,7 @@ static void StartElement(void *voidContext,
{ {
Context *context = (Context *)voidContext; Context *context = (Context *)voidContext;
if (COMPARE((char *)name, "TITLE")) if(COMPARE((char *)name, "TITLE")) {
{
context->title = ""; context->title = "";
context->addTitle = true; context->addTitle = true;
} }
@ -165,7 +154,7 @@ static void EndElement(void *voidContext,
{ {
Context *context = (Context *)voidContext; Context *context = (Context *)voidContext;
if (COMPARE((char *)name, "TITLE")) if(COMPARE((char *)name, "TITLE"))
context->addTitle = false; context->addTitle = false;
} }
@ -177,7 +166,7 @@ static void handleCharacters(Context *context,
const xmlChar *chars, const xmlChar *chars,
int length) int length)
{ {
if (context->addTitle) if(context->addTitle)
context->title.append((char *)chars, length); context->title.append((char *)chars, length);
} }
@ -271,10 +260,8 @@ int main(int argc, char *argv[])
// Ensure one argument is given // Ensure one argument is given
if (argc != 2) if(argc != 2) {
{
fprintf(stderr, "Usage: %s <url>\n", argv[0]); fprintf(stderr, "Usage: %s <url>\n", argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -282,10 +269,8 @@ int main(int argc, char *argv[])
// Initialize CURL connection // Initialize CURL connection
if (!init(conn, argv[1])) if(!init(conn, argv[1])) {
{
fprintf(stderr, "Connection initializion failed\n"); fprintf(stderr, "Connection initializion failed\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -294,19 +279,15 @@ int main(int argc, char *argv[])
code = curl_easy_perform(conn); code = curl_easy_perform(conn);
curl_easy_cleanup(conn); curl_easy_cleanup(conn);
if (code != CURLE_OK) if(code != CURLE_OK) {
{
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer); fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Parse the (assumed) HTML code // Parse the (assumed) HTML code
parseHtml(buffer, title); parseHtml(buffer, title);
// Display the extracted title // Display the extracted title
printf("Title: %s\n", title.c_str()); printf("Title: %s\n", title.c_str());
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* simple HTTP POST using the easy interface
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* HTTP request with custom modified, removed and added headers
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* HTTP PUT with easy interface and read callback
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -56,7 +60,7 @@ int main(int argc, char **argv)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
FILE * hd_src ; FILE * hd_src;
struct stat file_info; struct stat file_info;
char *file; char *file;
@ -65,7 +69,7 @@ int main(int argc, char **argv)
if(argc < 3) if(argc < 3)
return 1; return 1;
file= argv[1]; file = argv[1];
url = argv[2]; url = argv[2];
/* get the file size of the local file */ /* get the file size of the local file */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* Simple HTTPS GET
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to send e-mails
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -38,7 +44,8 @@ static const char *payload_text[] = {
"To: " TO "\r\n", "To: " TO "\r\n",
"From: " FROM "(Example User)\r\n", "From: " FROM "(Example User)\r\n",
"Cc: " CC "(Another example User)\r\n", "Cc: " CC "(Another example User)\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\r\n", "Message-ID: "
"<dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\r\n",
"Subject: IMAP example message\r\n", "Subject: IMAP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */ "\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n", "The body of the message starts here.\r\n",
@ -78,6 +85,8 @@ int main(void)
{ {
CURL *curl; CURL *curl;
CURLcode res = CURLE_OK; CURLcode res = CURLE_OK;
const char **p;
long infilesize;
struct upload_status upload_ctx; struct upload_status upload_ctx;
upload_ctx.lines_read = 0; upload_ctx.lines_read = 0;
@ -100,6 +109,12 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
infilesize = 0;
for(p = payload_text; *p; ++p) {
infilesize += (long)strlen(*p);
}
curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
/* Perform the append */ /* Perform the append */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to copy an e-mail from one folder to another
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,7 @@ int main(void)
/* This is source mailbox folder to select */ /* This is source mailbox folder to select */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX"); curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX");
/* Set the COPY command specifing the message ID and destination folder */ /* Set the COPY command specifying the message ID and destination folder */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "COPY 1 FOLDER"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "COPY 1 FOLDER");
/* Note that to perform a move operation you will need to perform the copy, /* Note that to perform a move operation you will need to perform the copy,

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to create a new folder
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,7 @@ int main(void)
/* This is just the server URL */ /* This is just the server URL */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com"); curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
/* Set the CREATE command specifing the new folder name */ /* Set the CREATE command specifying the new folder name */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "CREATE FOLDER"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "CREATE FOLDER");
/* Perform the custom request */ /* Perform the custom request */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to delete a folder
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,7 @@ int main(void)
/* This is just the server URL */ /* This is just the server URL */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com"); curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
/* Set the DELETE command specifing the existing folder */ /* Set the DELETE command specifying the existing folder */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE FOLDER"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE FOLDER");
/* Perform the custom request */ /* Perform the custom request */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to obtain information about a folder
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,7 @@ int main(void)
/* This is just the server URL */ /* This is just the server URL */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com"); curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
/* Set the EXAMINE command specifing the mailbox folder */ /* Set the EXAMINE command specifying the mailbox folder */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXAMINE OUTBOX"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXAMINE OUTBOX");
/* Perform the custom request */ /* Perform the custom request */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to retreieve e-mails
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -40,7 +46,8 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
/* This will fetch message 1 from the user's inbox */ /* This will fetch message 1 from the user's inbox */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1"); curl_easy_setopt(curl, CURLOPT_URL,
"imap://imap.example.com/INBOX/;UID=1");
/* Perform the fetch */ /* Perform the fetch */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example to list the folders within a mailbox
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example to list the subscribed folders
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,7 +19,14 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example using the multi interface
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <curl/curl.h> #include <curl/curl.h>
/* This is a simple example showing how to fetch mail using libcurl's IMAP /* This is a simple example showing how to fetch mail using libcurl's IMAP
@ -113,8 +120,7 @@ int main(void)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -138,7 +144,7 @@ int main(void)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to perform a noop
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to search for new e-mails
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,7 @@ int main(void)
/* This is mailbox folder to select */ /* This is mailbox folder to select */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX"); curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX");
/* Set the SEARCH command specifing what we want to search for. Note that /* Set the SEARCH command specifying what we want to search for. Note that
* this can contain a message sequence set and a number of search criteria * this can contain a message sequence set and a number of search criteria
* keywords including flags such as ANSWERED, DELETED, DRAFT, FLAGGED, NEW, * keywords including flags such as ANSWERED, DELETED, DRAFT, FLAGGED, NEW,
* RECENT and SEEN. For more information about the search criteria please * RECENT and SEEN. For more information about the search criteria please

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example using SSL
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -42,7 +48,8 @@ int main(void)
/* This will fetch message 1 from the user's inbox. Note the use of /* This will fetch message 1 from the user's inbox. Note the use of
* imaps:// rather than imap:// to request a SSL based connection. */ * imaps:// rather than imap:// to request a SSL based connection. */
curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.example.com/INBOX/;UID=1"); curl_easy_setopt(curl, CURLOPT_URL,
"imaps://imap.example.com/INBOX/;UID=1");
/* If you want to connect to a site who isn't using a certificate that is /* If you want to connect to a site who isn't using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the * signed by one of the certs in the CA bundle you have, you can skip the
@ -60,7 +67,7 @@ int main(void)
* they have mentioned in their server certificate's commonName (or * they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip * subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure. */ * this check, but this will make the connection less secure. */
#ifdef SKIP_HOSTNAME_VERFICATION #ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif #endif

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example showing how to modify the properties of an e-mail
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* IMAP example using TLS
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>
@ -41,7 +47,8 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
/* This will fetch message 1 from the user's inbox */ /* This will fetch message 1 from the user's inbox */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1"); curl_easy_setopt(curl, CURLOPT_URL,
"imap://imap.example.com/INBOX/;UID=1");
/* In this example, we'll start with a plain text connection, and upgrade /* In this example, we'll start with a plain text connection, and upgrade
* to Transport Layer Security (TLS) using the STARTTLS command. Be careful * to Transport Layer Security (TLS) using the STARTTLS command. Be careful
@ -55,12 +62,13 @@ int main(void)
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
*
* That is, in general, a bad idea. It is still better than sending your * That is, in general, a bad idea. It is still better than sending your
* authentication details in plain text though. * authentication details in plain text though. Instead, you should get
* Instead, you should get the issuer certificate (or the host certificate * the issuer certificate (or the host certificate if the certificate is
* if the certificate is self-signed) and add it to the set of certificates * self-signed) and add it to the set of certificates that are known to
* that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See * libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See docs/SSLCERTS
* docs/SSLCERTS for more information. */ * for more information. */
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem"); curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
/* Since the traffic will be encrypted, it is very useful to turn on debug /* Since the traffic will be encrypted, it is very useful to turn on debug

View File

@ -9,7 +9,7 @@
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html. # are also available at https://curl.haxx.se/docs/copyright.html.
# #
# You may opt to use, copy, modify, merge, publish, distribute and/or sell # You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is # copies of the Software, and permit persons to whom the Software is
@ -19,10 +19,6 @@
# KIND, either express or implied. # KIND, either express or implied.
# #
########################################################################### ###########################################################################
#
# Adapted for djgpp / Watt-32 / DOS by
# Gisle Vanem <gvanem@broadpark.no>
#
TOPDIR = ../.. TOPDIR = ../..

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,7 +19,11 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* This is an example application source code using the multi interface. */ /* <DESC>
* A basic application source code using the multi interface doing two
* transfers in parallel.
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -51,8 +55,8 @@ int main(void)
int msgs_left; /* how many messages are left */ int msgs_left; /* how many messages are left */
/* Allocate one CURL handle per transfer */ /* Allocate one CURL handle per transfer */
for (i=0; i<HANDLECOUNT; i++) for(i = 0; i<HANDLECOUNT; i++)
handles[i] = curl_easy_init(); handles[i] = curl_easy_init();
/* set the options (I left out a few, you'll get the point anyway) */ /* set the options (I left out a few, you'll get the point anyway) */
curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "http://example.com"); curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "http://example.com");
@ -64,8 +68,8 @@ int main(void)
multi_handle = curl_multi_init(); multi_handle = curl_multi_init();
/* add the individual transfers */ /* add the individual transfers */
for (i=0; i<HANDLECOUNT; i++) for(i = 0; i<HANDLECOUNT; i++)
curl_multi_add_handle(multi_handle, handles[i]); curl_multi_add_handle(multi_handle, handles[i]);
/* we start some action by calling perform right away */ /* we start some action by calling perform right away */
curl_multi_perform(multi_handle, &still_running); curl_multi_perform(multi_handle, &still_running);
@ -102,8 +106,7 @@ int main(void)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -127,7 +130,7 @@ int main(void)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
switch(rc) { switch(rc) {
@ -142,18 +145,18 @@ int main(void)
} while(still_running); } while(still_running);
/* See how the transfers went */ /* See how the transfers went */
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) { if(msg->msg == CURLMSG_DONE) {
int idx, found = 0; int idx, found = 0;
/* Find out which handle this message is about */ /* Find out which handle this message is about */
for (idx=0; idx<HANDLECOUNT; idx++) { for(idx = 0; idx<HANDLECOUNT; idx++) {
found = (msg->easy_handle == handles[idx]); found = (msg->easy_handle == handles[idx]);
if(found) if(found)
break; break;
} }
switch (idx) { switch(idx) {
case HTTP_HANDLE: case HTTP_HANDLE:
printf("HTTP transfer completed with status %d\n", msg->data.result); printf("HTTP transfer completed with status %d\n", msg->data.result);
break; break;
@ -167,8 +170,8 @@ int main(void)
curl_multi_cleanup(multi_handle); curl_multi_cleanup(multi_handle);
/* Free the CURL handles */ /* Free the CURL handles */
for (i=0; i<HANDLECOUNT; i++) for(i = 0; i<HANDLECOUNT; i++)
curl_easy_cleanup(handles[i]); curl_easy_cleanup(handles[i]);
return 0; return 0;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,7 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* This is an example showing the multi interface and the debug callback. */ /* <DESC>
* multi interface and debug callback
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -42,7 +45,7 @@ void dump(const char *text,
size_t i; size_t i;
size_t c; size_t c;
unsigned int width=0x10; unsigned int width = 0x10;
if(nohex) if(nohex)
/* without the hex output, we can fit more on screen */ /* without the hex output, we can fit more on screen */
@ -51,30 +54,32 @@ void dump(const char *text,
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
text, (long)size, (long)size); text, (long)size, (long)size);
for(i=0; i<size; i+= width) { for(i = 0; i<size; i += width) {
fprintf(stream, "%4.4lx: ", (long)i); fprintf(stream, "%4.4lx: ", (long)i);
if(!nohex) { if(!nohex) {
/* hex not disabled, show it */ /* hex not disabled, show it */
for(c = 0; c < width; c++) for(c = 0; c < width; c++)
if(i+c < size) if(i + c < size)
fprintf(stream, "%02x ", ptr[i+c]); fprintf(stream, "%02x ", ptr[i + c]);
else else
fputs(" ", stream); fputs(" ", stream);
} }
for(c = 0; (c < width) && (i+c < size); c++) { for(c = 0; (c < width) && (i + c < size); c++) {
/* check for 0D0A; if found, skip past and start a new line of output */ /* check for 0D0A; if found, skip past and start a new line of output */
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { if(nohex && (i + c + 1 < size) && ptr[i + c] == 0x0D &&
i+=(c+2-width); ptr[i + c + 1] == 0x0A) {
i += (c + 2 - width);
break; break;
} }
fprintf(stream, "%c", fprintf(stream, "%c",
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); (ptr[i + c] >= 0x20) && (ptr[i + c]<0x80)?ptr[i + c]:'.');
/* check again for 0D0A, to avoid an extra \n if it's at width */ /* check again for 0D0A, to avoid an extra \n if it's at width */
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D &&
i+=(c+3-width); ptr[i + c + 2] == 0x0A) {
i += (c + 3 - width);
break; break;
} }
} }
@ -93,9 +98,10 @@ int my_trace(CURL *handle, curl_infotype type,
(void)userp; (void)userp;
(void)handle; /* prevent compiler warning */ (void)handle; /* prevent compiler warning */
switch (type) { switch(type) {
case CURLINFO_TEXT: case CURLINFO_TEXT:
fprintf(stderr, "== Info: %s", data); fprintf(stderr, "== Info: %s", data);
/* FALLTHROUGH */
default: /* in case a new one is introduced to shock us */ default: /* in case a new one is introduced to shock us */
return 0; return 0;
@ -176,8 +182,7 @@ int main(void)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -201,7 +206,7 @@ int main(void)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
switch(rc) { switch(rc) {

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* multi interface code doing two parallel HTTP transfers
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -91,8 +95,7 @@ int main(void)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -116,7 +119,7 @@ int main(void)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
switch(rc) { switch(rc) {

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,8 +19,11 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* This is an example application source code using the multi interface /* <DESC>
* to do a multipart formpost without "blocking". */ * using the multi interface to do a multipart formpost without blocking
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/time.h> #include <sys/time.h>
@ -34,47 +37,43 @@ int main(void)
CURLM *multi_handle; CURLM *multi_handle;
int still_running; int still_running;
struct curl_httppost *formpost=NULL; curl_mime *form = NULL;
struct curl_httppost *lastptr=NULL; curl_mimepart *field = NULL;
struct curl_slist *headerlist=NULL; struct curl_slist *headerlist = NULL;
static const char buf[] = "Expect:"; static const char buf[] = "Expect:";
/* Fill in the file upload field. This makes libcurl load data from
the given file name when curl_easy_perform() is called. */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, "postit2.c",
CURLFORM_END);
/* Fill in the filename field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, "postit2.c",
CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
curl = curl_easy_init(); curl = curl_easy_init();
multi_handle = curl_multi_init(); multi_handle = curl_multi_init();
/* initalize custom header list (stating that Expect: 100-continue is not
wanted */
headerlist = curl_slist_append(headerlist, buf);
if(curl && multi_handle) { if(curl && multi_handle) {
/* Create the form */
form = curl_mime_init(curl);
/* Fill in the file upload field */
field = curl_mime_addpart(form);
curl_mime_name(field, "sendfile");
curl_mime_filedata(field, "multi-post.c");
/* Fill in the filename field */
field = curl_mime_addpart(form);
curl_mime_name(field, "filename");
curl_mime_data(field, "multi-post.c", CURL_ZERO_TERMINATED);
/* Fill in the submit field too, even if this is rarely needed */
field = curl_mime_addpart(form);
curl_mime_name(field, "submit");
curl_mime_data(field, "send", CURL_ZERO_TERMINATED);
/* initialize custom header list (stating that Expect: 100-continue is not
wanted */
headerlist = curl_slist_append(headerlist, buf);
/* what URL that receives this POST */ /* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi"); curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
curl_multi_add_handle(multi_handle, curl); curl_multi_add_handle(multi_handle, curl);
@ -112,8 +111,7 @@ int main(void)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
@ -137,7 +135,7 @@ int main(void)
else { else {
/* Note that on some platforms 'timeout' may be modified by select(). /* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */ If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
} }
switch(rc) { switch(rc) {
@ -159,11 +157,11 @@ int main(void)
/* always cleanup */ /* always cleanup */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
/* then cleanup the formpost chain */ /* then cleanup the form */
curl_formfree(formpost); curl_mime_free(form);
/* free slist */ /* free slist */
curl_slist_free_all (headerlist); curl_slist_free_all(headerlist);
} }
return 0; return 0;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,7 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* This is a very simple example using the multi interface. */ /* <DESC>
* using the multi interface to do a single download
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -74,14 +77,13 @@ int main(void)
/* wait for activity, timeout or "nothing" */ /* wait for activity, timeout or "nothing" */
mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
if(mc != CURLM_OK) if(mc != CURLM_OK) {
{ fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc);
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break; break;
} }
/* 'numfds' being zero means either a timeout or no file descriptors to /* 'numfds' being zero means either a timeout or no file descriptors to
wait for. Try timeout on first occurance, then assume no file wait for. Try timeout on first occurrence, then assume no file
descriptors and no file descriptors to wait for means wait for 100 descriptors and no file descriptors to wait for means wait for 100
milliseconds. */ milliseconds. */

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -20,18 +20,16 @@
* *
***************************************************************************/ ***************************************************************************/
/* Example application code using the multi socket interface to download /* <DESC>
multiple files at once, but instead of using curl_multi_perform and * multi_socket API using libuv
curl_multi_wait, which uses select(), we use libuv. * </DESC>
It supports epoll, kqueue, etc. on unixes and fast IO completion ports on */
Windows, which means, it should be very fast on all platforms.. /* Example application using the multi socket interface to download multiple
files in parallel, powered by libuv.
Written by Clemens Gruber, based on an outdated example from uvbook and
some tests from libuv.
Requires libuv and (of course) libcurl. Requires libuv and (of course) libcurl.
See http://nikhilm.github.com/uvbook/ for more information on libuv. See https://nikhilm.github.com/uvbook/ for more information on libuv.
*/ */
#include <stdio.h> #include <stdio.h>
@ -48,7 +46,7 @@ typedef struct curl_context_s {
curl_socket_t sockfd; curl_socket_t sockfd;
} curl_context_t; } curl_context_t;
curl_context_t* create_curl_context(curl_socket_t sockfd) static curl_context_t* create_curl_context(curl_socket_t sockfd)
{ {
curl_context_t *context; curl_context_t *context;
@ -62,27 +60,26 @@ curl_context_t* create_curl_context(curl_socket_t sockfd)
return context; return context;
} }
void curl_close_cb(uv_handle_t *handle) static void curl_close_cb(uv_handle_t *handle)
{ {
curl_context_t *context = (curl_context_t *) handle->data; curl_context_t *context = (curl_context_t *) handle->data;
free(context); free(context);
} }
void destroy_curl_context(curl_context_t *context) static void destroy_curl_context(curl_context_t *context)
{ {
uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb); uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb);
} }
static void add_download(const char *url, int num)
void add_download(const char *url, int num)
{ {
char filename[50]; char filename[50];
FILE *file; FILE *file;
CURL *handle; CURL *handle;
sprintf(filename, "%d.download", num); snprintf(filename, 50, "%d.download", num);
file = fopen(filename, "w"); file = fopen(filename, "wb");
if(!file) { if(!file) {
fprintf(stderr, "Error opening %s\n", filename); fprintf(stderr, "Error opening %s\n", filename);
return; return;
@ -98,22 +95,28 @@ void add_download(const char *url, int num)
static void check_multi_info(void) static void check_multi_info(void)
{ {
int running_handles;
char *done_url; char *done_url;
CURLMsg *message; CURLMsg *message;
int pending; int pending;
CURL *easy_handle;
FILE *file; FILE *file;
while((message = curl_multi_info_read(curl_handle, &pending))) { while((message = curl_multi_info_read(curl_handle, &pending))) {
switch(message->msg) { switch(message->msg) {
case CURLMSG_DONE: case CURLMSG_DONE:
curl_easy_getinfo(message->easy_handle, CURLINFO_EFFECTIVE_URL, /* Do not use message data after calling curl_multi_remove_handle() and
&done_url); curl_easy_cleanup(). As per curl_multi_info_read() docs:
curl_easy_getinfo(message->easy_handle, CURLINFO_PRIVATE, &file); "WARNING: The data the returned pointer points to will not survive
calling curl_multi_cleanup, curl_multi_remove_handle or
curl_easy_cleanup." */
easy_handle = message->easy_handle;
curl_easy_getinfo(easy_handle, CURLINFO_EFFECTIVE_URL, &done_url);
curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &file);
printf("%s DONE\n", done_url); printf("%s DONE\n", done_url);
curl_multi_remove_handle(curl_handle, message->easy_handle); curl_multi_remove_handle(curl_handle, easy_handle);
curl_easy_cleanup(message->easy_handle); curl_easy_cleanup(easy_handle);
if(file) { if(file) {
fclose(file); fclose(file);
} }
@ -126,23 +129,18 @@ static void check_multi_info(void)
} }
} }
void curl_perform(uv_poll_t *req, int status, int events) static void curl_perform(uv_poll_t *req, int status, int events)
{ {
int running_handles; int running_handles;
int flags = 0; int flags = 0;
curl_context_t *context; curl_context_t *context;
char *done_url;
CURLMsg *message;
int pending;
uv_timer_stop(&timeout);
if(events & UV_READABLE) if(events & UV_READABLE)
flags |= CURL_CSELECT_IN; flags |= CURL_CSELECT_IN;
if(events & UV_WRITABLE) if(events & UV_WRITABLE)
flags |= CURL_CSELECT_OUT; flags |= CURL_CSELECT_OUT;
context = (curl_context_t *) req; context = (curl_context_t *) req->data;
curl_multi_socket_action(curl_handle, context->sockfd, flags, curl_multi_socket_action(curl_handle, context->sockfd, flags,
&running_handles); &running_handles);
@ -150,7 +148,7 @@ void curl_perform(uv_poll_t *req, int status, int events)
check_multi_info(); check_multi_info();
} }
void on_timeout(uv_timer_t *req, int status) static void on_timeout(uv_timer_t *req)
{ {
int running_handles; int running_handles;
curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0, curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0,
@ -158,34 +156,41 @@ void on_timeout(uv_timer_t *req, int status)
check_multi_info(); check_multi_info();
} }
void start_timeout(CURLM *multi, long timeout_ms, void *userp) static int start_timeout(CURLM *multi, long timeout_ms, void *userp)
{ {
if(timeout_ms <= 0) if(timeout_ms < 0) {
timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it in uv_timer_stop(&timeout);
a bit */ }
uv_timer_start(&timeout, on_timeout, timeout_ms, 0); else {
if(timeout_ms == 0)
timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it
in a bit */
uv_timer_start(&timeout, on_timeout, timeout_ms, 0);
}
return 0;
} }
int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp,
void *socketp) void *socketp)
{ {
curl_context_t *curl_context; curl_context_t *curl_context;
if(action == CURL_POLL_IN || action == CURL_POLL_OUT) { int events = 0;
if(socketp) {
curl_context = (curl_context_t *) socketp;
}
else {
curl_context = create_curl_context(s);
}
curl_multi_assign(curl_handle, s, (void *) curl_context);
}
switch(action) { switch(action) {
case CURL_POLL_IN: case CURL_POLL_IN:
uv_poll_start(&curl_context->poll_handle, UV_READABLE, curl_perform);
break;
case CURL_POLL_OUT: case CURL_POLL_OUT:
uv_poll_start(&curl_context->poll_handle, UV_WRITABLE, curl_perform); case CURL_POLL_INOUT:
curl_context = socketp ?
(curl_context_t *) socketp : create_curl_context(s);
curl_multi_assign(curl_handle, s, (void *) curl_context);
if(action != CURL_POLL_IN)
events |= UV_WRITABLE;
if(action != CURL_POLL_OUT)
events |= UV_READABLE;
uv_poll_start(&curl_context->poll_handle, events, curl_perform);
break; break;
case CURL_POLL_REMOVE: case CURL_POLL_REMOVE:
if(socketp) { if(socketp) {
@ -209,7 +214,7 @@ int main(int argc, char **argv)
return 0; return 0;
if(curl_global_init(CURL_GLOBAL_ALL)) { if(curl_global_init(CURL_GLOBAL_ALL)) {
fprintf(stderr, "Could not init cURL\n"); fprintf(stderr, "Could not init curl\n");
return 1; return 1;
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,8 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* A multi-threaded example that uses pthreads extensively to fetch /* <DESC>
* X remote files at once */ * A multi-threaded example that uses pthreads to fetch several files at once
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <pthread.h> #include <pthread.h>
@ -31,14 +33,14 @@
/* /*
List of URLs to fetch. List of URLs to fetch.
If you intend to use a SSL-based protocol here you MUST setup the OpenSSL If you intend to use a SSL-based protocol here you might need to setup TLS
callback functions as described here: library mutex callbacks as described here:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION https://curl.haxx.se/libcurl/c/threadsafe.html
*/ */
const char * const urls[NUMT]= { const char * const urls[NUMT]= {
"http://curl.haxx.se/", "https://curl.haxx.se/",
"ftp://cool.haxx.se/", "ftp://cool.haxx.se/",
"http://www.contactor.se/", "http://www.contactor.se/",
"www.haxx.se" "www.haxx.se"
@ -72,7 +74,7 @@ int main(int argc, char **argv)
/* Must initialize libcurl before any threads are started */ /* Must initialize libcurl before any threads are started */
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
for(i=0; i< NUMT; i++) { for(i = 0; i< NUMT; i++) {
error = pthread_create(&tid[i], error = pthread_create(&tid[i],
NULL, /* default attributes please */ NULL, /* default attributes please */
pull_one_url, pull_one_url,
@ -84,7 +86,7 @@ int main(int argc, char **argv)
} }
/* now wait for all threads to terminate */ /* now wait for all threads to terminate */
for(i=0; i< NUMT; i++) { for(i = 0; i< NUMT; i++) {
error = pthread_join(tid[i], NULL); error = pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i); fprintf(stderr, "Thread %d terminated\n", i);
} }

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,16 +19,17 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* Example source code to show one way to set the necessary OpenSSL locking /* <DESC>
* callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with * one way to set the necessary OpenSSL locking callbacks if you want to do
* libcurl built to use OpenSSL. * multi-threaded transfers with HTTPS/FTPS with libcurl built to use OpenSSL.
* * </DESC>
*/
/*
* This is not a complete stand-alone example. * This is not a complete stand-alone example.
* *
* Author: Jeremy Brown * Author: Jeremy Brown
*/ */
#include <stdio.h> #include <stdio.h>
#include <pthread.h> #include <pthread.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -38,22 +39,22 @@
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
#define THREAD_ID pthread_self( ) #define THREAD_ID pthread_self()
void handle_error(const char *file, int lineno, const char *msg){ void handle_error(const char *file, int lineno, const char *msg)
fprintf(stderr, "** %s:%d %s\n", file, lineno, msg); {
ERR_print_errors_fp(stderr); fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
/* exit(-1); */ ERR_print_errors_fp(stderr);
} /* exit(-1); */
}
/* This array will store all of the mutexes available to OpenSSL. */ /* This array will store all of the mutexes available to OpenSSL. */
static MUTEX_TYPE *mutex_buf= NULL; static MUTEX_TYPE *mutex_buf = NULL;
static void locking_function(int mode, int n, const char *file, int line)
static void locking_function(int mode, int n, const char * file, int line)
{ {
if (mode & CRYPTO_LOCK) if(mode & CRYPTO_LOCK)
MUTEX_LOCK(mutex_buf[n]); MUTEX_LOCK(mutex_buf[n]);
else else
MUTEX_UNLOCK(mutex_buf[n]); MUTEX_UNLOCK(mutex_buf[n]);
@ -68,10 +69,10 @@ int thread_setup(void)
{ {
int i; int i;
mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE)); mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
if (!mutex_buf) if(!mutex_buf)
return 0; return 0;
for (i = 0; i < CRYPTO_num_locks( ); i++) for(i = 0; i < CRYPTO_num_locks(); i++)
MUTEX_SETUP(mutex_buf[i]); MUTEX_SETUP(mutex_buf[i]);
CRYPTO_set_id_callback(id_function); CRYPTO_set_id_callback(id_function);
CRYPTO_set_locking_callback(locking_function); CRYPTO_set_locking_callback(locking_function);
@ -82,11 +83,11 @@ int thread_cleanup(void)
{ {
int i; int i;
if (!mutex_buf) if(!mutex_buf)
return 0; return 0;
CRYPTO_set_id_callback(NULL); CRYPTO_set_id_callback(NULL);
CRYPTO_set_locking_callback(NULL); CRYPTO_set_locking_callback(NULL);
for (i = 0; i < CRYPTO_num_locks( ); i++) for(i = 0; i < CRYPTO_num_locks(); i++)
MUTEX_CLEANUP(mutex_buf[i]); MUTEX_CLEANUP(mutex_buf[i]);
free(mutex_buf); free(mutex_buf);
mutex_buf = NULL; mutex_buf = NULL;

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,10 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* re-using handles to do HTTP persistent connections
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <curl/curl.h> #include <curl/curl.h>

View File

@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at https://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
@ -19,6 +19,12 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
/* <DESC>
* POP3 example showing how to delete e-mails
* </DESC>
*/
#include <stdio.h> #include <stdio.h>
#include <curl/curl.h> #include <curl/curl.h>

Some files were not shown because too many files have changed in this diff Show More