Compare commits
139 Commits
http2-push
...
curl-7_44_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a7f66a3de | ||
|
|
c75a1e7750 | ||
|
|
daf7f98c11 | ||
|
|
bb0acba67d | ||
|
|
5778e6f526 | ||
|
|
c8a656d3c7 | ||
|
|
9ee40ce2ab | ||
|
|
0b8e9c8522 | ||
|
|
9a5574ca7b | ||
|
|
ade6682f8d | ||
|
|
002d58f1e8 | ||
|
|
cde447217f | ||
|
|
9d29afdfe3 | ||
|
|
0cc0b7e268 | ||
|
|
aa9ead36a4 | ||
|
|
ecece2cfb5 | ||
|
|
4d13b78aec | ||
|
|
39dcf352d2 | ||
|
|
55a255ee9c | ||
|
|
4c47cbf533 | ||
|
|
c22fae7ccc | ||
|
|
d712da787e | ||
|
|
2b743dcf8e | ||
|
|
333c36b276 | ||
|
|
1ab763acce | ||
|
|
a8e9e0c205 | ||
|
|
4a21346ef3 | ||
|
|
4aee1f9cf5 | ||
|
|
b9b7ccd04a | ||
|
|
84d122a8d6 | ||
|
|
5b9151231d | ||
|
|
cf8975387f | ||
|
|
0342ada31f | ||
|
|
3f5f042e5d | ||
|
|
bb6b521f69 | ||
|
|
8279dd7d39 | ||
|
|
fe6049f04b | ||
|
|
7f11259eb7 | ||
|
|
473807b95f | ||
|
|
f08e30d7bc | ||
|
|
6428b8de42 | ||
|
|
97c9d31884 | ||
|
|
9947f259bf | ||
|
|
33de75ed63 | ||
|
|
df5965ebf4 | ||
|
|
6e566451ce | ||
|
|
07f7cdc309 | ||
|
|
3725748599 | ||
|
|
1e67bc5eaf | ||
|
|
12f915ca2a | ||
|
|
4b96240d3f | ||
|
|
1b3d3f9237 | ||
|
|
c4eb10e2f0 | ||
|
|
3b4ee0d432 | ||
|
|
c092b0f0f3 | ||
|
|
f75b6065db | ||
|
|
11ab3f8918 | ||
|
|
a1b2a6bd93 | ||
|
|
c8331f515e | ||
|
|
23b84e448f | ||
|
|
0da1f5dc5c | ||
|
|
909f0a82b0 | ||
|
|
8b1d00ac1a | ||
|
|
f7dcc7c118 | ||
|
|
ecf7618e12 | ||
|
|
5b9a006b8f | ||
|
|
fc69e2f7ec | ||
|
|
bdd8cf4777 | ||
|
|
dda81c1d5f | ||
|
|
2d7e165761 | ||
|
|
8356022d17 | ||
|
|
467309406e | ||
|
|
b656715da3 | ||
|
|
9b95306d4c | ||
|
|
98e8b050ef | ||
|
|
d9efd36907 | ||
|
|
1627930177 | ||
|
|
299b74fcfc | ||
|
|
279965c923 | ||
|
|
7db03e5c21 | ||
|
|
a728225a92 | ||
|
|
29e5cf2a2d | ||
|
|
0f645adc95 | ||
|
|
373b77bca2 | ||
|
|
6d62d2c55d | ||
|
|
14b9e780d4 | ||
|
|
8204844f47 | ||
|
|
b46a7744bc | ||
|
|
a284b0ebc4 | ||
|
|
c5d060cab4 | ||
|
|
98835eed29 | ||
|
|
cee21eb6a7 | ||
|
|
da650c1e54 | ||
|
|
40c921f8b8 | ||
|
|
7a8e861a56 | ||
|
|
ad32457623 | ||
|
|
32d4260c2d | ||
|
|
1df8d28381 | ||
|
|
fa0eeedf35 | ||
|
|
68d17643f5 | ||
|
|
aab76af1fa | ||
|
|
172b2beba6 | ||
|
|
606b29fe0d | ||
|
|
60b19630b0 | ||
|
|
de74e856e6 | ||
|
|
cd20e81e89 | ||
|
|
79416fb2d6 | ||
|
|
8f0178a56b | ||
|
|
845b011614 | ||
|
|
ce1bf87a04 | ||
|
|
5602ad721b | ||
|
|
55b78c5ae9 | ||
|
|
c00b18d540 | ||
|
|
4ed8537be6 | ||
|
|
66a5f76583 | ||
|
|
616cecfdb6 | ||
|
|
b59f296bf6 | ||
|
|
e6749055d6 | ||
|
|
8208dd3b22 | ||
|
|
0c46abd79a | ||
|
|
1f70cdef98 | ||
|
|
e3e06e1aee | ||
|
|
37402b5eb8 | ||
|
|
69c77f69a5 | ||
|
|
dc2cbfda89 | ||
|
|
1b5eba8324 | ||
|
|
ddb106d7f6 | ||
|
|
77044b53f7 | ||
|
|
c712aa0ebe | ||
|
|
a384f28ca6 | ||
|
|
bf445b6e12 | ||
|
|
a3a55d80ec | ||
|
|
e9f0dd43bc | ||
|
|
f65ab8864e | ||
|
|
feea9263e9 | ||
|
|
ea7134ac87 | ||
|
|
70191958b5 | ||
|
|
5156982377 | ||
|
|
903b6e0556 |
14
CHANGES
14
CHANGES
@@ -1,15 +1,7 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
See http://curl.haxx.se/changes.html for the edited and human readable online
|
||||
version of what has changed over the years in different curl releases.
|
||||
|
||||
Changelog
|
||||
|
||||
This file no longer holds the changelog. Now you can generate it yourself
|
||||
like this:
|
||||
Generate a CHANGES file like the one present in evey release like this:
|
||||
|
||||
$ git log --pretty=fuller --no-color --date=short --decorate=full | \
|
||||
./log2changes.pl
|
||||
|
||||
The older, manually edited, changelog is found in git named CHANGES.0
|
||||
|
||||
@@ -491,7 +491,7 @@ mark_as_advanced(CMAKE_USE_GSSAPI)
|
||||
if(CMAKE_USE_GSSAPI)
|
||||
find_package(GSS)
|
||||
|
||||
set(HAVE_GSS_API ${GSS_FOUND})
|
||||
set(HAVE_GSSAPI ${GSS_FOUND})
|
||||
if(GSS_FOUND)
|
||||
|
||||
message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
|
||||
@@ -1046,12 +1046,12 @@ _add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX)
|
||||
_add_if("IDN" HAVE_LIBIDN)
|
||||
# TODO SSP1 (WinSSL) check is missing
|
||||
_add_if("SSPI" USE_WINDOWS_SSPI)
|
||||
_add_if("GSS-API" HAVE_GSS_API)
|
||||
_add_if("GSS-API" HAVE_GSSAPI)
|
||||
# TODO SSP1 missing for SPNEGO
|
||||
_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSS_API OR USE_WINDOWS_SSPI))
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
_add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSS_API OR USE_WINDOWS_SSPI))
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
# NTLM support requires crypto function adaptions from various SSL libs
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
|
||||
if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
|
||||
|
||||
84
Makefile.am
84
Makefile.am
@@ -32,86 +32,97 @@ CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
|
||||
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
|
||||
VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist
|
||||
VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC6_SRCTMPL = projects/Windows/VC6/src/curlsrc.tmpl
|
||||
VC6_SRCDSP = projects/Windows/VC6/src/curlsrc.dsp.dist
|
||||
VC6_SRCTMPL = projects/Windows/VC6/src/curl.tmpl
|
||||
VC6_SRCDSP = projects/Windows/VC6/src/curl.dsp.dist
|
||||
VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl
|
||||
VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist
|
||||
VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC7_SRCTMPL = projects/Windows/VC7/src/curlsrc.tmpl
|
||||
VC7_SRCVCPROJ = projects/Windows/VC7/src/curlsrc.vcproj.dist
|
||||
VC7_SRCTMPL = projects/Windows/VC7/src/curl.tmpl
|
||||
VC7_SRCVCPROJ = projects/Windows/VC7/src/curl.vcproj.dist
|
||||
VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl
|
||||
VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist
|
||||
VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC71_SRCTMPL = projects/Windows/VC7.1/src/curlsrc.tmpl
|
||||
VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curlsrc.vcproj.dist
|
||||
VC71_SRCTMPL = projects/Windows/VC7.1/src/curl.tmpl
|
||||
VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curl.vcproj.dist
|
||||
VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl
|
||||
VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist
|
||||
VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC8_SRCTMPL = projects/Windows/VC8/src/curlsrc.tmpl
|
||||
VC8_SRCVCPROJ = projects/Windows/VC8/src/curlsrc.vcproj.dist
|
||||
VC8_SRCTMPL = projects/Windows/VC8/src/curl.tmpl
|
||||
VC8_SRCVCPROJ = projects/Windows/VC8/src/curl.vcproj.dist
|
||||
VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl
|
||||
VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist
|
||||
VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC9_SRCTMPL = projects/Windows/VC9/src/curlsrc.tmpl
|
||||
VC9_SRCVCPROJ = projects/Windows/VC9/src/curlsrc.vcproj.dist
|
||||
VC9_SRCTMPL = projects/Windows/VC9/src/curl.tmpl
|
||||
VC9_SRCVCPROJ = projects/Windows/VC9/src/curl.vcproj.dist
|
||||
VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl
|
||||
VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist
|
||||
VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC10_SRCTMPL = projects/Windows/VC10/src/curlsrc.tmpl
|
||||
VC10_SRCVCXPROJ = projects/Windows/VC10/src/curlsrc.vcxproj.dist
|
||||
VC10_SRCTMPL = projects/Windows/VC10/src/curl.tmpl
|
||||
VC10_SRCVCXPROJ = projects/Windows/VC10/src/curl.vcxproj.dist
|
||||
VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl
|
||||
VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist
|
||||
VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC11_SRCTMPL = projects/Windows/VC11/src/curlsrc.tmpl
|
||||
VC11_SRCVCXPROJ = projects/Windows/VC11/src/curlsrc.vcxproj.dist
|
||||
VC11_SRCTMPL = projects/Windows/VC11/src/curl.tmpl
|
||||
VC11_SRCVCXPROJ = projects/Windows/VC11/src/curl.vcxproj.dist
|
||||
VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl
|
||||
VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist
|
||||
VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC12_SRCTMPL = projects/Windows/VC12/src/curlsrc.tmpl
|
||||
VC12_SRCVCXPROJ = projects/Windows/VC12/src/curlsrc.vcxproj.dist
|
||||
VC12_SRCTMPL = projects/Windows/VC12/src/curl.tmpl
|
||||
VC12_SRCVCXPROJ = projects/Windows/VC12/src/curl.vcxproj.dist
|
||||
VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC14_LIBTMPL = projects/Windows/VC14/lib/libcurl.tmpl
|
||||
VC14_LIBVCXPROJ = projects/Windows/VC14/lib/libcurl.vcxproj.dist
|
||||
VC14_LIBVCXPROJ_DEPS = $(VC14_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC14_SRCTMPL = projects/Windows/VC14/src/curl.tmpl
|
||||
VC14_SRCVCXPROJ = projects/Windows/VC14/src/curl.vcxproj.dist
|
||||
VC14_SRCVCXPROJ_DEPS = $(VC14_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC_DIST = projects/README \
|
||||
projects/build-openssl.bat \
|
||||
projects/build-wolfssl.bat \
|
||||
projects/checksrc.bat \
|
||||
projects/Windows/VC6/curl-all.dsw \
|
||||
projects/Windows/VC6/lib/libcurl.dsw \
|
||||
projects/Windows/VC6/src/curlsrc.dsw \
|
||||
projects/Windows/VC6/src/curl.dsw \
|
||||
projects/Windows/VC7/curl-all.sln \
|
||||
projects/Windows/VC7/lib/libcurl.sln \
|
||||
projects/Windows/VC7/src/curlsrc.sln \
|
||||
projects/Windows/VC7/src/curl.sln \
|
||||
projects/Windows/VC7.1/curl-all.sln \
|
||||
projects/Windows/VC7.1/lib/libcurl.sln \
|
||||
projects/Windows/VC7.1/src/curlsrc.sln \
|
||||
projects/Windows/VC7.1/src/curl.sln \
|
||||
projects/Windows/VC8/curl-all.sln \
|
||||
projects/Windows/VC8/lib/libcurl.sln \
|
||||
projects/Windows/VC8/src/curlsrc.sln \
|
||||
projects/Windows/VC8/src/curl.sln \
|
||||
projects/Windows/VC9/curl-all.sln \
|
||||
projects/Windows/VC9/lib/libcurl.sln \
|
||||
projects/Windows/VC9/src/curlsrc.sln \
|
||||
projects/Windows/VC9/src/curl.sln \
|
||||
projects/Windows/VC10/curl-all.sln \
|
||||
projects/Windows/VC10/lib/libcurl.sln \
|
||||
projects/Windows/VC10/src/curlsrc.sln \
|
||||
projects/Windows/VC10/src/curl.sln \
|
||||
projects/Windows/VC11/curl-all.sln \
|
||||
projects/Windows/VC11/lib/libcurl.sln \
|
||||
projects/Windows/VC11/src/curlsrc.sln \
|
||||
projects/Windows/VC11/src/curl.sln \
|
||||
projects/Windows/VC12/curl-all.sln \
|
||||
projects/Windows/VC12/lib/libcurl.sln \
|
||||
projects/Windows/VC12/src/curlsrc.sln
|
||||
projects/Windows/VC12/src/curl.sln \
|
||||
projects/Windows/VC14/curl-all.sln \
|
||||
projects/Windows/VC14/lib/libcurl.sln \
|
||||
projects/Windows/VC14/src/curl.sln
|
||||
|
||||
WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
|
||||
winbuild/MakefileBuild.vc winbuild/Makefile.vc \
|
||||
@@ -124,7 +135,8 @@ EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
|
||||
CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
|
||||
$(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \
|
||||
$(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
|
||||
|
||||
@@ -269,7 +281,7 @@ vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
|
||||
$(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \
|
||||
$(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_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_hdrs='$(LIB_HFILES) config-win32.h'; \
|
||||
win32_lib_rc='$(LIB_RCFILES)'; \
|
||||
@@ -530,4 +542,22 @@ function gen_element(type, dir, file)\
|
||||
-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)/$(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_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; };)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# 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
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -566,6 +566,17 @@ src/Makefile.vc12: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc12/g" -e "s/VC6/VC12/g" src/Makefile.vc6 > src/Makefile.vc12
|
||||
|
||||
# VC14 makefiles are for use with VS2015
|
||||
vc14: lib/Makefile.vc14 src/Makefile.vc14
|
||||
|
||||
lib/Makefile.vc14: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc14/g" -e "s/VC6/VC14/g" lib/Makefile.vc6 > lib/Makefile.vc14
|
||||
|
||||
src/Makefile.vc14: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc14/g" -e "s/VC6/VC14/g" src/Makefile.vc6 > src/Makefile.vc14
|
||||
|
||||
ca-bundle: lib/mk-ca-bundle.pl
|
||||
@echo "generate a fresh ca-bundle.crt"
|
||||
@perl $< -b -l -u lib/ca-bundle.crt
|
||||
|
||||
103
RELEASE-NOTES
103
RELEASE-NOTES
@@ -8,12 +8,74 @@ Curl and libcurl 7.44.0
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o
|
||||
|
||||
o http2: added CURLMOPT_PUSHFUNCTION and CURLMOPT_PUSHDATA [6]
|
||||
o examples: added http2-serverpush.c [7]
|
||||
o http2: added curl_pushheader_byname() and curl_pushheader_bynum()
|
||||
o docs: added CODE_OF_CONDUCT.md [8]
|
||||
o curl: Add --ssl-no-revoke to disable certificate revocation checks [5]
|
||||
o libcurl: New value CURLSSLOPT_NO_REVOKE for CURLOPT_SSL_OPTIONS [9]
|
||||
o makefile: Added support for VC14
|
||||
o build: Added Visual Studio 2015 (VC14) project files
|
||||
o build: Added wolfSSL configurations to VC10+ project files [18]
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o
|
||||
o FTP: fix HTTP CONNECT logic regression [1]
|
||||
o openssl: Fix build with openssl < ~ 0.9.8f
|
||||
o openssl: fix build with BoringSSL
|
||||
o curl_easy_setopt.3: option order doesn't matter
|
||||
o openssl: fix use of uninitialized buffer [2]
|
||||
o RTSP: removed dead code
|
||||
o Makefile.m32: add support for CURL_LDFLAG_EXTRAS
|
||||
o curl: always provide negotiate/kerberos options
|
||||
o cookie: Fix bug in export if any-domain cookie is present
|
||||
o curl_easy_setopt.3: mention CURLOPT_PIPEWAIT
|
||||
o INSTALL: Advise use of non-native SSL for Windows <= XP
|
||||
o tool_help: fix --tlsv1 help text to use >= for TLSv1
|
||||
o HTTP: POSTFIELDSIZE set after added to multi handle [3]
|
||||
o SSL-PROBLEMS: mention WinSSL problems in WinXP
|
||||
o setup-vms.h: Symbol case fixups
|
||||
o SSL: Pinned public key hash support
|
||||
o libtest: call PR_Cleanup() on exit if NSPR is used
|
||||
o ntlm_wb: Fix theoretical memory leak
|
||||
o runtests: Allow for spaces in curl custom path
|
||||
o http2: add stream != NULL checks for reliability
|
||||
o schannel: Replace deprecated GetVersion with VerifyVersionInfo
|
||||
o http2: verify success of strchr() in http2_send()
|
||||
o configure: add --disable-rt option
|
||||
o openssl: work around MSVC warning
|
||||
o HTTP: ignore "Content-Encoding: compress"
|
||||
o configure: check if OpenSSL linking wants -ldl
|
||||
o build-openssl.bat: Show syntax if required args are missing
|
||||
o test1902: attempt to make the test more reliable
|
||||
o libcurl-thread.3: Consolidate thread safety info
|
||||
o maketgz: Fixed some VC makefiles missing from the release tarball
|
||||
o libcurl-multi.3: mention curl_multi_wait [10]
|
||||
o ABI doc: use secure URL
|
||||
o http: move HTTP/2 cleanup code off http_disconnect() [11]
|
||||
o libcurl-thread.3: Warn memory functions must be thread safe [12]
|
||||
o curl_global_init_mem.3: Warn threaded resolver needs thread safe funcs [13]
|
||||
o docs: formpost needs the full size at start of upload [14]
|
||||
o curl_gssapi: remove 'const' to fix compiler warnings
|
||||
o SSH: three state machine fixups [15]
|
||||
o libcurl.3: fix a single typo [16]
|
||||
o generate.bat: Only clean prerequisite files when in ALL mode
|
||||
o curl_slist_append.3: add error checking to the example
|
||||
o buildconf.bat: Added support for file clean-up via -clean
|
||||
o generate.bat: Use buildconf.bat for prerequisite file clean-up
|
||||
o NTLM: handle auth for only a single request [17]
|
||||
o curl_multi_remove_handle.3: fix formatting [19]
|
||||
o checksrc.bat: Fixed error when [directory] isn't a curl source directory
|
||||
o checksrc.bat: Fixed error when missing *.c and *.h files
|
||||
o CURLOPT_RESOLVE.3: Note removal support was added in 7.42 [20]
|
||||
o test46: update cookie expire time
|
||||
o SFTP: fix range request off-by-one in size check [21]
|
||||
o CMake: fix GSSAPI builds [22]
|
||||
o build: refer to fixed libidn versions [4]
|
||||
o http2: discard frames with no SessionHandle [23]
|
||||
o curl_easy_recv.3: fix formatting
|
||||
o libcurl-tutorial.3: fix formatting [24]
|
||||
o curl_formget.3: correct return code [25]
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -22,10 +84,41 @@ This release includes the following known bugs:
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
|
||||
Anders Bakken, Cédric Connes, Dan Fandrich, Daniel Stenberg, David Woodhouse,
|
||||
Eric Ridge, Feist Josselin, Gustavo Grieco, Inca R, Isaac Boukris,
|
||||
Jakub Zakrzewski, John E. Malmberg, Kamil Dudka, Lior Kaplan, Marcel Raad,
|
||||
Michael Kaufmann, Michał Fita, Patrick Monnerat, Paul Howarth, Ray Satiro,
|
||||
Roger Leigh, Stefan Bühler, Štefan Kremeň, Steve Holme, Svyatoslav Mishyn,
|
||||
Tatsuhiro Tsujikawa, Terri Oda, Tim Stack, TJ Saunders, Tomas Tomecek,
|
||||
Viktor Szakáts,
|
||||
(31 contributors)
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
References to bug reports and discussions on issues:
|
||||
|
||||
[1] =
|
||||
[1] = https://github.com/bagder/curl/issues/278
|
||||
[2] = https://github.com/bagder/curl/issues/318
|
||||
[3] = http://curl.haxx.se/mail/lib-2015-06/0122.html
|
||||
[4] = http://curl.haxx.se/bug/?i=371
|
||||
[5] = https://github.com/bagder/curl/issues/264
|
||||
[6] = http://curl.haxx.se/libcurl/c/CURLMOPT_PUSHFUNCTION.html
|
||||
[7] = http://curl.haxx.se/libcurl/c/http2-serverpush.html
|
||||
[8] = https://github.com/bagder/curl/blob/master/docs/CODE_OF_CONDUCT.md
|
||||
[9] = http://curl.haxx.se/libcurl/c/CURLOPT_SSL_OPTIONS.html
|
||||
[10] = https://github.com/bagder/curl/issues/356
|
||||
[11] = https://bugzilla.redhat.com/1248389
|
||||
[12] = http://curl.haxx.se/mail/lib-2015-07/0149.html
|
||||
[13] = http://curl.haxx.se/mail/lib-2015-07/0149.html
|
||||
[14] = http://curl.haxx.se/bug/?i=360
|
||||
[15] = http://curl.haxx.se/bug/?i=357
|
||||
[16] = https://github.com/bagder/curl/issues/361
|
||||
[17] = https://github.com/bagder/curl/issues/363
|
||||
[18] = https://github.com/bagder/curl/pull/174
|
||||
[19] = https://github.com/bagder/curl/issues/366
|
||||
[20] = http://curl.haxx.se/mail/lib-2015-08/0019.html
|
||||
[21] = http://curl.haxx.se/bug/?i=359
|
||||
[22] = http://curl.haxx.se/bug/?i=370
|
||||
[23] = http://curl.haxx.se/bug/?i=372
|
||||
[24] = http://curl.haxx.se/bug/?i=374
|
||||
[25] = http://curl.haxx.se/bug/?i=375
|
||||
|
||||
29
acinclude.m4
29
acinclude.m4
@@ -1851,8 +1851,10 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
|
||||
AC_REQUIRE([AC_HEADER_TIME])dnl
|
||||
AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
|
||||
AC_MSG_CHECKING([for monotonic clock_gettime])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#
|
||||
if test "x$dontwant_rt" == "xno" ; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@@ -1866,17 +1868,18 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
]],[[
|
||||
struct timespec ts;
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
]])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
ac_cv_func_clock_gettime="yes"
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
ac_cv_func_clock_gettime="no"
|
||||
])
|
||||
]],[[
|
||||
struct timespec ts;
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
]])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
ac_cv_func_clock_gettime="yes"
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
ac_cv_func_clock_gettime="no"
|
||||
])
|
||||
fi
|
||||
dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally postponed
|
||||
dnl until library linking and run-time checks for clock_gettime succeed.
|
||||
])
|
||||
|
||||
375
buildconf.bat
375
buildconf.bat
@@ -1,38 +1,353 @@
|
||||
@echo off
|
||||
REM
|
||||
REM
|
||||
REM This batch file must be used to set up a git tree to build on
|
||||
REM systems where there is no autotools support (i.e. Microsoft).
|
||||
REM
|
||||
REM This file is not included nor needed for curl's release
|
||||
REM archives, neither for curl's daily snapshot archives.
|
||||
rem ***************************************************************************
|
||||
rem * _ _ ____ _
|
||||
rem * Project ___| | | | _ \| |
|
||||
rem * / __| | | | |_) | |
|
||||
rem * | (__| |_| | _ <| |___
|
||||
rem * \___|\___/|_| \_\_____|
|
||||
rem *
|
||||
rem * Copyright (C) 1998 - 2015, 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 http://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
|
||||
ECHO ERROR: This file shall only be used with a curl git tree checkout.
|
||||
goto end_all
|
||||
:start_doing
|
||||
rem NOTES
|
||||
rem
|
||||
rem This batch file must be used to set up a git tree to build on systems where
|
||||
rem there is no autotools support (i.e. DOS and Windows).
|
||||
rem
|
||||
rem This file is not included or required for curl's release archives or daily
|
||||
rem snapshot archives.
|
||||
|
||||
REM create tool_hugehelp.c
|
||||
if not exist src\tool_hugehelp.c.cvs goto end_hugehelp_c
|
||||
copy /Y src\tool_hugehelp.c.cvs src\tool_hugehelp.c
|
||||
:end_hugehelp_c
|
||||
:begin
|
||||
rem Set our variables
|
||||
if "%OS%" == "Windows_NT" setlocal
|
||||
set MODE=GENERATE
|
||||
|
||||
REM create Makefile
|
||||
if not exist Makefile.dist goto end_makefile
|
||||
copy /Y Makefile.dist Makefile
|
||||
:end_makefile
|
||||
rem Switch to this batch file's directory
|
||||
cd /d "%~0\.." 1>NUL 2>&1
|
||||
|
||||
REM create curlbuild.h
|
||||
if not exist include\curl\curlbuild.h.dist goto end_curlbuild_h
|
||||
copy /Y include\curl\curlbuild.h.dist include\curl\curlbuild.h
|
||||
:end_curlbuild_h
|
||||
rem Check we are running from a curl git repository
|
||||
if not exist GIT-INFO goto norepo
|
||||
|
||||
REM setup c-ares git tree
|
||||
if not exist ares\buildconf.bat goto end_c_ares
|
||||
cd ares
|
||||
call buildconf.bat
|
||||
cd ..
|
||||
:end_c_ares
|
||||
rem Detect programs. HAVE_<PROGNAME>
|
||||
rem When not found the variable is set undefined. The undefined pattern
|
||||
rem allows for statements like "if not defined HAVE_PERL (command)"
|
||||
groff --version <NUL 1>NUL 2>&1
|
||||
if errorlevel 1 (set HAVE_GROFF=) else (set HAVE_GROFF=Y)
|
||||
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 4 goto nogencurlbuild
|
||||
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 3 goto nocleancurlbuild
|
||||
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 4 - failed to generate curlbuild.h
|
||||
rem
|
||||
:generate
|
||||
if "%OS%" == "Windows_NT" setlocal
|
||||
set BASIC_HUGEHELP=0
|
||||
|
||||
rem Create Makefile
|
||||
if exist Makefile.dist (
|
||||
echo * %CD%\Makefile
|
||||
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 Create curlbuild.h
|
||||
if exist include\curl\curlbuild.h.dist (
|
||||
echo * %CD%\include\curl\curlbuild.h
|
||||
copy /Y include\curl\curlbuild.h.dist include\curl\curlbuild.h 1>NUL 2>&1
|
||||
if errorlevel 1 (
|
||||
if "%OS%" == "Windows_NT" endlocal
|
||||
exit /B 4
|
||||
)
|
||||
)
|
||||
|
||||
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 3 - failed to clean curlbuild.h
|
||||
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
|
||||
)
|
||||
)
|
||||
|
||||
rem Remove curlbuild.h
|
||||
echo * %CD%\include\curl\curlbuild.h
|
||||
if exist include\curl\curlbuild.h (
|
||||
del include\curl\curlbuild.h 2>NUL
|
||||
if exist include\curl\curlbuild.h (
|
||||
exit /B 3
|
||||
/)
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
:nogencurlbuild
|
||||
echo.
|
||||
echo Error: Unable to generate include\curl\curlbuild.h
|
||||
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
|
||||
|
||||
:nocleancurlbuild
|
||||
echo.
|
||||
echo Error: Unable to clean include\curl\curlbuild.h
|
||||
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.
|
||||
echo.
|
||||
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
|
||||
|
||||
43
configure.ac
43
configure.ac
@@ -47,6 +47,7 @@ CURL_CHECK_OPTION_WERROR
|
||||
CURL_CHECK_OPTION_CURLDEBUG
|
||||
CURL_CHECK_OPTION_SYMBOL_HIDING
|
||||
CURL_CHECK_OPTION_ARES
|
||||
CURL_CHECK_OPTION_RT
|
||||
|
||||
XC_CHECK_PATH_SEPARATOR
|
||||
|
||||
@@ -1508,6 +1509,46 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
|
||||
])
|
||||
|
||||
|
||||
if test X"$HAVECRYPTO" = X"yes"; then
|
||||
AC_MSG_CHECKING([OpenSSL linking without -ldl])
|
||||
saved_libs=$LIBS
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#include <openssl/evp.h>
|
||||
],
|
||||
[
|
||||
SSLeay_add_all_algorithms();
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
LIBS="$saved_libs"
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([OpenSSL linking with -ldl])
|
||||
LIBS="-ldl $LIBS"
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#include <openssl/evp.h>
|
||||
],
|
||||
[
|
||||
SSLeay_add_all_algorithms();
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
LIBS="$saved_libs -ldl"
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
LIBS="$saved_libs"
|
||||
]
|
||||
)
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
if test X"$HAVECRYPTO" = X"yes"; then
|
||||
dnl This is only reasonable to do if crypto actually is there: check for
|
||||
dnl SSL libs NOTE: it is important to do this AFTER the crypto lib
|
||||
@@ -3217,7 +3258,7 @@ if test "x$want_thres" = xyes && test "x$want_ares" = xyes; then
|
||||
[Options --enable-threaded-resolver and --enable-ares are mutually exclusive])
|
||||
fi
|
||||
|
||||
if test "$want_thres" = "yes"; then
|
||||
if test "$want_thres" = "yes" && test "$dontwant_rt" = "no"; then
|
||||
AC_CHECK_HEADER(pthread.h,
|
||||
[ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have <pthread.h>])
|
||||
save_CFLAGS="$CFLAGS"
|
||||
|
||||
32
docs/CODE_OF_CONDUCT.md
Normal file
32
docs/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,32 @@
|
||||
Contributor Code of Conduct
|
||||
===========================
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all
|
||||
people who contribute through reporting issues, posting feature requests,
|
||||
updating documentation, submitting pull requests or patches, and other
|
||||
activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free
|
||||
experience for everyone, regardless of level of experience, gender, gender
|
||||
identity and expression, sexual orientation, disability, personal appearance,
|
||||
body size, race, ethnicity, age, or religion.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual
|
||||
language or imagery, derogatory comments or personal attacks, trolling, public
|
||||
or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct. Project maintainers who do not
|
||||
follow the Code of Conduct may be removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by opening an issue or contacting one or more of the project
|
||||
maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor
|
||||
Covenant](http://contributor-covenant.org), version 1.1.0, available at
|
||||
[http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/)
|
||||
12
docs/INSTALL
12
docs/INSTALL
@@ -473,12 +473,12 @@ Win32
|
||||
|
||||
Legacy Windows and SSL
|
||||
----------------------
|
||||
WinSSL (Windows SSPI, more specifically Schannel), is the native SSL library
|
||||
that comes with the Windows OS. WinSSL in Windows <= XP is not able to
|
||||
connect to servers that no longer support the legacy handshakes and
|
||||
algorithms used by those versions. If you will be using curl in one of those
|
||||
earlier versions of Windows you should choose another SSL backend like
|
||||
OpenSSL.
|
||||
|
||||
WinSSL (specifically SChannel from Windows SSPI), is the native SSL library
|
||||
in Windows. However, WinSSL in Windows <= XP is unable to connect to servers
|
||||
that no longer support the legacy handshakes and algorithms used by those
|
||||
versions. If you will be using curl in one of those earlier versions of
|
||||
Windows you should choose another SSL backend such as OpenSSL.
|
||||
|
||||
Apple iOS and Mac OS X
|
||||
======================
|
||||
|
||||
@@ -38,7 +38,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
||||
MAIL-ETIQUETTE HTTP-COOKIES SECURITY RELEASE-PROCEDURE \
|
||||
SSL-PROBLEMS HTTP2.md ROADMAP.md
|
||||
SSL-PROBLEMS HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md
|
||||
|
||||
MAN2HTML= roffit < $< >$@
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ CA bundle missing intermediate certificates
|
||||
problems if your CA cert does not have the certificates for the
|
||||
intermediates in the whole trust chain.
|
||||
|
||||
SSL version
|
||||
Protocol version
|
||||
|
||||
Some broken servers fail to support the protocol negotiation properly that
|
||||
SSL servers are supposed to handle. This may cause the connection to fail
|
||||
@@ -36,7 +36,9 @@ SSL version
|
||||
An additional complication can be that modern SSL libraries sometimes are
|
||||
built with support for older SSL and TLS versions disabled!
|
||||
|
||||
SSL ciphers
|
||||
All versions of SSL are considered insecure and should be avoided. Use TLS.
|
||||
|
||||
Ciphers
|
||||
|
||||
Clients give servers a list of ciphers to select from. If the list doesn't
|
||||
include any ciphers the server wants/can use, the connection handshake
|
||||
@@ -51,6 +53,10 @@ SSL ciphers
|
||||
Note that these weak ciphers are identified as flawed. For example, this
|
||||
includes symmetric ciphers with less than 128 bit keys and RC4.
|
||||
|
||||
WinSSL in Windows XP is not able to connect to servers that no longer
|
||||
support the legacy handshakes and algorithms used by those versions, so we
|
||||
advice against building curl to use WinSSL on really old Windows versions.
|
||||
|
||||
References:
|
||||
|
||||
https://tools.ietf.org/html/draft-popov-tls-prohibiting-rc4-01
|
||||
@@ -65,3 +71,17 @@ Allow BEAST
|
||||
introduced. Exactly as it sounds, it re-introduces the BEAST vulnerability
|
||||
but on the other hand it allows curl to connect to that kind of strange
|
||||
servers.
|
||||
|
||||
Disabling certificate revocation checks
|
||||
|
||||
Some SSL backends may do certificate revocation checks (CRL, OCSP, etc)
|
||||
depending on the OS or build configuration. The --ssl-no-revoke option was
|
||||
introduced in 7.44.0 to disable revocation checking but currently is only
|
||||
supported for WinSSL (the native Windows SSL library), with an exception in
|
||||
the case of Windows' Untrusted Publishers blacklist which it seems can't be
|
||||
bypassed. This option may have broader support to accommodate other SSL
|
||||
backends in the future.
|
||||
|
||||
References:
|
||||
|
||||
http://curl.haxx.se/docs/ssl-compared.html
|
||||
|
||||
45
docs/TODO
45
docs/TODO
@@ -26,6 +26,7 @@
|
||||
1.8 Allow SSL (HTTPS) to proxy
|
||||
1.9 Cache negative name resolves
|
||||
1.10 Support IDNA2008
|
||||
1.11 minimize dependencies with dynamicly loaded modules
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
@@ -113,6 +114,7 @@
|
||||
17.7 warning when sending binary output to terminal
|
||||
17.8 offer color-coded HTTP header output
|
||||
17.9 Choose the name of file in braces for complex URLs
|
||||
17.10 improve how curl works in a windows console window
|
||||
|
||||
18. Build
|
||||
18.1 roffit
|
||||
@@ -225,6 +227,13 @@
|
||||
by libidn. libidn implements IDNA2003 which has been superseded by IDNA2008.
|
||||
libidn2 is an existing library offering support for IDNA2008.
|
||||
|
||||
1.11 minimize dependencies with dynamicly loaded modules
|
||||
|
||||
We can create a system with loadable modules/plug-ins, where these modules
|
||||
would be the ones that link to 3rd party libs. That would allow us to avoid
|
||||
having to load ALL dependencies since only the necessary ones for this
|
||||
app/invoke/used protocols would be necessary to load. See
|
||||
https://github.com/bagder/curl/issues/349
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
@@ -615,32 +624,38 @@ Currently the SMB authentication uses NTLMv1.
|
||||
|
||||
17.6 warning when setting an option
|
||||
|
||||
Display a warning when libcurl returns an error when setting an option.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
Display a warning when libcurl returns an error when setting an option.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
|
||||
17.7 warning when sending binary output to terminal
|
||||
|
||||
Provide a way that prompts the user for confirmation before binary data is
|
||||
sent to the terminal, much in the style 'less' does it.
|
||||
Provide a way that prompts the user for confirmation before binary data is
|
||||
sent to the terminal, much in the style 'less' does it.
|
||||
|
||||
17.8 offer color-coded HTTP header output
|
||||
|
||||
By offering different color output on the header name and the header
|
||||
contents, they could be made more readable and thus help users working on
|
||||
HTTP services.
|
||||
By offering different color output on the header name and the header
|
||||
contents, they could be made more readable and thus help users working on
|
||||
HTTP services.
|
||||
|
||||
17.9 Choose the name of file in braces for complex URLs
|
||||
|
||||
When using braces to download a list of URLs and you use complicated names
|
||||
in the list of alternatives, it could be handy to allow curl to use other
|
||||
names when saving.
|
||||
When using braces to download a list of URLs and you use complicated names
|
||||
in the list of alternatives, it could be handy to allow curl to use other
|
||||
names when saving.
|
||||
|
||||
Consider a way to offer that. Possibly like
|
||||
{partURL1:name1,partURL2:name2,partURL3:name3} where the name following the
|
||||
colon is the output name.
|
||||
Consider a way to offer that. Possibly like
|
||||
{partURL1:name1,partURL2:name2,partURL3:name3} where the name following the
|
||||
colon is the output name.
|
||||
|
||||
See https://github.com/bagder/curl/issues/221
|
||||
See https://github.com/bagder/curl/issues/221
|
||||
|
||||
17.10 improve how curl works in a windows console window
|
||||
|
||||
If you pull the scrollbar when transferring with curl in a Windows console
|
||||
window, the transfer is interrupted and can get disconnected. This can
|
||||
probably be improved. See https://github.com/bagder/curl/issues/322
|
||||
|
||||
|
||||
18. Build
|
||||
|
||||
19
docs/curl.1
19
docs/curl.1
@@ -544,9 +544,11 @@ OpenSSL-powered curl to make SSL-connections much more efficiently than using
|
||||
|
||||
If this option is set, the default capath value will be ignored, and if it is
|
||||
used several times, the last one will be used.
|
||||
.IP "--pinnedpubkey <pinned public key>"
|
||||
(SSL) Tells curl to use the specified public key file to verify the peer. The
|
||||
file must contain a single public key in PEM or DER format.
|
||||
.IP "--pinnedpubkey <pinned public key (hashes)>"
|
||||
(SSL) Tells curl to use the specified public key file (or hashes) to verify the
|
||||
peer. This can be a path to a file which contains a single public key in PEM or
|
||||
DER format, or any number of base64 encoded sha256 hashes preceded by
|
||||
\'sha256//\' and seperated by \';\'
|
||||
|
||||
When negotiating a TLS or SSL connection, the server sends a certificate
|
||||
indicating its identity. A public key is extracted from this certificate and
|
||||
@@ -554,7 +556,8 @@ if it does not exactly match the public key provided to this option, curl will
|
||||
abort the connection before sending or receiving any data.
|
||||
|
||||
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for NSS and
|
||||
wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||
wolfSSL/CyaSSL. sha256 support added in 7.44.0 for OpenSSL,
|
||||
GnuTLS, NSS and wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cert-status"
|
||||
@@ -604,7 +607,9 @@ input:
|
||||
\fBcurl\fP -F password=@/etc/passwd www.mypasswords.com
|
||||
|
||||
To read content from stdin instead of a file, use - as the filename. This goes
|
||||
for both @ and < constructs.
|
||||
for both @ and < constructs. Unfortunately it does not support reading the
|
||||
file from a named pipe or similar, as it needs the full size before the
|
||||
transfer starts.
|
||||
|
||||
You can also tell curl what Content-Type to use by using 'type=', in a manner
|
||||
similar to:
|
||||
@@ -1542,6 +1547,10 @@ and TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer
|
||||
may use workarounds known to cause interoperability problems with some older
|
||||
SSL implementations. WARNING: this option loosens the SSL security, and by
|
||||
using this flag you ask for exactly that. (Added in 7.25.0)
|
||||
.IP "--ssl-no-revoke"
|
||||
(WinSSL) This option tells curl to disable certificate revocation checks.
|
||||
WARNING: this option loosens the SSL security, and by using this flag you ask
|
||||
for exactly that. (Added in 7.44.0)
|
||||
.IP "--socks4 <host[:port]>"
|
||||
Use the specified SOCKS4 proxy. If the port number is not specified, it is
|
||||
assumed at port 1080. (Added in 7.15.2)
|
||||
|
||||
@@ -32,7 +32,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
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-tls imap-multi url2file sftpget ftpsget postinmemory http2-download \
|
||||
http2-upload
|
||||
http2-upload http2-serverpush
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
|
||||
@@ -50,7 +50,7 @@ LIBRTMP_PATH = ../../../librtmp-2.4
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.30
|
||||
LIBIDN_PATH = ../../../libidn-1.32
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS IDN package.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
|
||||
@@ -34,7 +34,7 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.30
|
||||
LIBIDN_PATH = ../../../libidn-1.32
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,8 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
// Get a web page, parse it with libxml.
|
||||
//
|
||||
/* <DESC>
|
||||
* Get a web page, extract the title with libxml.
|
||||
* </DESC>
|
||||
*/
|
||||
// Written by Lars Nilsson
|
||||
//
|
||||
// GNU C++ compile command line suggestion (edit paths accordingly):
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* simple HTTP POST using the easy interface
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Multiplexed HTTP/2 downloads over a single connection
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
317
docs/examples/http2-serverpush.c
Normal file
317
docs/examples/http2-serverpush.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP/2 server push
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef CURLPIPE_MULTIPLEX
|
||||
#error "too old libcurl, can't do HTTP/2 server push!"
|
||||
#endif
|
||||
|
||||
static
|
||||
void dump(const char *text, unsigned char *ptr, size_t size,
|
||||
char nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stderr, "%s, %ld bytes (0x%lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stderr, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stderr, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* 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) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "%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 */
|
||||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stderr); /* newline */
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
(void)userp;
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, (unsigned char *)data, size, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup(CURL *hnd)
|
||||
{
|
||||
FILE *out = fopen("dl", "wb");
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
|
||||
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
|
||||
/* send it verbose for max debuggaility */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* called when there's an incoming push */
|
||||
static int server_push_callback(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp)
|
||||
{
|
||||
char *headp;
|
||||
size_t i;
|
||||
int *transfers = (int *)userp;
|
||||
char filename[128];
|
||||
FILE *out;
|
||||
static unsigned int count = 0;
|
||||
|
||||
(void)parent; /* we have no use for this */
|
||||
|
||||
sprintf(filename, "push%u", count++);
|
||||
|
||||
/* here's a new stream, save it in a new file for each new push */
|
||||
out = fopen(filename, "wb");
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, out);
|
||||
|
||||
fprintf(stderr, "**** push callback approves stream %u, got %d headers!\n",
|
||||
count, (int)num_headers);
|
||||
|
||||
for(i=0; i<num_headers; i++) {
|
||||
headp = curl_pushheader_bynum(headers, i);
|
||||
fprintf(stderr, "**** header %u: %s\n", (int)i, headp);
|
||||
}
|
||||
|
||||
headp = curl_pushheader_byname(headers, ":path");
|
||||
if(headp) {
|
||||
fprintf(stderr, "**** The PATH is %s\n", headp /* skip :path + colon */ );
|
||||
}
|
||||
|
||||
(*transfers)++; /* one more */
|
||||
return CURL_PUSH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Download a file over HTTP/2, take care of server push.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *easy;
|
||||
CURLM *multi_handle;
|
||||
int still_running; /* keep number of running handles */
|
||||
int transfers=1; /* we start with one */
|
||||
struct CURLMsg *m;
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
easy = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
setup(easy);
|
||||
|
||||
/* add the easy transfer */
|
||||
curl_multi_add_handle(multi_handle, easy);
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
CURLMcode mc; /* curl_multi_fdset() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
if(mc != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* On success the value of maxfd is guaranteed to be >= -1. We call
|
||||
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
|
||||
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
|
||||
to sleep 100ms, which is the minimum suggested value in the
|
||||
curl_multi_fdset() doc. */
|
||||
|
||||
if(maxfd == -1) {
|
||||
#ifdef _WIN32
|
||||
Sleep(100);
|
||||
rc = 0;
|
||||
#else
|
||||
/* Portable sleep for platforms other than Windows. */
|
||||
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
|
||||
rc = select(0, NULL, NULL, NULL, &wait);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* Note that on some platforms 'timeout' may be modified by select().
|
||||
If you need access to the original value save a copy beforehand. */
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* A little caution when doing server push is that libcurl itself has
|
||||
* created and added one or more easy handles but we need to clean them up
|
||||
* when we are done.
|
||||
*/
|
||||
|
||||
do {
|
||||
int msgq = 0;;
|
||||
m = curl_multi_info_read(multi_handle, &msgq);
|
||||
if(m && (m->msg == CURLMSG_DONE)) {
|
||||
CURL *e = m->easy_handle;
|
||||
transfers--;
|
||||
curl_multi_remove_handle(multi_handle, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
} while(m);
|
||||
|
||||
} while(transfers); /* as long as we have transfers going */
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Multiplexed HTTP/2 uploads over a single connection
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP request with custom modified, removed and added headers
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP PUT with easy interface and read callback
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Simple HTTPS GET
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Simple IMAP APPEND use
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,7 +19,10 @@
|
||||
* 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 <string.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi interface code doing two parallel HTTP transfers
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,8 +19,11 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* This is an example application source code using the multi interface
|
||||
* to do a multipart formpost without "blocking". */
|
||||
/* <DESC>
|
||||
* using the multi interface to do a multipart formpost without blocking
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,7 +19,10 @@
|
||||
* 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 <string.h>
|
||||
@@ -76,7 +79,7 @@ int main(void)
|
||||
|
||||
if(mc != CURLM_OK)
|
||||
{
|
||||
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
|
||||
fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -20,6 +20,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* multi_socket API using libuv
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application code using the multi socket interface to download
|
||||
multiple files at once, but instead of using curl_multi_perform and
|
||||
curl_multi_wait, which uses select(), we use libuv.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,8 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* A multi-threaded example that uses pthreads extensively to fetch
|
||||
* X remote files at once */
|
||||
/* <DESC>
|
||||
* A multi-threaded example that uses pthreads to fetch several files at once
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,16 +19,17 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example source code to show one way to set the necessary OpenSSL locking
|
||||
* callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
|
||||
* libcurl built to use OpenSSL.
|
||||
*
|
||||
/* <DESC>
|
||||
* one way to set the necessary OpenSSL locking callbacks if you want to do
|
||||
* multi-threaded transfers with HTTPS/FTPS with libcurl built to use OpenSSL.
|
||||
* </DESC>
|
||||
*/
|
||||
/*
|
||||
* This is not a complete stand-alone example.
|
||||
*
|
||||
* Author: Jeremy Brown
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* re-using handles to do HTTP persistent connections
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -19,8 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* An example source code that issues a HTTP POST and we provide the actual
|
||||
/* <DESC>
|
||||
* An example source code that issues a HTTP POST and we provide the actual
|
||||
* data through a read callback.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -1,63 +1,55 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
libcurl's binary interface
|
||||
|
||||
ABI - Application Binary Interface
|
||||
----------------------------------
|
||||
==================================
|
||||
|
||||
"ABI" describes the low-level interface between an application program and a
|
||||
library. Calling conventions, function arguments, return values, struct
|
||||
sizes/defines and more.
|
||||
"ABI" describes the low-level interface between an application program and a
|
||||
library. Calling conventions, function arguments, return values, struct
|
||||
sizes/defines and more.
|
||||
|
||||
[Wikipedia has a longer description](http://en.wikipedia.org/wiki/Application_binary_interface)
|
||||
[Wikipedia has a longer description](https://en.wikipedia.org/wiki/Application_binary_interface)
|
||||
|
||||
Upgrades
|
||||
--------
|
||||
|
||||
In the vast majority of all cases, a typical libcurl upgrade does not break
|
||||
the ABI at all. Your application can remain using libcurl just as before,
|
||||
only with less bugs and possibly with added new features. You need to read
|
||||
the release notes, and if they mention an ABI break/soname bump, you may
|
||||
have to verify that your application still builds fine and uses libcurl as
|
||||
it now is defined to work.
|
||||
In the vast majority of all cases, a typical libcurl upgrade does not break
|
||||
the ABI at all. Your application can remain using libcurl just as before,
|
||||
only with less bugs and possibly with added new features. You need to read
|
||||
the release notes, and if they mention an ABI break/soname bump, you may have
|
||||
to verify that your application still builds fine and uses libcurl as it now
|
||||
is defined to work.
|
||||
|
||||
Version Numbers
|
||||
---------------
|
||||
|
||||
In libcurl land, you really can't tell by the libcurl version number if that
|
||||
libcurl is binary compatible or not with another libcurl version.
|
||||
In libcurl land, you really can't tell by the libcurl version number if that
|
||||
libcurl is binary compatible or not with another libcurl version.
|
||||
|
||||
Soname Bumps
|
||||
------------
|
||||
|
||||
Whenever there are changes done to the library that will cause an ABI
|
||||
breakage, that may require your application to get attention or possibly be
|
||||
changed to adhere to new things, we will bump the soname. Then the library
|
||||
will get a different output name and thus can in fact be installed in
|
||||
parallel with an older installed lib (on most systems). Thus, old
|
||||
applications built against the previous ABI version will remain working and
|
||||
using the older lib, while newer applications build and use the newer one.
|
||||
Whenever there are changes done to the library that will cause an ABI
|
||||
breakage, that may require your application to get attention or possibly be
|
||||
changed to adhere to new things, we will bump the soname. Then the library
|
||||
will get a different output name and thus can in fact be installed in
|
||||
parallel with an older installed lib (on most systems). Thus, old
|
||||
applications built against the previous ABI version will remain working and
|
||||
using the older lib, while newer applications build and use the newer one.
|
||||
|
||||
During the first seven years of libcurl releases, there have only been four
|
||||
ABI breakages.
|
||||
During the first seven years of libcurl releases, there have only been four
|
||||
ABI breakages.
|
||||
|
||||
We are determined to bump the SONAME as rarely as possible. Ideally, we
|
||||
never do it again.
|
||||
We are determined to bump the SONAME as rarely as possible. Ideally, we
|
||||
never do it again.
|
||||
|
||||
Downgrades
|
||||
----------
|
||||
|
||||
Going to an older libcurl version from one you're currently using can be a
|
||||
tricky thing. Mostly we add features and options to newer libcurls as that
|
||||
won't break ABI or hamper existing applications. This has the implication
|
||||
that going backwards may get you in a situation where you pick a libcurl
|
||||
that doesn't support the options your application needs. Or possibly you
|
||||
even downgrade so far so you cross an ABI break border and thus a different
|
||||
soname, and then your application may need to adapt to the modified ABI.
|
||||
Going to an older libcurl version from one you're currently using can be a
|
||||
tricky thing. Mostly we add features and options to newer libcurls as that
|
||||
won't break ABI or hamper existing applications. This has the implication
|
||||
that going backwards may get you in a situation where you pick a libcurl that
|
||||
doesn't support the options your application needs. Or possibly you even
|
||||
downgrade so far so you cross an ABI break border and thus a different
|
||||
soname, and then your application may need to adapt to the modified ABI.
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
@@ -29,18 +29,19 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
||||
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
||||
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
||||
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 curl_global_cleanup.3 \
|
||||
curl_multi_add_handle.3 curl_multi_cleanup.3 curl_multi_fdset.3 \
|
||||
curl_multi_info_read.3 curl_multi_init.3 curl_multi_perform.3 \
|
||||
curl_multi_remove_handle.3 curl_share_cleanup.3 curl_share_init.3 \
|
||||
curl_share_setopt.3 libcurl.3 libcurl-easy.3 libcurl-multi.3 \
|
||||
libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
|
||||
curl_global_cleanup.3 curl_multi_add_handle.3 curl_multi_cleanup.3 \
|
||||
curl_multi_fdset.3 curl_multi_info_read.3 curl_multi_init.3 \
|
||||
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
|
||||
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
|
||||
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
||||
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
||||
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
|
||||
curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 \
|
||||
curl_multi_socket_action.3 curl_multi_wait.3 libcurl-symbols.3
|
||||
curl_multi_socket_action.3 curl_multi_wait.3 libcurl-symbols.3 \
|
||||
libcurl-thread.3
|
||||
|
||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||
@@ -60,27 +61,28 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_unescape.html curl_multi_setopt.html curl_multi_socket.html \
|
||||
curl_multi_timeout.html curl_formget.html curl_multi_assign.html \
|
||||
curl_easy_pause.html curl_easy_recv.html curl_easy_send.html \
|
||||
curl_multi_socket_action.html curl_multi_wait.html libcurl-symbols.html
|
||||
curl_multi_socket_action.html curl_multi_wait.html \
|
||||
libcurl-symbols.html libcurl-thread.html
|
||||
|
||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
||||
curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
|
||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
||||
curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
|
||||
curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
|
||||
curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
|
||||
curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
|
||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf curl_share_init.pdf \
|
||||
curl_share_setopt.pdf libcurl.pdf libcurl-multi.pdf libcurl-easy.pdf \
|
||||
libcurl-share.pdf libcurl-errors.pdf curl_easy_strerror.pdf \
|
||||
curl_multi_strerror.pdf curl_share_strerror.pdf \
|
||||
curl_global_init_mem.pdf libcurl-tutorial.pdf curl_easy_reset.pdf \
|
||||
curl_easy_escape.pdf curl_easy_unescape.pdf curl_multi_setopt.pdf \
|
||||
curl_multi_socket.pdf curl_multi_timeout.pdf curl_formget.pdf \
|
||||
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
||||
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf \
|
||||
libcurl-symbols.pdf
|
||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf \
|
||||
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
|
||||
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
||||
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
|
||||
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
||||
curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \
|
||||
curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf \
|
||||
curl_formget.pdf curl_multi_assign.pdf curl_easy_pause.pdf \
|
||||
curl_easy_recv.pdf curl_easy_send.pdf curl_multi_socket_action.pdf \
|
||||
curl_multi_wait.pdf libcurl-symbols.pdf libcurl-thread.pdf
|
||||
|
||||
m4macrodir = $(datadir)/aclocal
|
||||
dist_m4macro_DATA = libcurl.m4
|
||||
|
||||
@@ -42,7 +42,7 @@ buffer. The variable \fBn\fP points to will receive the number of received
|
||||
bytes.
|
||||
|
||||
To establish the connection, set \fBCURLOPT_CONNECT_ONLY(3)\fP option before
|
||||
calling \fIcurl_easy_perform(3)\fP or \cIcurl_multi_perform(3)\fP. Note that
|
||||
calling \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP. Note that
|
||||
\fIcurl_easy_recv(3)\fP does not work on connections that were created without
|
||||
this option.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -103,6 +103,9 @@ given file match one of the internally known file extensions. For
|
||||
providing multiple \fBCURLFORM_FILE\fP arguments each followed by the filename
|
||||
(and each \fICURLFORM_FILE\fP is allowed to have a
|
||||
\fICURLFORM_CONTENTTYPE\fP).
|
||||
|
||||
The given upload file has to exist in its full in the file system already when
|
||||
the upload starts, as libcurl needs to read the correct file size beforehand.
|
||||
.IP CURLFORM_CONTENTTYPE
|
||||
is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
|
||||
string which provides the content-type for this part, possibly instead of an
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -26,7 +26,7 @@ curl_formget - serialize a previously built multipart/formdata HTTP POST chain
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
|
||||
void curl_formget(struct curl_httppost * form, void *userp,
|
||||
int curl_formget(struct curl_httppost * form, void *userp,
|
||||
curl_formget_callback append );
|
||||
.SH DESCRIPTION
|
||||
curl_formget() is used to serialize data previously built/appended with
|
||||
|
||||
@@ -36,9 +36,10 @@ This function works exactly as \fIcurl_global_init(3)\fP with one addition: it
|
||||
allows the application to set callbacks to replace the otherwise used internal
|
||||
memory functions.
|
||||
|
||||
This man page only adds documentation for the callbacks, see the
|
||||
\fIcurl_global_init(3)\fP man page for all the rest. When you use this
|
||||
function, all callback arguments must be set to valid function pointers.
|
||||
When you use this function, all callback arguments must be set to valid
|
||||
function pointers. \fBIf you are using libcurl from multiple threads or with
|
||||
the threaded resolver (the default in Windows) the callback replacement
|
||||
functions must be thread safe.\fP
|
||||
|
||||
The prototypes for the given callbacks should match these:
|
||||
.IP "void *malloc_callback(size_t size);"
|
||||
@@ -51,6 +52,9 @@ To replace realloc()
|
||||
To replace strdup()
|
||||
.IP "void *calloc_callback(size_t nmemb, size_t size);"
|
||||
To replace calloc()
|
||||
.RE
|
||||
This function is otherwise the same as \fIcurl_global_init(3)\fP, please refer
|
||||
to that man page for documentation.
|
||||
.SH "CAUTION"
|
||||
Manipulating these gives considerable powers to the application to severely
|
||||
screw things up for libcurl. Take care!
|
||||
|
||||
@@ -28,7 +28,7 @@ curl_multi_remove_handle - remove an easy handle from a multi session
|
||||
CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle);
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
Removes a given \fIeasy_handle\fI from the \fImulti_handle\fI. This will make
|
||||
Removes a given \fIeasy_handle\fP from the \fImulti_handle\fP. This will make
|
||||
the specified easy handle be removed from this multi handle's control.
|
||||
|
||||
When the easy handle has been removed from a multi stack, it is again
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -37,32 +37,36 @@ expects. Read this manual carefully as bad input values may cause libcurl to
|
||||
behave badly! You can only set one option in each function call.
|
||||
|
||||
.SH OPTIONS
|
||||
.IP CURLMOPT_SOCKETFUNCTION
|
||||
See \fICURLMOPT_SOCKETFUNCTION(3)\fP
|
||||
.IP CURLMOPT_SOCKETDATA
|
||||
See \fICURLMOPT_SOCKETDATA(3)\fP
|
||||
.IP CURLMOPT_PIPELINING
|
||||
See \fICURLMOPT_PIPELINING(3)\fP
|
||||
.IP CURLMOPT_TIMERFUNCTION
|
||||
See \fICURLMOPT_TIMERFUNCTION(3)\fP
|
||||
.IP CURLMOPT_TIMERDATA
|
||||
See \fICURLMOPT_TIMERDATA(3)\fP
|
||||
.IP CURLMOPT_MAXCONNECTS
|
||||
See \fICURLMOPT_MAXCONNECTS(3)\fP
|
||||
.IP CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE
|
||||
See \fICURLMOPT_CHUNK_LENGTH_PENALTY_SIZE(3)\fP
|
||||
.IP CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE
|
||||
See \fICURLMOPT_CONTENT_LENGTH_PENALTY_SIZE(3)\fP
|
||||
.IP CURLMOPT_MAX_HOST_CONNECTIONS
|
||||
See \fICURLMOPT_MAX_HOST_CONNECTIONS(3)\fP
|
||||
.IP CURLMOPT_MAX_PIPELINE_LENGTH
|
||||
See \fICURLMOPT_MAX_PIPELINE_LENGTH(3)\fP
|
||||
.IP CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE
|
||||
See \fICURLMOPT_CONTENT_LENGTH_PENALTY_SIZE(3)\fP
|
||||
.IP CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE
|
||||
See \fICURLMOPT_CHUNK_LENGTH_PENALTY_SIZE(3)\fP
|
||||
.IP CURLMOPT_MAX_TOTAL_CONNECTIONS
|
||||
See \fICURLMOPT_MAX_TOTAL_CONNECTIONS(3)\fP
|
||||
.IP CURLMOPT_MAXCONNECTS
|
||||
See \fICURLMOPT_MAXCONNECTS(3)\fP
|
||||
.IP CURLMOPT_PIPELINING
|
||||
See \fICURLMOPT_PIPELINING(3)\fP
|
||||
.IP CURLMOPT_PIPELINING_SITE_BL
|
||||
See \fICURLMOPT_PIPELINING_SITE_BL(3)\fP
|
||||
.IP CURLMOPT_PIPELINING_SERVER_BL
|
||||
See \fICURLMOPT_PIPELINING_SERVER_BL(3)\fP
|
||||
.IP CURLMOPT_MAX_TOTAL_CONNECTIONS
|
||||
See \fICURLMOPT_MAX_TOTAL_CONNECTIONS(3)\fP
|
||||
.IP CURLMOPT_PUSHFUNCTION
|
||||
See \fICURLMOPT_PUSHFUNCTION(3)\fP
|
||||
.IP CURLMOPT_PUSHDATA
|
||||
See \fICURLMOPT_PUSHDATA(3)\fP
|
||||
.IP CURLMOPT_SOCKETFUNCTION
|
||||
See \fICURLMOPT_SOCKETFUNCTION(3)\fP
|
||||
.IP CURLMOPT_SOCKETDATA
|
||||
See \fICURLMOPT_SOCKETDATA(3)\fP
|
||||
.IP CURLMOPT_TIMERFUNCTION
|
||||
See \fICURLMOPT_TIMERFUNCTION(3)\fP
|
||||
.IP CURLMOPT_TIMERDATA
|
||||
See \fICURLMOPT_TIMERDATA(3)\fP
|
||||
.SH RETURNS
|
||||
The standard CURLMcode for multi interface error codes. Note that it returns a
|
||||
CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -46,6 +46,10 @@ pointer is returned.
|
||||
struct curl_slist *slist=NULL;
|
||||
|
||||
slist = curl_slist_append(slist, "pragma:");
|
||||
|
||||
if (slist == NULL)
|
||||
return -1;
|
||||
|
||||
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist);
|
||||
|
||||
curl_easy_perform(handle);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<br><a href="libcurl-share.html">libcurl-share</a>
|
||||
<br><a href="libcurl-errors.html">libcurl-errors</a>
|
||||
<br><a href="libcurl-tutorial.html">libcurl-tutorial</a>
|
||||
<br><a href="libcurl-thread.html">libcurl-thread</a>
|
||||
|
||||
<H2>Library Functions (A-Z)</H2>
|
||||
<a href="curl_easy_cleanup.html">curl_easy_cleanup</A>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -51,28 +51,27 @@ To use the multi interface, you must first create a 'multi handle' with
|
||||
\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
|
||||
curl_multi_* functions.
|
||||
|
||||
With a multi handle and the multi interface you can do any amount of
|
||||
simultaneous transfers in parallel. Each single transfer is built up around an
|
||||
easy handle. You must create the easy handles you need, and setup the
|
||||
appropriate options for each easy handle, as outlined in the \fIlibcurl(3)\fP
|
||||
man page, using \fIcurl_easy_setopt(3)\fP.
|
||||
With a multi handle and the multi interface you can do several simultaneous
|
||||
transfers in parallel. Each single transfer is built up around an easy
|
||||
handle. You create all the easy handles you need, and setup the appropriate
|
||||
options for each easy handle using \fIcurl_easy_setopt(3)\fP.
|
||||
|
||||
There are two flavours of the multi interface, the select() oriented one and
|
||||
the event based one we called multi_socket. You will benefit from reading
|
||||
through the description of both versions to full understand how they work and
|
||||
the event based one we call multi_socket. You will benefit from reading
|
||||
through the description of both versions to fully understand how they work and
|
||||
differentiate. We start out with the select() oriented version.
|
||||
|
||||
When an easy handle is setup for a transfer, then instead of using
|
||||
When an easy handle is setup and ready for transfer, then instead of using
|
||||
\fIcurl_easy_perform(3)\fP like when using the easy interface for transfers,
|
||||
you should add the easy handle to the multi handle with
|
||||
\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
|
||||
\'multi stack\' because of the fact that it may hold a large amount of easy
|
||||
handles.
|
||||
\fIcurl_multi_add_handle(3)\fP. You can add more easy handles to a multi
|
||||
handle at any point, even if other transfers are already running.
|
||||
|
||||
Should you change your mind, the easy handle is again removed from the multi
|
||||
stack using \fIcurl_multi_remove_handle(3)\fP. Once removed from the multi
|
||||
handle, you can again use other easy interface functions like
|
||||
\fIcurl_easy_perform(3)\fP on the handle or whatever you think is necessary.
|
||||
\fIcurl_easy_perform(3)\fP on the handle or whatever you think is
|
||||
necessary. You can remove handles at any point in time during transfers.
|
||||
|
||||
Adding the easy handle to the multi handle does not start the transfer.
|
||||
Remember that one of the main ideas with this interface is to let your
|
||||
@@ -84,16 +83,16 @@ current transfers in the multi stack that are ready to transfer anything. It
|
||||
may be all, it may be none. When there's nothing more to do for now, it
|
||||
returns back to the calling application.
|
||||
|
||||
Your application can acquire knowledge from libcurl when it would like to get
|
||||
invoked to transfer data, so that you don't have to busy-loop and call that
|
||||
\fIcurl_multi_perform(3)\fP like crazy. \fIcurl_multi_fdset(3)\fP offers an
|
||||
interface using which you can extract fd_sets from libcurl to use in select()
|
||||
or poll() calls in order to get to know when the transfers in the multi stack
|
||||
might need attention. This also makes it very easy for your program to wait
|
||||
for input on your own private file descriptors at the same time or perhaps
|
||||
timeout every now and then, should you want that. \fIcurl_multi_timeout(3)\fP
|
||||
also helps you with providing a suitable timeout period for your select()
|
||||
call.
|
||||
Your application extracts info from libcurl about when it would like to get
|
||||
invoked to transfer data or do other work. The most convenient way is to use
|
||||
\fIcurl_multi_wait(3)\fP that will help you wait until the application should
|
||||
call libcurl again. The older API to accomplish the same thing is
|
||||
\fIcurl_multi_fdset(3)\fP that extracts fd_sets from libcurl to use in
|
||||
select() or poll() calls in order to get to know when the transfers in the
|
||||
multi stack might need attention. Both these APIs allow for your program to
|
||||
wait for input on your own private file descriptors at the same time
|
||||
\fIcurl_multi_timeout(3)\fP also helps you with providing a suitable timeout
|
||||
period for your select() calls.
|
||||
|
||||
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
||||
one of its input arguments, and by reading that you can figure out when all
|
||||
@@ -114,9 +113,9 @@ the multi stack. You need to first remove the easy handle with
|
||||
\fIcurl_easy_cleanup(3)\fP, or possibly set new options to it and add it again
|
||||
with \fIcurl_multi_add_handle(3)\fP to start another transfer.
|
||||
|
||||
When all transfers in the multi stack are done, cleanup the multi handle with
|
||||
When all transfers in the multi stack are done, close the multi handle with
|
||||
\fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP
|
||||
invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle
|
||||
invoke separate \fIcurl_easy_cleanup(3)\fP calls for every single easy handle
|
||||
to clean them up properly.
|
||||
|
||||
If you want to re-use an easy handle that was added to the multi handle for
|
||||
|
||||
95
docs/libcurl/libcurl-thread.3
Normal file
95
docs/libcurl/libcurl-thread.3
Normal file
@@ -0,0 +1,95 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH libcurl-thread 3 "13 Jul 2015" "libcurl" "libcurl thread safety"
|
||||
.SH NAME
|
||||
libcurl-thread \- libcurl thread safety
|
||||
.SH "Multi-threading with libcurl"
|
||||
libcurl is thread safe but has no internal thread synchronization. You may have
|
||||
to provide your own locking should you meet any of the thread safety exceptions
|
||||
below.
|
||||
|
||||
\fBHandles.\fP You must \fBnever\fP share the same handle in multiple threads.
|
||||
You can pass the handles around among threads, but you must never use a single
|
||||
handle from more than one thread at any given time.
|
||||
|
||||
\fBShared objects.\fP You can share certain data between multiple handles by
|
||||
using the share interface but you must provide your own locking and set
|
||||
\fIcurl_share_setopt(3)\fP CURLSHOPT_LOCKFUNC and CURLSHOPT_UNLOCKFUNC.
|
||||
.SH TLS
|
||||
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
||||
then of course using the underlying SSL library multi-threaded and those libs
|
||||
might have their own requirements on this issue. You may need to provide one
|
||||
or two functions to allow it to function properly:
|
||||
.IP OpenSSL
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
http://curl.haxx.se/libcurl/c/opensslthreadlock.html
|
||||
.IP GnuTLS
|
||||
http://gnutls.org/manual/html_node/Thread-safety.html
|
||||
.IP NSS
|
||||
thread-safe already without anything required.
|
||||
.IP PolarSSL
|
||||
Required actions unknown.
|
||||
.IP yassl
|
||||
Required actions unknown.
|
||||
.IP axTLS
|
||||
Required actions unknown.
|
||||
.IP Secure-Transport
|
||||
The engine is used by libcurl in a way that is fully thread-safe.
|
||||
.IP WinSSL
|
||||
The engine is used by libcurl in a way that is fully thread-safe.
|
||||
.IP wolfSSL
|
||||
The engine is used by libcurl in a way that is fully thread-safe.
|
||||
.SH "Other areas of caution"
|
||||
.IP Signals
|
||||
Signals are used for timing out name resolves (during DNS lookup) - when built
|
||||
without using either the c-ares or threaded resolver backends. When using
|
||||
multiple threads you should set the \fICURLOPT_NOSIGNAL(3)\fP option to 1L for
|
||||
all handles. Everything will or might work fine except that timeouts are not
|
||||
honored during the DNS lookup - which you can work around by building libcurl
|
||||
with c-ares support. c-ares is a library that provides asynchronous name
|
||||
resolves. On some platforms, libcurl simply will not function properly
|
||||
multi-threaded unless this option is set.
|
||||
.IP "Name resolving"
|
||||
\fBgethostby* functions and other system calls.\fP These functions, provided
|
||||
by your operating system, must be thread safe. It is very important that
|
||||
libcurl can find and use thread safe versions of these and other system calls,
|
||||
as otherwise it can't function fully thread safe. Some operating systems are
|
||||
known to have faulty thread implementations. We have previously received
|
||||
problem reports on *BSD (at least in the past, they may be working fine these
|
||||
days). Some operating systems that are known to have solid and working thread
|
||||
support are Linux, Solaris and Windows.
|
||||
.IP "curl_global_* functions"
|
||||
These functions are not thread safe. If you are using libcurl with multiple
|
||||
threads it is especially important that before use you call
|
||||
\fIcurl_global_init(3)\fP or \fIcurl_global_init_mem(3)\fP to explicitly
|
||||
initialize the library and its dependents, rather than rely on the "lazy"
|
||||
fail-safe initialization that takes place the first time
|
||||
\fIcurl_easy_init(3)\fP is called. For an in-depth explanation refer to
|
||||
\fIlibcurl(3)\fP section \fBGLOBAL CONSTANTS\fP.
|
||||
.IP "Memory functions"
|
||||
These functions, provided either by your operating system or your own
|
||||
replacements, must be thread safe. You can use \fIcurl_global_init_mem(3)\fP
|
||||
to set your own replacement memory functions.
|
||||
.IP Non-safe functions
|
||||
\fICURLOPT_DNS_USE_GLOBAL_CACHE(3)\fP is not thread-safe.
|
||||
@@ -256,58 +256,8 @@ complication for you. Given simply the URL to a file, libcurl will take care
|
||||
of all the details needed to get the file moved from one machine to another.
|
||||
|
||||
.SH "Multi-threading Issues"
|
||||
The first basic rule is that you must \fBnever\fP simultaneously share a
|
||||
libcurl handle (be it easy or multi or whatever) between multiple
|
||||
threads. Only use one handle in one thread at any time. You can pass the
|
||||
handles around among threads, but you must never use a single handle from more
|
||||
than one thread at any given time.
|
||||
|
||||
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
|
||||
handlers. Signals are used for timing out name resolves (during DNS lookup) -
|
||||
when built without using either the c-ares or threaded resolver backends.
|
||||
|
||||
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
||||
then of course using the underlying SSL library multi-threaded and those libs
|
||||
might have their own requirements on this issue. Basically, you need to
|
||||
provide one or two functions to allow it to function properly. For all
|
||||
details, see this:
|
||||
|
||||
OpenSSL
|
||||
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
GnuTLS
|
||||
|
||||
http://gnutls.org/manual/html_node/Thread-safety.html
|
||||
|
||||
NSS
|
||||
|
||||
is claimed to be thread-safe already without anything required.
|
||||
|
||||
PolarSSL
|
||||
|
||||
Required actions unknown.
|
||||
|
||||
yassl
|
||||
|
||||
Required actions unknown.
|
||||
|
||||
axTLS
|
||||
|
||||
Required actions unknown.
|
||||
|
||||
Secure Transport
|
||||
|
||||
The engine is fully thread-safe, and no additional steps are required.
|
||||
|
||||
When using multiple threads you should set the \fICURLOPT_NOSIGNAL(3)\fP
|
||||
option to 1 for all handles. Everything will or might work fine except that
|
||||
timeouts are not honored during the DNS lookup - which you can work around by
|
||||
building libcurl with c-ares support. c-ares is a library that provides
|
||||
asynchronous name resolves. On some platforms, libcurl simply will not
|
||||
function properly multi-threaded unless this option is set.
|
||||
|
||||
Also, note that \fICURLOPT_DNS_USE_GLOBAL_CACHE(3)\fP is not thread-safe.
|
||||
libcurl is thread safe but there are a few exceptions. Refer to
|
||||
\fIlibcurl-thread(3)\fP for more information.
|
||||
|
||||
.SH "When It Doesn't Work"
|
||||
There will always be times when the transfer fails for some reason. You might
|
||||
@@ -1005,7 +955,7 @@ or understand incoming cookies and they will just be ignored. However, when
|
||||
the parser is enabled the cookies will be understood and the cookies will be
|
||||
kept in memory and used properly in subsequent requests when the same handle
|
||||
is used. Many times this is enough, and you may not have to save the cookies
|
||||
to disk at all. Note that the file you specify to \ICURLOPT_COOKIEFILE(3)\fP
|
||||
to disk at all. Note that the file you specify to \fICURLOPT_COOKIEFILE(3)\fP
|
||||
doesn't have to exist to enable the parser, so a common way to just enable the
|
||||
parser and not read any cookies is to use the name of a file you know doesn't
|
||||
exist.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -97,8 +97,8 @@ Unix-like operating system that ship libcurl as part of their distributions
|
||||
often don't provide the curl-config tool, but simply install the library and
|
||||
headers in the common path for this purpose.
|
||||
|
||||
Many Linux and similar sytems use pkg-config to provide build and link options
|
||||
about libraries and libcurl supports that as well.
|
||||
Many Linux and similar systems use pkg-config to provide build and link
|
||||
options about libraries and libcurl supports that as well.
|
||||
.SH "LIBCURL SYMBOL NAMES"
|
||||
All public functions in the libcurl interface are prefixed with 'curl_' (with
|
||||
a lowercase c). You can find other functions in the library source code, but
|
||||
@@ -111,13 +111,8 @@ libcurl works
|
||||
.B exactly
|
||||
the same, on any of the platforms it compiles and builds on.
|
||||
.SH "THREADS"
|
||||
Never ever call curl-functions simultaneously using the same handle from
|
||||
several threads. libcurl is thread-safe and can be used in any number of
|
||||
threads, but you must use separate curl handles if you want to use libcurl in
|
||||
more than one thread simultaneously.
|
||||
|
||||
The global environment functions are not thread-safe. See \fBGLOBAL
|
||||
CONSTANTS\fP below for details.
|
||||
libcurl is thread safe but there are a few exceptions. Refer to
|
||||
\fIlibcurl-thread(3)\fP for more information.
|
||||
|
||||
.SH "PERSISTENT CONNECTIONS"
|
||||
Persistent connections means that libcurl can re-use the same connection for
|
||||
|
||||
49
docs/libcurl/opts/CURLMOPT_PUSHDATA.3
Normal file
49
docs/libcurl/opts/CURLMOPT_PUSHDATA.3
Normal file
@@ -0,0 +1,49 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH CURLMOPT_PUSHDATA 3 "1 Jun 2015" "libcurl 7.44.0" "curl_multi_setopt options"
|
||||
.SH NAME
|
||||
CURLMOPT_PUSHDATA \- pointer to pass to push callback
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PUSHDATA, void *pointer);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
Set \fIpointer\fP to pass as the last argument to the
|
||||
\fICURLMOPT_PUSHFUNCTION(3)\fP callback. The pointer will not be touched or
|
||||
used by libcurl itself, only passed on to the callback function.
|
||||
.SH DEFAULT
|
||||
NULL
|
||||
.SH PROTOCOLS
|
||||
HTTP(S)
|
||||
.SH EXAMPLE
|
||||
TODO
|
||||
.SH AVAILABILITY
|
||||
Added in 7.44.0
|
||||
.SH RETURN VALUE
|
||||
Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not.
|
||||
.SH "SEE ALSO"
|
||||
.BR CURLMOPT_PUSHFUNCTION "(3), " CURLMOPT_PIPELINING "(3), "
|
||||
.BR CURLOPT_PIPEWAIT "(3), "
|
||||
.BR RFC 7540
|
||||
132
docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3
Normal file
132
docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3
Normal file
@@ -0,0 +1,132 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH CURLMOPT_PUSHFUNCTION 3 "1 Jun 2015" "libcurl 7.44.0" "curl_multi_setopt options"
|
||||
.SH NAME
|
||||
CURLMOPT_PUSHFUNCTION \- callback that approves or denies server pushes
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <curl/curl.h>
|
||||
|
||||
char *curl_pushheader_bynum(push_headers, int num);
|
||||
char *curl_pushheader_byname(push_headers, const char *name);
|
||||
|
||||
int curl_push_callback(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp);
|
||||
|
||||
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PUSHFUNCTION,
|
||||
curl_push_callback func);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This callback gets called when a new HTTP/2 stream is being pushed by the
|
||||
server (using the PUSH_PROMISE frame). If no push callback is set, all offered
|
||||
pushes will be denied automatically.
|
||||
.SH CALLBACK DESCRIPTION
|
||||
The callback gets its arguments like this:
|
||||
|
||||
\fIparent\fP is the handle of the stream on which this push arrives. The new
|
||||
handle has been duphandle()d from the parent, meaning that it has gotten all
|
||||
its options inherited. It is then up to the application to alter any options
|
||||
if desired.
|
||||
|
||||
\fIeasy\fP is a newly created handle that represents this upcoming transfer.
|
||||
|
||||
\fInum_headers\fP is the number of name+value pairs that was received and can
|
||||
be accessed
|
||||
|
||||
\fIheaders\fP is a handle used to access push headers using the accessor
|
||||
functions described below. This only accesses and provides the PUSH_PROMISE
|
||||
headers, the normal response headers will be provided in the header callback
|
||||
as usual.
|
||||
|
||||
\fIuserp\fP is the pointer set with \fICURLMOPT_PUSHDATA(3)\fP
|
||||
|
||||
If the callback returns CURL_PUSH_OK, the 'easy' handle will be added to the
|
||||
multi handle, the callback must not do that by itself.
|
||||
|
||||
The callback can access PUSH_PROMISE headers with two accessor
|
||||
functions. These functions can only be used from within this callback and they
|
||||
can only access the PUSH_PROMISE headers. The normal response headers will be
|
||||
pased to the header callback for pushed streams just as for normal streams.
|
||||
.IP curl_pushheader_bynum
|
||||
Returns the header at index 'num' (or NULL). The returned pointer points to a
|
||||
"name:value" string that will be freed when this callback returns.
|
||||
.IP curl_pushheader_byname
|
||||
Returns the value for the given header name (or NULL). This is a shortcut so
|
||||
that the application doesn't have to loop through all headers to find the one
|
||||
it is interested in. The data pointed will be freed when this callback
|
||||
returns.
|
||||
.SH CALLBACK RETURN VALUE
|
||||
.IP "CURL_PUSH_OK (0)"
|
||||
The application has accepted the stream and it can now start receiving data,
|
||||
the ownership of the CURL handle has been taken over by the application.
|
||||
.IP "CURL_PUSH_DENY (1)"
|
||||
The callback denies the stream and no data for this will reach the
|
||||
application, the easy handle will be destroyed by libcurl.
|
||||
.IP *
|
||||
All other return codes are reserved for future use.
|
||||
.SH DEFAULT
|
||||
NULL, no callback
|
||||
.SH PROTOCOLS
|
||||
HTTP(S) (HTTP/2 only)
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
/* only allow pushes for file names starting with "push-" */
|
||||
int push_callback(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp)
|
||||
{
|
||||
char *headp;
|
||||
int *transfers = (int *)userp;
|
||||
FILE *out;
|
||||
headp = curl_pushheader_byname(headers, ":path");
|
||||
if(headp && !strncmp(headp, "/push-", 6)) {
|
||||
fprintf(stderr, "The PATH is %s\n", headp);
|
||||
|
||||
/* save the push here */
|
||||
out = fopen("pushed-stream", "wb");
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, out);
|
||||
|
||||
(*transfers)++; /* one more */
|
||||
|
||||
return CURL_PUSH_OK;
|
||||
}
|
||||
return CURL_PUSH_DENY;
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback);
|
||||
curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter);
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.44.0
|
||||
.SH RETURN VALUE
|
||||
Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not.
|
||||
.SH "SEE ALSO"
|
||||
.BR CURLMOPT_PUSHDATA "(3), " CURLMOPT_PIPELINING "(3), " CURLOPT_PIPEWAIT "(3), "
|
||||
.BR RFC 7540
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -39,6 +39,9 @@ response codes will slip through, especially when authentication is involved
|
||||
You might get some amounts of headers transferred before this situation is
|
||||
detected, like when a "100-continue" is received as a response to a POST/PUT
|
||||
and a 401 or 407 is received immediately afterwards.
|
||||
|
||||
When this option is used and an error is detected, it will cause the
|
||||
connection to get closed.
|
||||
.SH DEFAULT
|
||||
0, do not fail on error
|
||||
.SH PROTOCOLS
|
||||
|
||||
@@ -28,8 +28,10 @@ CURLOPT_PINNEDPUBLICKEY \- set pinned public key
|
||||
|
||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PINNEDPUBLICKEY, char *pinnedpubkey);
|
||||
.SH DESCRIPTION
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the file name of your pinned public key. The format expected is "PEM" or "DER".
|
||||
Pass a pointer to a zero terminated string as parameter. The string can be the
|
||||
file name of your pinned public key. The file format expected is "PEM" or "DER".
|
||||
The string can also be any number of base64 encoded sha256 hashes preceded by
|
||||
"sha256//" and seperated by ";"
|
||||
|
||||
When negotiating a TLS or SSL connection, the server sends a certificate
|
||||
indicating its identity. A public key is extracted from this certificate and
|
||||
@@ -45,6 +47,9 @@ CURL *curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, "/etc/publickey.der");
|
||||
/* OR
|
||||
curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjAa3HWY3tvRMwE=;sha256//t62CeU2tQiqkexU74Gxa2eg7fRbEgoChTociMee9wno=");
|
||||
*/
|
||||
|
||||
/* Perform the request */
|
||||
curl_easy_perform(curl);
|
||||
@@ -54,9 +59,14 @@ if(curl) {
|
||||
If you do not have the server's public key file you can extract it from the
|
||||
server's certificate.
|
||||
.nf
|
||||
# extract public key in pem format from certificate
|
||||
openssl x509 -in www.test.com.pem -pubkey -noout > www.test.com.pubkey.pem
|
||||
# convert public key from pem to der
|
||||
openssl asn1parse -noout -inform pem -in www.test.com.pubkey.pem -out www.test.com.pubkey.der
|
||||
# sha256 hash and base64 encode der to string for use
|
||||
openssl dgst -sha256 -binary www.test.com.pubkey.der | openssl base64
|
||||
.fi
|
||||
The public key is output in PEM format and contains a header, base64 data and a
|
||||
The public key in PEM format contains a header, base64 data and a
|
||||
footer:
|
||||
.nf
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
@@ -65,7 +75,8 @@ footer:
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for
|
||||
NSS and wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||
NSS and wolfSSL/CyaSSL. sha256 support added in 7.44.0 for OpenSSL,
|
||||
GnuTLS, NSS and wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||
.SH RETURN VALUE
|
||||
Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
|
||||
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
||||
|
||||
@@ -51,7 +51,8 @@ entries.
|
||||
You can remove names from the DNS cache again, to stop providing these fake
|
||||
resolves, by including a string in the linked list that uses the format
|
||||
\&"-HOST:PORT". The host name must be prefixed with a dash, and the host name
|
||||
and port number must exactly match what was already added previously.
|
||||
and port number must exactly match what was already added previously. (Added in
|
||||
7.42.0)
|
||||
.SH DEFAULT
|
||||
NULL
|
||||
.SH PROTOCOLS
|
||||
@@ -75,7 +76,7 @@ if(curl) {
|
||||
curl_slist_free_all(host);
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.21.3
|
||||
Added in 7.21.3. Removal support added in 7.42.0.
|
||||
.SH RETURN VALUE
|
||||
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
||||
.SH "SEE ALSO"
|
||||
|
||||
@@ -30,13 +30,25 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_OPTIONS, long bitmask);
|
||||
.SH DESCRIPTION
|
||||
Pass a long with a bitmask to tell libcurl about specific SSL behaviors.
|
||||
|
||||
\fICURLSSLOPT_ALLOW_BEAST\fP is the only supported bit and by setting this the
|
||||
user will tell libcurl to not attempt to use any workarounds for a security
|
||||
flaw in the SSL3 and TLS1.0 protocols. If this option isn't used or this bit
|
||||
is set to 0, the SSL layer libcurl uses may use a work-around for this flaw
|
||||
although it might cause interoperability problems with some (older) SSL
|
||||
implementations. WARNING: avoiding this work-around lessens the security, and
|
||||
by setting this option to 1 you ask for exactly that.
|
||||
\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any
|
||||
workarounds for a security flaw in the SSL3 and TLS1.0 protocols. If this
|
||||
option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a
|
||||
work-around for this flaw although it might cause interoperability problems
|
||||
with some (older) SSL implementations. WARNING: avoiding this work-around
|
||||
lessens the security, and by setting this option to 1 you ask for exactly that.
|
||||
This option is only supported for DarwinSSL, NSS and OpenSSL.
|
||||
|
||||
Added in 7.44.0:
|
||||
|
||||
\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation
|
||||
checks for those SSL backends where such behavior is present. \fBCurrently this
|
||||
option is only supported for WinSSL (the native Windows SSL library), with an
|
||||
exception in the case of Windows' Untrusted Publishers blacklist which it seems
|
||||
can't be bypassed.\fP This option may have broader support to accommodate other
|
||||
SSL backends in the future.
|
||||
http://curl.haxx.se/docs/ssl-compared.html
|
||||
|
||||
|
||||
.SH DEFAULT
|
||||
0
|
||||
.SH PROTOCOLS
|
||||
|
||||
@@ -114,7 +114,8 @@ man_MANS = CURLOPT_ACCEPT_ENCODING.3 CURLOPT_ACCEPTTIMEOUT_MS.3 \
|
||||
CURLMOPT_SOCKETDATA.3 CURLMOPT_SOCKETFUNCTION.3 CURLMOPT_TIMERDATA.3 \
|
||||
CURLMOPT_TIMERFUNCTION.3 CURLOPT_UNIX_SOCKET_PATH.3 \
|
||||
CURLOPT_PATH_AS_IS.3 CURLOPT_PROXY_SERVICE_NAME.3 \
|
||||
CURLOPT_SERVICE_NAME.3 CURLOPT_PIPEWAIT.3
|
||||
CURLOPT_SERVICE_NAME.3 CURLOPT_PIPEWAIT.3 CURLMOPT_PUSHDATA.3 \
|
||||
CURLMOPT_PUSHFUNCTION.3
|
||||
|
||||
HTMLPAGES = CURLOPT_ACCEPT_ENCODING.html CURLOPT_ACCEPTTIMEOUT_MS.html \
|
||||
CURLOPT_ADDRESS_SCOPE.html CURLOPT_APPEND.html \
|
||||
@@ -222,7 +223,8 @@ HTMLPAGES = CURLOPT_ACCEPT_ENCODING.html CURLOPT_ACCEPTTIMEOUT_MS.html \
|
||||
CURLMOPT_TIMERDATA.html CURLMOPT_TIMERFUNCTION.html \
|
||||
CURLOPT_UNIX_SOCKET_PATH.html CURLOPT_PATH_AS_IS.html \
|
||||
CURLOPT_PROXY_SERVICE_NAME.html CURLOPT_SERVICE_NAME.html \
|
||||
CURLOPT_PIPEWAIT.html
|
||||
CURLOPT_PIPEWAIT.html CURLMOPT_PUSHDATA.html \
|
||||
CURLMOPT_PUSHFUNCTION.html
|
||||
|
||||
PDFPAGES = CURLOPT_ACCEPT_ENCODING.pdf CURLOPT_ACCEPTTIMEOUT_MS.pdf \
|
||||
CURLOPT_ADDRESS_SCOPE.pdf CURLOPT_APPEND.pdf CURLOPT_AUTOREFERER.pdf \
|
||||
@@ -328,7 +330,7 @@ PDFPAGES = CURLOPT_ACCEPT_ENCODING.pdf CURLOPT_ACCEPTTIMEOUT_MS.pdf \
|
||||
CURLMOPT_TIMERDATA.pdf CURLMOPT_TIMERFUNCTION.pdf \
|
||||
CURLOPT_UNIX_SOCKET_PATH.pdf CURLOPT_PATH_AS_IS.pdf \
|
||||
CURLOPT_PROXY_SERVICE_NAME.pdf CURLOPT_SERVICE_NAME.pdf \
|
||||
CURLOPT_PIPEWAIT.pdf
|
||||
CURLOPT_PIPEWAIT.pdf CURLMOPT_PUSHDATA.pdf CURLMOPT_PUSHFUNCTION.pdf
|
||||
|
||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||
|
||||
|
||||
@@ -284,6 +284,8 @@ CURLMOPT_MAX_TOTAL_CONNECTIONS 7.30.0
|
||||
CURLMOPT_PIPELINING 7.16.0
|
||||
CURLMOPT_PIPELINING_SERVER_BL 7.30.0
|
||||
CURLMOPT_PIPELINING_SITE_BL 7.30.0
|
||||
CURLMOPT_PUSHDATA 7.44.0
|
||||
CURLMOPT_PUSHFUNCTION 7.44.0
|
||||
CURLMOPT_SOCKETDATA 7.15.4
|
||||
CURLMOPT_SOCKETFUNCTION 7.15.4
|
||||
CURLMOPT_TIMERDATA 7.16.0
|
||||
@@ -631,6 +633,7 @@ CURLSSLBACKEND_POLARSSL 7.34.0
|
||||
CURLSSLBACKEND_QSOSSL 7.34.0 - 7.38.1
|
||||
CURLSSLBACKEND_SCHANNEL 7.34.0
|
||||
CURLSSLOPT_ALLOW_BEAST 7.25.0
|
||||
CURLSSLOPT_NO_REVOKE 7.44.0
|
||||
CURLUSESSL_ALL 7.17.0
|
||||
CURLUSESSL_CONTROL 7.17.0
|
||||
CURLUSESSL_NONE 7.17.0
|
||||
@@ -702,6 +705,8 @@ CURL_POLL_OUT 7.14.0
|
||||
CURL_POLL_REMOVE 7.14.0
|
||||
CURL_PROGRESS_BAR 7.1.1 - 7.4.1
|
||||
CURL_PROGRESS_STATS 7.1.1 - 7.4.1
|
||||
CURL_PUSH_DENY 7.44.0
|
||||
CURL_PUSH_OK 7.44.0
|
||||
CURL_READFUNC_ABORT 7.12.1
|
||||
CURL_READFUNC_PAUSE 7.18.0
|
||||
CURL_REDIR_GET_ALL 7.19.1
|
||||
|
||||
@@ -725,6 +725,10 @@ typedef enum {
|
||||
servers, a user can this way allow the vulnerability back. */
|
||||
#define CURLSSLOPT_ALLOW_BEAST (1<<0)
|
||||
|
||||
/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
|
||||
SSL backends where such behavior is present. */
|
||||
#define CURLSSLOPT_NO_REVOKE (1<<1)
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
|
||||
@@ -370,6 +370,12 @@ typedef enum {
|
||||
/* maximum number of open connections in total */
|
||||
CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
|
||||
|
||||
/* This is the server push callback function pointer */
|
||||
CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
|
||||
|
||||
/* This is the argument passed to the server push callback */
|
||||
CINIT(PUSHDATA, OBJECTPOINT, 15),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
@@ -397,6 +403,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t sockfd, void *sockp);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
|
||||
size_t num);
|
||||
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
|
||||
const char *name);
|
||||
|
||||
typedef int (*curl_push_callback)(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -80,9 +80,9 @@ if SONAME_BUMP
|
||||
#
|
||||
# This conditional soname bump SHOULD be removed at next "proper" bump.
|
||||
#
|
||||
VERSIONINFO=-version-info 8:0:3
|
||||
VERSIONINFO=-version-info 9:0:4
|
||||
else
|
||||
VERSIONINFO=-version-info 7:0:3
|
||||
VERSIONINFO=-version-info 8:0:4
|
||||
endif
|
||||
|
||||
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||
|
||||
@@ -30,7 +30,7 @@ LIBRTMP_PATH = ../../librtmp-2.4
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.30
|
||||
LIBIDN_PATH = ../../libidn-1.32
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS IDN package.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
|
||||
@@ -949,16 +949,21 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
}
|
||||
#else
|
||||
ULONGLONG majorVersionMask;
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION,
|
||||
VER_GREATER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask))
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
else
|
||||
detectOsState = DETECT_OS_PREVISTA;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -27,9 +27,9 @@
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
|
||||
static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
|
||||
@@ -84,7 +84,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
if(ntlm->state == NTLMSTATE_LAST) {
|
||||
infof(conn->data, "NTLM auth restarted\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
}
|
||||
else if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
ntlm->state = NTLMSTATE_NONE;
|
||||
@@ -211,6 +215,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
ntlm->state = NTLMSTATE_LAST;
|
||||
|
||||
case NTLMSTATE_LAST:
|
||||
Curl_safefree(*allocuserpwd);
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
|
||||
@@ -306,7 +306,7 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
len_out == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
goto done;
|
||||
/* invalid response */
|
||||
if(len_out < 4)
|
||||
goto done;
|
||||
|
||||
@@ -93,20 +93,25 @@ CURLcode Curl_sspi_global_init(void)
|
||||
osver.dwPlatformId == platformId)
|
||||
securityDll = TRUE;
|
||||
#else
|
||||
ULONGLONG majorVersionMask;
|
||||
ULONGLONG platformIdMask;
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwPlatformId = platformId;
|
||||
majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
platformIdMask = VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
/* Verify the major version number == 4 and platform id == WIN_NT */
|
||||
if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask) &&
|
||||
VerifyVersionInfo(&osver, VER_PLATFORMID, platformIdMask))
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
|
||||
VER_PLATFORMID),
|
||||
cm))
|
||||
securityDll = TRUE;
|
||||
#endif
|
||||
|
||||
@@ -219,7 +224,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
|
||||
Curl_unicodefree(useranddomain.tchar_ptr);
|
||||
|
||||
/* Setup ntlm identity's password and length */
|
||||
/* Setup the identity's password and length */
|
||||
passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
46
lib/http.c
46
lib/http.c
@@ -86,7 +86,6 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode http_disconnect(struct connectdata *conn, bool dead);
|
||||
static int http_getsock_do(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
@@ -117,7 +116,7 @@ const struct Curl_handler Curl_handler_http = {
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
http_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
@@ -141,7 +140,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
http_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTPS, /* defport */
|
||||
CURLPROTO_HTTPS, /* protocol */
|
||||
@@ -164,25 +163,11 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
conn->data->req.protop = http;
|
||||
|
||||
Curl_http2_setup_conn(conn);
|
||||
Curl_http2_setup_req(conn->data);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode http_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
#ifdef USE_NGHTTP2
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
if(http) {
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
}
|
||||
#else
|
||||
(void)conn;
|
||||
#endif
|
||||
(void)dead_connection;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||
* particular header (prefix).
|
||||
@@ -1458,7 +1443,10 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct HTTP *http =data->req.protop;
|
||||
struct HTTP *http = data->req.protop;
|
||||
#ifdef USE_NGHTTP2
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
#endif
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
@@ -1491,6 +1479,15 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
if(http->stream_id) {
|
||||
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3571,14 +3568,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
k->auto_decoding = GZIP;
|
||||
start += 6;
|
||||
}
|
||||
else if(checkprefix("compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 8;
|
||||
}
|
||||
else if(checkprefix("x-compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 10;
|
||||
}
|
||||
else
|
||||
/* unknown! */
|
||||
break;
|
||||
@@ -3611,9 +3600,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
else if(checkprefix("gzip", start)
|
||||
|| checkprefix("x-gzip", start))
|
||||
k->auto_decoding = GZIP;
|
||||
else if(checkprefix("compress", start)
|
||||
|| checkprefix("x-compress", start))
|
||||
k->auto_decoding = COMPRESS;
|
||||
}
|
||||
else if(checkprefix("Content-Range:", k->p)) {
|
||||
/* Content-Range: bytes [num]-
|
||||
|
||||
@@ -176,6 +176,10 @@ struct HTTP {
|
||||
const uint8_t *upload_mem; /* points to a buffer to read from */
|
||||
size_t upload_len; /* size of the buffer 'upload_mem' points to */
|
||||
curl_off_t upload_left; /* number of bytes left to upload */
|
||||
|
||||
char **push_headers; /* allocated array */
|
||||
size_t push_headers_used; /* number of entries filled in */
|
||||
size_t push_headers_alloc; /* number of entries allocated */
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -211,7 +215,6 @@ struct http_conn {
|
||||
nghttp2_session_mem_recv */
|
||||
|
||||
/* this is a hash of all individual streams (SessionHandle structs) */
|
||||
struct curl_hash streamsh;
|
||||
struct h2settings settings;
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
|
||||
495
lib/http2.c
495
lib/http2.c
@@ -33,6 +33,7 @@
|
||||
#include "rawstr.h"
|
||||
#include "multiif.h"
|
||||
#include "conncache.h"
|
||||
#include "url.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -79,6 +80,7 @@ static int http2_getsock(struct connectdata *conn,
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
|
||||
@@ -86,7 +88,16 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
Curl_hash_destroy(&c->streamsh);
|
||||
|
||||
if(http) {
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
|
||||
|
||||
@@ -94,12 +105,9 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn)
|
||||
void Curl_http2_setup_req(struct SessionHandle *data)
|
||||
{
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
|
||||
conn->proto.httpc.settings.max_concurrent_streams =
|
||||
DEFAULT_MAX_CONCURRENT_STREAMS;
|
||||
struct HTTP *http = data->req.protop;
|
||||
|
||||
http->nread_header_recvbuf = 0;
|
||||
http->bodystarted = FALSE;
|
||||
@@ -108,13 +116,18 @@ void Curl_http2_setup_conn(struct connectdata *conn)
|
||||
http->pauselen = 0;
|
||||
http->error_code = NGHTTP2_NO_ERROR;
|
||||
http->closed = FALSE;
|
||||
|
||||
/* where to store incoming data for this stream and how big the buffer is */
|
||||
http->mem = conn->data->state.buffer;
|
||||
http->mem = data->state.buffer;
|
||||
http->len = BUFSIZE;
|
||||
http->memlen = 0;
|
||||
}
|
||||
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
conn->proto.httpc.settings.max_concurrent_streams =
|
||||
DEFAULT_MAX_CONCURRENT_STREAMS;
|
||||
}
|
||||
|
||||
/*
|
||||
* HTTP2 handler interface. This isn't added to the general list of protocols
|
||||
* but will be used at run-time when the protocol is dynamically switched from
|
||||
@@ -205,40 +218,199 @@ static ssize_t send_callback(nghttp2_session *h2,
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
/* We pass a pointer to this struct in the push callback, but the contents of
|
||||
the struct are hidden from the user. */
|
||||
struct curl_pushheaders {
|
||||
struct SessionHandle *data;
|
||||
const nghttp2_push_promise *frame;
|
||||
};
|
||||
|
||||
/*
|
||||
* push header access function. Only to be used from within the push callback
|
||||
*/
|
||||
char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
|
||||
{
|
||||
/* Verify that we got a good easy handle in the push header struct, mostly to
|
||||
detect rubbish input fast(er). */
|
||||
if(!h || !GOOD_EASY_HANDLE(h->data))
|
||||
return NULL;
|
||||
else {
|
||||
struct HTTP *stream = h->data->req.protop;
|
||||
if(num < stream->push_headers_used)
|
||||
return stream->push_headers[num];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* push header access function. Only to be used from within the push callback
|
||||
*/
|
||||
char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
|
||||
{
|
||||
/* Verify that we got a good easy handle in the push header struct,
|
||||
mostly to detect rubbish input fast(er). Also empty header name
|
||||
is just a rubbish too. We have to allow ":" at the beginning of
|
||||
the header, but header == ":" must be rejected. If we have ':' in
|
||||
the middle of header, it could be matched in middle of the value,
|
||||
this is because we do prefix match.*/
|
||||
if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
|
||||
Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
|
||||
return NULL;
|
||||
else {
|
||||
struct HTTP *stream = h->data->req.protop;
|
||||
size_t len = strlen(header);
|
||||
size_t i;
|
||||
for(i=0; i<stream->push_headers_used; i++) {
|
||||
if(!strncmp(header, stream->push_headers[i], len)) {
|
||||
/* sub-match, make sure that it us followed by a colon */
|
||||
if(stream->push_headers[i][len] != ':')
|
||||
continue;
|
||||
return &stream->push_headers[i][len+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CURL *duphandle(struct SessionHandle *data)
|
||||
{
|
||||
struct SessionHandle *second = curl_easy_duphandle(data);
|
||||
if(second) {
|
||||
/* setup the request struct */
|
||||
struct HTTP *http = calloc(1, sizeof(struct HTTP));
|
||||
if(!http) {
|
||||
(void)Curl_close(second);
|
||||
second = NULL;
|
||||
}
|
||||
else {
|
||||
second->req.protop = http;
|
||||
http->header_recvbuf = Curl_add_buffer_init();
|
||||
if(!http->header_recvbuf) {
|
||||
free(http);
|
||||
(void)Curl_close(second);
|
||||
second = NULL;
|
||||
}
|
||||
else
|
||||
Curl_http2_setup_req(second);
|
||||
}
|
||||
}
|
||||
return second;
|
||||
}
|
||||
|
||||
|
||||
static int push_promise(struct SessionHandle *data,
|
||||
struct connectdata *conn,
|
||||
const nghttp2_push_promise *frame)
|
||||
{
|
||||
int rv;
|
||||
DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
struct HTTP *stream;
|
||||
struct curl_pushheaders heads;
|
||||
CURLMcode rc;
|
||||
struct http_conn *httpc;
|
||||
size_t i;
|
||||
/* clone the parent */
|
||||
CURL *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
rv = 1; /* FAIL HARD */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
heads.data = data;
|
||||
heads.frame = frame;
|
||||
/* ask the application */
|
||||
DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
|
||||
|
||||
stream = data->req.protop;
|
||||
if(!stream) {
|
||||
failf(data, "Internal NULL stream!\n");
|
||||
rv = 1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rv = data->multi->push_cb(data, newhandle,
|
||||
stream->push_headers_used, &heads,
|
||||
data->multi->push_userp);
|
||||
|
||||
/* free the headers again */
|
||||
for(i=0; i<stream->push_headers_used; i++)
|
||||
free(stream->push_headers[i]);
|
||||
free(stream->push_headers);
|
||||
stream->push_headers = NULL;
|
||||
|
||||
if(rv) {
|
||||
/* denied, kill off the new handle again */
|
||||
(void)Curl_close(newhandle);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* approved, add to the multi handle and immediately switch to PERFORM
|
||||
state with the given connection !*/
|
||||
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
||||
if(rc) {
|
||||
infof(data, "failed to add handle to multi\n");
|
||||
Curl_close(newhandle);
|
||||
rv = 1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
httpc = &conn->proto.httpc;
|
||||
nghttp2_session_set_stream_user_data(httpc->h2,
|
||||
frame->promised_stream_id, newhandle);
|
||||
}
|
||||
else {
|
||||
DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
|
||||
rv = 1;
|
||||
}
|
||||
fail:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct connectdata *conn = NULL;
|
||||
struct http_conn *httpc = NULL;
|
||||
struct SessionHandle *data_s = NULL;
|
||||
struct HTTP *stream = NULL;
|
||||
static int lastStream = -1;
|
||||
int rv;
|
||||
size_t left, ncopy;
|
||||
int32_t stream_id = frame->hd.stream_id;
|
||||
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data, "on_frame_recv() header %x stream %x\n",
|
||||
(void)userp;
|
||||
|
||||
if(!stream_id) {
|
||||
/* stream ID zero is for connection-oriented stuff */
|
||||
return 0;
|
||||
}
|
||||
data_s = nghttp2_session_get_stream_user_data(session,
|
||||
frame->hd.stream_id);
|
||||
if(lastStream != frame->hd.stream_id) {
|
||||
lastStream = frame->hd.stream_id;
|
||||
}
|
||||
if(!data_s) {
|
||||
DEBUGF(infof(conn->data,
|
||||
"No SessionHandle associated with stream: %x\n",
|
||||
stream_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
|
||||
frame->hd.type, stream_id));
|
||||
|
||||
if(stream_id) {
|
||||
/* get the stream from the hash based on Stream ID, stream ID zero is for
|
||||
connection-oriented stuff */
|
||||
data_s = Curl_hash_pick(&httpc->streamsh, &stream_id,
|
||||
sizeof(stream_id));
|
||||
if(!data_s) {
|
||||
/* Receiving a Stream ID not in the hash should not happen, this is an
|
||||
internal error more than anything else! */
|
||||
failf(conn->data, "Received frame on Stream ID: %x not in stream hash!",
|
||||
stream_id);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
stream = data_s->req.protop;
|
||||
}
|
||||
else
|
||||
/* we do nothing on stream zero */
|
||||
return 0;
|
||||
|
||||
conn = data_s->easy_conn;
|
||||
assert(conn);
|
||||
assert(conn->data == data_s);
|
||||
httpc = &conn->proto.httpc;
|
||||
switch(frame->hd.type) {
|
||||
case NGHTTP2_DATA:
|
||||
/* If body started on this stream, then receiving DATA is illegal. */
|
||||
@@ -292,12 +464,14 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
Curl_expire(data_s, 1);
|
||||
break;
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
DEBUGF(infof(data_s, "Got PUSH_PROMISE, RST_STREAM it!\n"));
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_CANCEL);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
rv = push_promise(data_s, conn, &frame->push_promise);
|
||||
if(rv) { /* deny! */
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_CANCEL);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NGHTTP2_SETTINGS:
|
||||
@@ -334,12 +508,15 @@ static int on_invalid_frame_recv(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
int lib_error_code, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data,
|
||||
"on_invalid_frame_recv() was called, error=%d:%s\n",
|
||||
lib_error_code, nghttp2_strerror(lib_error_code)));
|
||||
struct SessionHandle *data_s = NULL;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
DEBUGF(infof(data_s,
|
||||
"on_invalid_frame_recv() was called, error=%d:%s\n",
|
||||
lib_error_code, nghttp2_strerror(lib_error_code)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -347,29 +524,26 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
const uint8_t *data, size_t len, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct HTTP *stream;
|
||||
struct SessionHandle *data_s;
|
||||
size_t nread;
|
||||
(void)session;
|
||||
(void)flags;
|
||||
(void)data;
|
||||
DEBUGF(infof(conn->data, "on_data_chunk_recv() "
|
||||
"len = %u, stream %u\n", len, stream_id));
|
||||
(void)userp;
|
||||
|
||||
DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
|
||||
|
||||
/* get the stream from the hash based on Stream ID */
|
||||
data_s = Curl_hash_pick(&conn->proto.httpc.streamsh, &stream_id,
|
||||
sizeof(stream_id));
|
||||
if(!data_s) {
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s)
|
||||
/* Receiving a Stream ID not in the hash should not happen, this is an
|
||||
internal error more than anything else! */
|
||||
failf(conn->data, "Received frame on Stream ID: %x not in stream hash!",
|
||||
stream_id);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
nread = MIN(stream->len, len);
|
||||
memcpy(&stream->mem[stream->memlen], data, nread);
|
||||
@@ -393,7 +567,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
|
||||
", stream %u\n",
|
||||
len - nread, stream_id));
|
||||
conn->proto.httpc.pause_stream_id = stream_id;
|
||||
data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
|
||||
return NGHTTP2_ERR_PAUSE;
|
||||
}
|
||||
return 0;
|
||||
@@ -403,69 +577,75 @@ static int before_frame_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data, "before_frame_send() was called\n"));
|
||||
struct SessionHandle *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
DEBUGF(infof(data_s, "before_frame_send() was called\n"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int on_frame_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data, "on_frame_send() was called, length = %zd\n",
|
||||
frame->hd.length));
|
||||
struct SessionHandle *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
|
||||
frame->hd.length));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int on_frame_not_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
int lib_error_code, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data,
|
||||
"on_frame_not_send() was called, lib_error_code = %d\n",
|
||||
lib_error_code));
|
||||
struct SessionHandle *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
DEBUGF(infof(data_s,
|
||||
"on_frame_not_send() was called, lib_error_code = %d\n",
|
||||
lib_error_code));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
uint32_t error_code, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct SessionHandle *data_s;
|
||||
struct HTTP *stream;
|
||||
(void)session;
|
||||
(void)stream_id;
|
||||
DEBUGF(infof(conn->data, "on_stream_close(), error_code = %d, stream %u\n",
|
||||
error_code, stream_id));
|
||||
(void)userp;
|
||||
|
||||
if(stream_id) {
|
||||
/* get the stream from the hash based on Stream ID, stream ID zero is for
|
||||
connection-oriented stuff */
|
||||
data_s = Curl_hash_pick(&conn->proto.httpc.streamsh, &stream_id,
|
||||
sizeof(stream_id));
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s) {
|
||||
/* We could get stream ID not in the hash. For example, if we
|
||||
decided to reject stream (e.g., PUSH_PROMISE). We call infof
|
||||
as a debugging purpose for now. */
|
||||
infof(conn->data,
|
||||
"Received frame on Stream ID: %x not in stream hash!\n",
|
||||
stream_id);
|
||||
decided to reject stream (e.g., PUSH_PROMISE). */
|
||||
return 0;
|
||||
}
|
||||
DEBUGF(infof(data_s, "on_stream_close(), error_code = %d, stream %u\n",
|
||||
error_code, stream_id));
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
stream->error_code = error_code;
|
||||
stream->closed = TRUE;
|
||||
|
||||
/* remove the entry from the hash as the stream is now gone */
|
||||
Curl_hash_delete(&conn->proto.httpc.streamsh,
|
||||
&stream_id, sizeof(stream_id));
|
||||
DEBUGF(infof(conn->data, "Removed stream %u hash!\n", stream_id));
|
||||
nghttp2_session_set_stream_user_data(session, stream_id, 0);
|
||||
DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -473,10 +653,13 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
static int on_begin_headers(nghttp2_session *session,
|
||||
const nghttp2_frame *frame, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)frame;
|
||||
DEBUGF(infof(conn->data, "on_begin_headers() was called\n"));
|
||||
struct SessionHandle *data_s = NULL;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -514,39 +697,63 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
uint8_t flags,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct HTTP *stream;
|
||||
struct SessionHandle *data_s;
|
||||
int32_t stream_id = frame->hd.stream_id;
|
||||
|
||||
(void)session;
|
||||
(void)frame;
|
||||
(void)flags;
|
||||
|
||||
/* Ignore PUSH_PROMISE for now */
|
||||
if(frame->hd.type != NGHTTP2_HEADERS) {
|
||||
return 0;
|
||||
}
|
||||
(void)userp;
|
||||
|
||||
DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
|
||||
|
||||
/* get the stream from the hash based on Stream ID */
|
||||
data_s = Curl_hash_pick(&conn->proto.httpc.streamsh, &stream_id,
|
||||
sizeof(stream_id));
|
||||
if(!data_s) {
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s)
|
||||
/* Receiving a Stream ID not in the hash should not happen, this is an
|
||||
internal error more than anything else! */
|
||||
failf(conn->data, "Received frame on Stream ID: %x not in stream hash!",
|
||||
stream_id);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream) {
|
||||
failf(data_s, "Internal NULL stream! 5\n");
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
stream = data_s->req.protop;
|
||||
|
||||
if(stream->bodystarted)
|
||||
/* Ignore trailer or HEADERS not mapped to HTTP semantics. The
|
||||
consequence is handled in on_frame_recv(). */
|
||||
return 0;
|
||||
|
||||
/* Store received PUSH_PROMISE headers to be used when the subsequent
|
||||
PUSH_PROMISE callback comes */
|
||||
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||
char *h;
|
||||
|
||||
if(!stream->push_headers) {
|
||||
stream->push_headers_alloc = 10;
|
||||
stream->push_headers = malloc(stream->push_headers_alloc *
|
||||
sizeof(char *));
|
||||
stream->push_headers_used = 0;
|
||||
}
|
||||
else if(stream->push_headers_used ==
|
||||
stream->push_headers_alloc) {
|
||||
char **headp;
|
||||
stream->push_headers_alloc *= 2;
|
||||
headp = realloc(stream->push_headers,
|
||||
stream->push_headers_alloc * sizeof(char *));
|
||||
if(!headp) {
|
||||
free(stream->push_headers);
|
||||
stream->push_headers = NULL;
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
stream->push_headers = headp;
|
||||
}
|
||||
h = aprintf("%s:%s", name, value);
|
||||
if(h)
|
||||
stream->push_headers[stream->push_headers_used++] = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(namelen == sizeof(":status") - 1 &&
|
||||
memcmp(":status", name, namelen) == 0) {
|
||||
/* nghttp2 guarantees :status is received first and only once, and
|
||||
@@ -589,31 +796,27 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
nghttp2_data_source *source,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
struct SessionHandle *data_s;
|
||||
struct HTTP *stream = NULL;
|
||||
size_t nread;
|
||||
(void)session;
|
||||
(void)stream_id;
|
||||
(void)source;
|
||||
(void)userp;
|
||||
|
||||
if(stream_id) {
|
||||
/* get the stream from the hash based on Stream ID, stream ID zero is for
|
||||
connection-oriented stuff */
|
||||
data_s = Curl_hash_pick(&c->streamsh, &stream_id, sizeof(stream_id));
|
||||
if(!data_s) {
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(!data_s)
|
||||
/* Receiving a Stream ID not in the hash should not happen, this is an
|
||||
internal error more than anything else! */
|
||||
failf(conn->data, "Asked for data to stream %u not in hash!", stream_id);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
else {
|
||||
failf(conn->data, "nghttp2 confusion");
|
||||
else
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
nread = MIN(stream->upload_len, length);
|
||||
if(nread > 0) {
|
||||
@@ -645,11 +848,6 @@ static nghttp2_settings_entry settings[] = {
|
||||
|
||||
#define H2_BUFSIZE 32768
|
||||
|
||||
static void freestreamentry(void *freethis)
|
||||
{
|
||||
(void)freethis;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize nghttp2 for a Curl connection
|
||||
*/
|
||||
@@ -709,8 +907,6 @@ CURLcode Curl_http2_init(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
|
||||
rc = Curl_hash_init(&conn->proto.httpc.streamsh, 7, Curl_hash_str,
|
||||
Curl_str_key_compare, freestreamentry);
|
||||
if(rc) {
|
||||
failf(conn->data, "Couldn't init stream hash!");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
@@ -1065,6 +1261,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
/* Extract :method, :path from request line */
|
||||
end = strchr(hdbuf, ' ');
|
||||
if(!end)
|
||||
goto fail;
|
||||
nva[0].name = (unsigned char *)":method";
|
||||
nva[0].namelen = (uint16_t)strlen((char *)nva[0].name);
|
||||
nva[0].value = (unsigned char *)hdbuf;
|
||||
@@ -1074,6 +1272,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
hdbuf = end + 1;
|
||||
|
||||
end = strchr(hdbuf, ' ');
|
||||
if(!end)
|
||||
goto fail;
|
||||
nva[1].name = (unsigned char *)":path";
|
||||
nva[1].namelen = (uint16_t)strlen((char *)nva[1].name);
|
||||
nva[1].value = (unsigned char *)hdbuf;
|
||||
@@ -1090,13 +1290,16 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nva[2].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
|
||||
hdbuf = strchr(hdbuf, 0x0a);
|
||||
if(!hdbuf)
|
||||
goto fail;
|
||||
++hdbuf;
|
||||
|
||||
authority_idx = 0;
|
||||
|
||||
for(i = 3; i < nheader; ++i) {
|
||||
end = strchr(hdbuf, ':');
|
||||
assert(end);
|
||||
if(!end)
|
||||
goto fail;
|
||||
if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = (unsigned char *)":authority";
|
||||
@@ -1109,7 +1312,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
hdbuf = end + 1;
|
||||
for(; *hdbuf == ' '; ++hdbuf);
|
||||
end = strchr(hdbuf, 0x0d);
|
||||
assert(end);
|
||||
if(!end)
|
||||
goto fail;
|
||||
nva[i].value = (unsigned char *)hdbuf;
|
||||
nva[i].valuelen = (uint16_t)(end - hdbuf);
|
||||
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
@@ -1149,14 +1353,14 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
data_prd.read_callback = data_source_read_callback;
|
||||
data_prd.source.ptr = NULL;
|
||||
stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
|
||||
&data_prd, NULL);
|
||||
&data_prd, conn->data);
|
||||
break;
|
||||
default:
|
||||
stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
|
||||
NULL, NULL);
|
||||
NULL, conn->data);
|
||||
}
|
||||
|
||||
free(nva);
|
||||
Curl_safefree(nva);
|
||||
|
||||
if(stream_id < 0) {
|
||||
DEBUGF(infof(conn->data, "http2_send() send error\n"));
|
||||
@@ -1168,14 +1372,6 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
stream_id, conn->data);
|
||||
stream->stream_id = stream_id;
|
||||
|
||||
/* put the SessionHandle in the hash with the stream_id as key */
|
||||
if(!Curl_hash_add(&httpc->streamsh, &stream->stream_id, sizeof(stream_id),
|
||||
conn->data)) {
|
||||
failf(conn->data, "Couldn't add stream to hash!");
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = nghttp2_session_send(h2);
|
||||
|
||||
if(rv != 0) {
|
||||
@@ -1196,6 +1392,11 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
fail:
|
||||
free(nva);
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
@@ -1273,12 +1474,9 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
|
||||
/* put the SessionHandle in the hash with the stream->stream_id as key */
|
||||
if(!Curl_hash_add(&httpc->streamsh, &stream->stream_id,
|
||||
sizeof(stream->stream_id), conn->data)) {
|
||||
failf(conn->data, "Couldn't add stream to hash!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
nghttp2_session_set_stream_user_data(httpc->h2,
|
||||
stream->stream_id,
|
||||
conn->data);
|
||||
}
|
||||
else {
|
||||
/* stream ID is unknown at this point */
|
||||
@@ -1340,4 +1538,25 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
#else /* !USE_NGHTTP2 */
|
||||
|
||||
/* Satisfy external references even if http2 is not compiled in. */
|
||||
|
||||
#define CURL_DISABLE_TYPECHECK
|
||||
#include <curl/curl.h>
|
||||
|
||||
char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
|
||||
{
|
||||
(void) h;
|
||||
(void) num;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
|
||||
{
|
||||
(void) h;
|
||||
(void) header;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* USE_NGHTTP2 */
|
||||
|
||||
@@ -46,6 +46,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
const char *data, size_t nread);
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
@@ -53,6 +54,7 @@ void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup_conn(x)
|
||||
#define Curl_http2_setup_req(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
||||
@@ -218,7 +218,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
(ssize_t)piece);
|
||||
break;
|
||||
|
||||
case COMPRESS:
|
||||
default:
|
||||
failf (conn->data,
|
||||
"Unrecognized content encoding type. "
|
||||
|
||||
35
lib/multi.c
35
lib/multi.c
@@ -62,8 +62,6 @@
|
||||
|
||||
#define GOOD_MULTI_HANDLE(x) \
|
||||
((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
|
||||
#define GOOD_EASY_HANDLE(x) \
|
||||
((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
|
||||
|
||||
static void singlesocket(struct Curl_multi *multi,
|
||||
struct SessionHandle *data);
|
||||
@@ -402,11 +400,6 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
/* Point to the multi's connection cache */
|
||||
data->state.conn_cache = &multi->conn_cache;
|
||||
|
||||
if(data->set.httpreq == HTTPREQ_PUT)
|
||||
data->state.infilesize = data->set.filesize;
|
||||
else
|
||||
data->state.infilesize = data->set.postfieldsize;
|
||||
|
||||
/* This adds the new entry at the 'end' of the doubly-linked circular
|
||||
list of SessionHandle structs to try and maintain a FIFO queue so
|
||||
the pipelined requests are in order. */
|
||||
@@ -957,6 +950,28 @@ static bool multi_ischanged(struct Curl_multi *multi, bool clear)
|
||||
return retval;
|
||||
}
|
||||
|
||||
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||
struct SessionHandle *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_add_handle(multi, data);
|
||||
if(!rc) {
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
/* pass in NULL for 'conn' here since we don't want to init the
|
||||
connection, only this transfer */
|
||||
Curl_init_do(data, NULL);
|
||||
|
||||
/* take this handle to the perform state right away */
|
||||
multistate(data, CURLM_STATE_PERFORM);
|
||||
data->easy_conn = conn;
|
||||
k->keepon |= KEEP_RECV; /* setup to receive! */
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct timeval now,
|
||||
struct SessionHandle *data)
|
||||
@@ -2346,6 +2361,12 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
case CURLMOPT_SOCKETDATA:
|
||||
multi->socket_userp = va_arg(param, void *);
|
||||
break;
|
||||
case CURLMOPT_PUSHFUNCTION:
|
||||
multi->push_cb = va_arg(param, curl_push_callback);
|
||||
break;
|
||||
case CURLMOPT_PUSHDATA:
|
||||
multi->push_userp = va_arg(param, void *);
|
||||
break;
|
||||
case CURLMOPT_PIPELINING:
|
||||
multi->pipelining = va_arg(param, long);
|
||||
break;
|
||||
|
||||
@@ -87,6 +87,10 @@ struct Curl_multi {
|
||||
curl_socket_callback socket_cb;
|
||||
void *socket_userp;
|
||||
|
||||
/* callback function and user data pointer for server push */
|
||||
curl_push_callback push_cb;
|
||||
void *push_userp;
|
||||
|
||||
/* Hostname cache */
|
||||
struct curl_hash hostcache;
|
||||
|
||||
|
||||
@@ -88,4 +88,10 @@ void Curl_multi_connchanged(struct Curl_multi *multi);
|
||||
|
||||
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
|
||||
|
||||
/*
|
||||
* Add a handle and move it into PERFORM state at once. For pushed streams.
|
||||
*/
|
||||
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||
struct SessionHandle *data,
|
||||
struct connectdata *conn);
|
||||
#endif /* HEADER_CURL_MULTIIF_H */
|
||||
|
||||
@@ -249,6 +249,9 @@ char * unix_path;
|
||||
#define MD5_Init MD5_INIT
|
||||
#define MD5_Update MD5_UPDATE
|
||||
#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
|
||||
#ifndef __VAX
|
||||
#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
|
||||
#endif
|
||||
#define PEM_read_X509 PEM_READ_X509
|
||||
#define PEM_write_bio_X509 PEM_WRITE_BIO_X509
|
||||
#define PKCS12_PBE_add PKCS12_PBE_ADD
|
||||
@@ -272,6 +275,7 @@ char * unix_path;
|
||||
#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
|
||||
#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
|
||||
#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
|
||||
#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
|
||||
#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
|
||||
#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
|
||||
#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
|
||||
@@ -301,6 +305,7 @@ char * unix_path;
|
||||
#define SSL_set_fd SSL_SET_FD
|
||||
#define SSL_set_session SSL_SET_SESSION
|
||||
#define SSL_shutdown SSL_SHUTDOWN
|
||||
#define SSL_version SSL_VERSION
|
||||
#define SSL_write SSL_WRITE
|
||||
#define SSLeay SSLEAY
|
||||
#define SSLv23_client_method SSLV23_CLIENT_METHOD
|
||||
@@ -325,6 +330,7 @@ char * unix_path;
|
||||
#define UI_set_result UI_SET_RESULT
|
||||
#define X509V3_EXT_print X509V3_EXT_PRINT
|
||||
#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
|
||||
#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
|
||||
#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
|
||||
#define X509_LOOKUP_file X509_LOOKUP_FILE
|
||||
#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
|
||||
@@ -349,6 +355,12 @@ char * unix_path;
|
||||
#define sk_pop SK_POP
|
||||
#define sk_pop_free SK_POP_FREE
|
||||
#define sk_value SK_VALUE
|
||||
#ifdef __VAX
|
||||
#define OPENSSL_NO_SHA256
|
||||
#endif
|
||||
#define SHA256_Final SHA256_FINAL
|
||||
#define SHA256_Init SHA256_INIT
|
||||
#define SHA256_Update SHA256_UPDATE
|
||||
|
||||
#define USE_UPPERCASE_GSSAPI 1
|
||||
#define gss_seal GSS_SEAL
|
||||
|
||||
13
lib/ssh.c
13
lib/ssh.c
@@ -935,6 +935,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_HOST_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1019,11 +1020,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->sshagent_identity);
|
||||
|
||||
if(rc < 0) {
|
||||
if(rc != LIBSSH2_ERROR_EAGAIN) {
|
||||
if(rc != LIBSSH2_ERROR_EAGAIN)
|
||||
/* tried and failed? go to next identity */
|
||||
sshc->sshagent_prev_identity = sshc->sshagent_identity;
|
||||
}
|
||||
break;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,8 +1038,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
infof(data, "Agent based authentication successful\n");
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
}
|
||||
else
|
||||
else {
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -2141,7 +2144,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
/* from is relative to end of file */
|
||||
from += size;
|
||||
}
|
||||
if(from >= size) {
|
||||
if(from > size) {
|
||||
failf(data, "Offset (%"
|
||||
CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
|
||||
CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
|
||||
|
||||
@@ -824,6 +824,9 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
||||
case SEC_E_OK:
|
||||
txt = "No error";
|
||||
break;
|
||||
case CRYPT_E_REVOKED:
|
||||
txt = "CRYPT_E_REVOKED";
|
||||
break;
|
||||
case SEC_E_ALGORITHM_MISMATCH:
|
||||
txt = "SEC_E_ALGORITHM_MISMATCH";
|
||||
break;
|
||||
|
||||
@@ -756,7 +756,6 @@ static CURLcode readwrite_data(struct SessionHandle *data,
|
||||
result = Curl_unencode_gzip_write(conn, k, nread);
|
||||
break;
|
||||
|
||||
case COMPRESS:
|
||||
default:
|
||||
failf (data, "Unrecognized content encoding type. "
|
||||
"libcurl understands `identity', `deflate' and `gzip' "
|
||||
@@ -1315,6 +1314,11 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
Curl_safefree(data->info.wouldredirect);
|
||||
data->info.wouldredirect = NULL;
|
||||
|
||||
if(data->set.httpreq == HTTPREQ_PUT)
|
||||
data->state.infilesize = data->set.filesize;
|
||||
else
|
||||
data->state.infilesize = data->set.postfieldsize;
|
||||
|
||||
/* If there is a list of cookie files to read, do it now! */
|
||||
if(data->change.cookielist)
|
||||
Curl_cookie_loadfiles(data);
|
||||
|
||||
24
lib/url.c
24
lib/url.c
@@ -142,7 +142,6 @@ find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
|
||||
struct connectbundle *bundle);
|
||||
static void conn_free(struct connectdata *conn);
|
||||
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
|
||||
static CURLcode do_init(struct connectdata *conn);
|
||||
static CURLcode parse_url_login(struct SessionHandle *data,
|
||||
struct connectdata *conn,
|
||||
char **userptr, char **passwdptr,
|
||||
@@ -2235,7 +2234,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
|
||||
case CURLOPT_SSL_OPTIONS:
|
||||
arg = va_arg(param, long);
|
||||
data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
|
||||
data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
|
||||
data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
|
||||
break;
|
||||
|
||||
#endif
|
||||
@@ -5651,7 +5651,7 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
/* since we skip do_init() */
|
||||
do_init(conn);
|
||||
Curl_init_do(data, conn);
|
||||
|
||||
goto out;
|
||||
}
|
||||
@@ -5830,7 +5830,7 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
conn->inuse = TRUE;
|
||||
|
||||
/* Setup and init stuff before DO starts, in preparing for the transfer. */
|
||||
do_init(conn);
|
||||
Curl_init_do(data, conn);
|
||||
|
||||
/*
|
||||
* Setup whatever necessary for a resumed transfer
|
||||
@@ -6112,20 +6112,24 @@ CURLcode Curl_done(struct connectdata **connp,
|
||||
}
|
||||
|
||||
/*
|
||||
* do_init() inits the readwrite session. This is inited each time (in the DO
|
||||
* function before the protocol-specific DO functions are invoked) for a
|
||||
* transfer, sometimes multiple times on the same SessionHandle. Make sure
|
||||
* Curl_init_do() inits the readwrite session. This is inited each time (in
|
||||
* the DO function before the protocol-specific DO functions are invoked) for
|
||||
* a transfer, sometimes multiple times on the same SessionHandle. Make sure
|
||||
* nothing in here depends on stuff that are setup dynamically for the
|
||||
* transfer.
|
||||
*
|
||||
* Allow this function to get called with 'conn' set to NULL.
|
||||
*/
|
||||
|
||||
static CURLcode do_init(struct connectdata *conn)
|
||||
CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
if(conn)
|
||||
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
|
||||
* use */
|
||||
|
||||
data->state.done = FALSE; /* Curl_done() is not called yet */
|
||||
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
|
||||
data->state.expect100header = FALSE;
|
||||
|
||||
if(data->set.opt_no_body)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -27,6 +27,7 @@
|
||||
* Prototypes for library-wide functions provided by url.c
|
||||
*/
|
||||
|
||||
CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn);
|
||||
CURLcode Curl_open(struct SessionHandle **curl);
|
||||
CURLcode Curl_init_userdefined(struct UserDefined *set);
|
||||
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
|
||||
@@ -198,6 +198,8 @@
|
||||
#define HEADERSIZE 256
|
||||
|
||||
#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
|
||||
#define GOOD_EASY_HANDLE(x) \
|
||||
((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
|
||||
|
||||
/* Some convenience macros to get the larger/smaller value out of two given.
|
||||
We prefix with CURL to prevent name collisions. */
|
||||
@@ -658,7 +660,6 @@ struct SingleRequest {
|
||||
#define IDENTITY 0 /* No encoding */
|
||||
#define DEFLATE 1 /* zlib deflate [RFC 1950 & 1951] */
|
||||
#define GZIP 2 /* gzip algorithm [RFC 1952] */
|
||||
#define COMPRESS 3 /* Not handled, added for completeness */
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
zlibInitState zlib_init; /* possible zlib init state;
|
||||
@@ -1580,6 +1581,7 @@ struct UserDefined {
|
||||
bool connect_only; /* make connection, let application use the socket */
|
||||
bool ssl_enable_beast; /* especially allow this flaw for interoperability's
|
||||
sake*/
|
||||
bool ssl_no_revoke; /* disable SSL certificate revocation checks */
|
||||
long ssh_auth_types; /* allowed SSH auth types */
|
||||
bool http_te_skip; /* pass the raw body data to the user, even when
|
||||
transfer-encoded (chunked, compressed) */
|
||||
|
||||
@@ -67,6 +67,7 @@ and that's a problem since options.h hasn't been included yet. */
|
||||
#include <cyassl/error.h>
|
||||
#endif
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -770,4 +771,16 @@ int Curl_cyassl_random(struct SessionHandle *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum /* output */,
|
||||
size_t unused)
|
||||
{
|
||||
Sha256 SHA256pw;
|
||||
(void)unused;
|
||||
InitSha256(&SHA256pw);
|
||||
Sha256Update(&SHA256pw, tmp, tmplen);
|
||||
Sha256Final(&SHA256pw, sha256sum);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,10 @@ CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
|
||||
int Curl_cyassl_random(struct SessionHandle *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t unused);
|
||||
|
||||
/* Set the API backend definition to Schannel */
|
||||
#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
|
||||
@@ -65,6 +69,7 @@ int Curl_cyassl_random(struct SessionHandle *data,
|
||||
#define curlssl_check_cxn(x) ((void)x, -1)
|
||||
#define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y)
|
||||
#define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z)
|
||||
#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d)
|
||||
|
||||
#endif /* USE_CYASSL */
|
||||
#endif /* HEADER_CURL_CYASSL_H */
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#ifdef USE_GNUTLS_NETTLE
|
||||
#include <gnutls/crypto.h>
|
||||
#include <nettle/md5.h>
|
||||
#include <nettle/sha2.h>
|
||||
#else
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
@@ -1557,6 +1558,25 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
|
||||
#endif
|
||||
}
|
||||
|
||||
void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t sha256len)
|
||||
{
|
||||
#if defined(USE_GNUTLS_NETTLE)
|
||||
struct sha256_ctx SHA256pw;
|
||||
sha256_init(&SHA256pw);
|
||||
sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
|
||||
sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_md_hd_t SHA256pw;
|
||||
gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
|
||||
gcry_md_write(SHA256pw, tmp, tmplen);
|
||||
memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
|
||||
gcry_md_close(SHA256pw);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Curl_gtls_cert_status_request(void)
|
||||
{
|
||||
#ifdef HAS_OCSP
|
||||
|
||||
@@ -48,6 +48,10 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *md5sum, /* output */
|
||||
size_t md5len);
|
||||
void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t sha256len);
|
||||
|
||||
bool Curl_gtls_cert_status_request(void);
|
||||
|
||||
@@ -77,6 +81,7 @@ bool Curl_gtls_cert_status_request(void);
|
||||
#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
|
||||
#define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
|
||||
#define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
|
||||
#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
|
||||
#define curlssl_cert_status_request() Curl_gtls_cert_status_request()
|
||||
|
||||
#endif /* USE_GNUTLS */
|
||||
|
||||
@@ -2041,6 +2041,19 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
|
||||
PK11_DestroyContext(MD5pw, PR_TRUE);
|
||||
}
|
||||
|
||||
void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t sha256len)
|
||||
{
|
||||
PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
|
||||
unsigned int SHA256out;
|
||||
|
||||
PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
|
||||
PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
|
||||
PK11_DestroyContext(SHA256pw, PR_TRUE);
|
||||
}
|
||||
|
||||
bool Curl_nss_cert_status_request(void)
|
||||
{
|
||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||
|
||||
@@ -56,6 +56,11 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
|
||||
unsigned char *md5sum, /* output */
|
||||
size_t md5len);
|
||||
|
||||
void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t sha256len);
|
||||
|
||||
bool Curl_nss_cert_status_request(void);
|
||||
|
||||
bool Curl_nss_false_start(void);
|
||||
@@ -89,6 +94,7 @@ bool Curl_nss_false_start(void);
|
||||
#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
|
||||
#define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
|
||||
#define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
|
||||
#define curlssl_sha256sum(a,b,c,d) Curl_nss_sha256sum(a,b,c,d)
|
||||
#define curlssl_cert_status_request() Curl_nss_cert_status_request()
|
||||
#define curlssl_false_start() Curl_nss_false_start()
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
#include <openssl/pkcs12.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BORINGSSL
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
#include <openssl/ocsp.h>
|
||||
#endif
|
||||
|
||||
@@ -136,8 +136,8 @@
|
||||
#define CONF_modules_load_file(a,b,c)
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
/* not present in BoringSSL */
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) || defined(OPENSSL_IS_BORINGSSL)
|
||||
/* not present in BoringSSL or older OpenSSL */
|
||||
#define OPENSSL_load_builtin_modules(x)
|
||||
#endif
|
||||
|
||||
@@ -1492,7 +1492,7 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
|
||||
char ssl_buf[1024];
|
||||
char unknown[32];
|
||||
int msg_type, txt_len;
|
||||
const char *verstr;
|
||||
const char *verstr = NULL;
|
||||
struct connectdata *conn = userp;
|
||||
|
||||
if(!conn || !conn->data || !conn->data->set.fdebug ||
|
||||
@@ -3183,6 +3183,20 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
|
||||
MD5_Final(md5sum, &MD5pw);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SHA256
|
||||
void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum /* output */,
|
||||
size_t unused)
|
||||
{
|
||||
SHA256_CTX SHA256pw;
|
||||
(void)unused;
|
||||
SHA256_Init(&SHA256pw);
|
||||
SHA256_Update(&SHA256pw, tmp, tmplen);
|
||||
SHA256_Final(sha256sum, &SHA256pw);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Curl_ossl_cert_status_request(void)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
|
||||
|
||||
@@ -72,6 +72,10 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *md5sum /* output */,
|
||||
size_t unused);
|
||||
void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum /* output */,
|
||||
size_t unused);
|
||||
|
||||
bool Curl_ossl_cert_status_request(void);
|
||||
|
||||
@@ -104,6 +108,9 @@ bool Curl_ossl_cert_status_request(void);
|
||||
#define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y)
|
||||
#define curlssl_random(x,y,z) Curl_ossl_random(x,y,z)
|
||||
#define curlssl_md5sum(a,b,c,d) Curl_ossl_md5sum(a,b,c,d)
|
||||
#ifndef OPENSSL_NO_SHA256
|
||||
#define curlssl_sha256sum(a,b,c,d) Curl_ossl_sha256sum(a,b,c,d)
|
||||
#endif
|
||||
#define curlssl_cert_status_request() Curl_ossl_cert_status_request()
|
||||
|
||||
#define DEFAULT_CIPHER_SELECTION \
|
||||
|
||||
@@ -128,16 +128,24 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
|
||||
#else
|
||||
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
|
||||
SCH_CRED_REVOCATION_CHECK_CHAIN;
|
||||
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
|
||||
if(data->set.ssl_no_revoke)
|
||||
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
|
||||
else
|
||||
schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
|
||||
#endif
|
||||
infof(data, "schannel: checking server certificate revocation\n");
|
||||
if(data->set.ssl_no_revoke)
|
||||
infof(data, "schannel: disabled server certificate revocation "
|
||||
"checks\n");
|
||||
else
|
||||
infof(data, "schannel: checking server certificate revocation\n");
|
||||
}
|
||||
else {
|
||||
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
|
||||
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
|
||||
infof(data, "schannel: disable server certificate revocation checks\n");
|
||||
infof(data, "schannel: disabled server certificate revocation checks\n");
|
||||
}
|
||||
|
||||
if(!data->set.ssl.verifyhost) {
|
||||
@@ -1112,12 +1120,25 @@ cleanup:
|
||||
*/
|
||||
if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
|
||||
!connssl->recv_sspi_close_notify) {
|
||||
DWORD winver_full, winver_major, winver_minor;
|
||||
winver_full = GetVersion();
|
||||
winver_major = (DWORD)(LOBYTE(LOWORD(winver_full)));
|
||||
winver_minor = (DWORD)(HIBYTE(LOWORD(winver_full)));
|
||||
BOOL isWin2k;
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
if(winver_major == 5 && winver_minor == 0 && sspi_status == SEC_E_OK)
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = 5;
|
||||
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
isWin2k = VerifyVersionInfo(&osver,
|
||||
(VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm);
|
||||
|
||||
if(isWin2k && sspi_status == SEC_E_OK)
|
||||
connssl->recv_sspi_close_notify = true;
|
||||
else {
|
||||
*err = CURLE_RECV_ERROR;
|
||||
@@ -1384,7 +1405,8 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
NULL,
|
||||
pCertContextServer->hCertStore,
|
||||
&ChainPara,
|
||||
0,
|
||||
(data->set.ssl_no_revoke ? 0 :
|
||||
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
|
||||
NULL,
|
||||
&pChainContext)) {
|
||||
failf(data, "schannel: CertGetCertificateChain failed: %s",
|
||||
@@ -1395,21 +1417,24 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(result == CURLE_OK) {
|
||||
CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
|
||||
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED|
|
||||
CERT_TRUST_REVOCATION_STATUS_UNKNOWN);
|
||||
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
|
||||
dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
|
||||
if(dwTrustErrorMask) {
|
||||
if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
|
||||
if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
|
||||
failf(data, "schannel: CertGetCertificateChain trust error"
|
||||
" CERT_TRUST_IS_REVOKED");
|
||||
else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
|
||||
failf(data, "schannel: CertGetCertificateChain trust error"
|
||||
" CERT_TRUST_IS_PARTIAL_CHAIN");
|
||||
if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
failf(data, "schannel: CertGetCertificateChain trust error"
|
||||
" CERT_TRUST_IS_UNTRUSTED_ROOT");
|
||||
if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
|
||||
else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
|
||||
failf(data, "schannel: CertGetCertificateChain trust error"
|
||||
" CERT_TRUST_IS_NOT_TIME_VALID");
|
||||
failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
|
||||
dwTrustErrorMask);
|
||||
else
|
||||
failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
|
||||
dwTrustErrorMask);
|
||||
result = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
}
|
||||
@@ -1425,6 +1450,14 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
cert_hostname.const_tchar_ptr = cert_hostname_buff;
|
||||
hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
|
||||
|
||||
/* TODO: Fix this for certificates with multiple alternative names.
|
||||
Right now we're only asking for the first preferred alternative name.
|
||||
Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
|
||||
(if WinCE supports that?) and run this section in a loop for each.
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
|
||||
curl: (51) schannel: CertGetNameString() certificate hostname
|
||||
(.google.com) did not match connection (google.com)
|
||||
*/
|
||||
len = CertGetNameString(pCertContextServer,
|
||||
CERT_NAME_DNS_TYPE,
|
||||
0,
|
||||
|
||||
@@ -774,12 +774,78 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
|
||||
size_t size, pem_len;
|
||||
CURLcode pem_read;
|
||||
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
#ifdef curlssl_sha256sum
|
||||
size_t pinkeylen;
|
||||
char *pinkeycopy, *begin_pos, *end_pos;
|
||||
unsigned char *sha256sumdigest = NULL, *expectedsha256sumdigest = NULL;
|
||||
#endif
|
||||
|
||||
/* if a path wasn't specified, don't pin */
|
||||
if(!pinnedpubkey)
|
||||
return CURLE_OK;
|
||||
if(!pubkey || !pubkeylen)
|
||||
return result;
|
||||
|
||||
#ifdef curlssl_sha256sum
|
||||
/* only do this if pinnedpubkey starts with "sha256//", length 8 */
|
||||
if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
|
||||
/* compute sha256sum of public key */
|
||||
sha256sumdigest = malloc(SHA256_DIGEST_LENGTH);
|
||||
if(!sha256sumdigest)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
curlssl_sha256sum(pubkey, pubkeylen,
|
||||
sha256sumdigest, SHA256_DIGEST_LENGTH);
|
||||
|
||||
/* it starts with sha256//, copy so we can modify it */
|
||||
pinkeylen = strlen(pinnedpubkey) + 1;
|
||||
pinkeycopy = malloc(pinkeylen);
|
||||
if(!pinkeycopy) {
|
||||
Curl_safefree(sha256sumdigest);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
|
||||
/* point begin_pos to the copy, and start extracting keys */
|
||||
begin_pos = pinkeycopy;
|
||||
do {
|
||||
end_pos = strstr(begin_pos, ";sha256//");
|
||||
/*
|
||||
* if there is an end_pos, null terminate,
|
||||
* otherwise it'll go to the end of the original string
|
||||
*/
|
||||
if(end_pos)
|
||||
end_pos[0] = '\0';
|
||||
|
||||
/* decode base64 pinnedpubkey, 8 is length of "sha256//" */
|
||||
pem_read = Curl_base64_decode(begin_pos + 8,
|
||||
&expectedsha256sumdigest, &size);
|
||||
/* if not valid base64, don't bother comparing or freeing */
|
||||
if(!pem_read) {
|
||||
/* compare sha256 digests directly */
|
||||
if(SHA256_DIGEST_LENGTH == size &&
|
||||
!memcmp(sha256sumdigest, expectedsha256sumdigest,
|
||||
SHA256_DIGEST_LENGTH)) {
|
||||
result = CURLE_OK;
|
||||
Curl_safefree(expectedsha256sumdigest);
|
||||
break;
|
||||
}
|
||||
Curl_safefree(expectedsha256sumdigest);
|
||||
}
|
||||
|
||||
/*
|
||||
* change back the null-terminator we changed earlier,
|
||||
* and look for next begin
|
||||
*/
|
||||
if(end_pos) {
|
||||
end_pos[0] = ';';
|
||||
begin_pos = strstr(end_pos, "sha256//");
|
||||
}
|
||||
} while(end_pos && begin_pos);
|
||||
Curl_safefree(sha256sumdigest);
|
||||
Curl_safefree(pinkeycopy);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
fp = fopen(pinnedpubkey, "rb");
|
||||
if(!fp)
|
||||
return result;
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
#define MD5_DIGEST_LENGTH 16 /* fixed size */
|
||||
#endif
|
||||
|
||||
#ifndef SHA256_DIGEST_LENGTH
|
||||
#define SHA256_DIGEST_LENGTH 32 /* fixed size */
|
||||
#endif
|
||||
|
||||
/* see http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
|
||||
#define ALPN_HTTP_1_1_LENGTH 8
|
||||
#define ALPN_HTTP_1_1 "http/1.1"
|
||||
|
||||
@@ -316,6 +316,42 @@ dnl AC_MSG_ERROR([options --enable-ares and --enable-threads are mutually ex
|
||||
dnl fi
|
||||
dnl ])
|
||||
|
||||
dnl CURL_CHECK_OPTION_RT
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify if configure has been involed with option
|
||||
dnl --disable-rt and set shell variable dontwant_rt
|
||||
dnl as appropriate.
|
||||
|
||||
AC_DEFUN([CURL_CHECK_OPTION_RT], [
|
||||
AC_BEFORE([$0], [CURL_CHECK_LIB_THREADS])dnl
|
||||
AC_MSG_CHECKING([whether to disable dependency on -lrt])
|
||||
OPT_RT="default"
|
||||
AC_ARG_ENABLE(rt,
|
||||
AC_HELP_STRING([--disable-rt],[disable dependency on -lrt]),
|
||||
OPT_RT=$enableval)
|
||||
case "$OPT_RT" in
|
||||
no)
|
||||
dnl --disable-rt used (reverse logic)
|
||||
dontwant_rt="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
;;
|
||||
default)
|
||||
dnl configure option not specified (so not disabled)
|
||||
dontwant_rt="no"
|
||||
AC_MSG_RESULT([(assumed no)]
|
||||
;;
|
||||
*)
|
||||
dnl --enable-rt option used (reverse logic)
|
||||
dontwant_rt="no"
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
dnl TODO: may require mutual exclusion
|
||||
if test "$dontwant_rt" = "yes" && test "$want_thres" = "yes" ; then
|
||||
AC_MSG_ERROR([options --disable-rt and --enable-thread-resolver are mutually exclusive, at most one can be selected.])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_CHECK_OPTION_WARNINGS
|
||||
dnl -------------------------------------------------
|
||||
|
||||
5
maketgz
5
maketgz
@@ -60,8 +60,9 @@ sed -e 's/^#define LIBCURL_VERSION .*/#define LIBCURL_VERSION "'$libversion'"/g'
|
||||
# Replace version number in header file:
|
||||
sed 's/#define CURL_VERSION .*/#define CURL_VERSION "'$curlversion'"/g' $CHEADER >$CHEADER.dist
|
||||
|
||||
# Generate VC8, VC9, and VC10 versions from the VC6 Makefile versions
|
||||
for ver in vc8 vc9 vc10; do
|
||||
# Generate VC7, VC8, VC9, VC10, VC11, VC12 and VC14 versions from the VC6
|
||||
# Makefile versions
|
||||
for ver in vc7 vc8 vc9 vc10 vc11 vc12 vc14; do
|
||||
make -f Makefile.dist $ver
|
||||
mv src/Makefile.$ver src/Makefile.$ver.dist
|
||||
mv lib/Makefile.$ver lib/Makefile.$ver.dist
|
||||
|
||||
@@ -148,7 +148,7 @@ parameter/array boundary.
|
||||
Please note that CURLFORM_PTRCONTENTS and CURLFORM_BUFFERPTR are considered
|
||||
unconvertible strings and thus are NOT followed by a CCSID.
|
||||
|
||||
_ curl_easy_getinfo_ccsid
|
||||
_ curl_easy_getinfo_ccsid()
|
||||
The following options are followed by a 'char * *' and a CCSID. Unlike
|
||||
curl_easy_getinfo(), the value returned in the pointer should be freed after
|
||||
use:
|
||||
@@ -169,6 +169,14 @@ CCSID. Returned structures sould be free'ed using curl_certinfo_free_all() after
|
||||
use.
|
||||
Other options are processed like in curl_easy_getinfo().
|
||||
|
||||
_ curl_pushheader_bynum_cssid() and curl_pushheader_byname_ccsid()
|
||||
Although the prototypes are self-explanatory, the returned string pointer
|
||||
should be freed after use, as opposite to the non-ccsid versions of these
|
||||
procedures.
|
||||
Please note that HTTP2 is not (yet) implemented on OS/400, thus these
|
||||
functions will always return NULL.
|
||||
|
||||
|
||||
Standard compilation environment does support neither autotools nor make;
|
||||
in fact, very few common utilities are available. As a consequence, the
|
||||
config-os400.h has been coded manually and the compilation scripts are
|
||||
@@ -265,14 +273,14 @@ _ Do not use original source include files unless you know what you are doing.
|
||||
ILE/RPG support:
|
||||
|
||||
Since 95% of the OS/400 programmers use ILE/RPG exclusively, a definition
|
||||
/COPY member is provided for this language. To include all libcurl
|
||||
/INCLUDE member is provided for this language. To include all libcurl
|
||||
definitions in an ILE/RPG module, line
|
||||
|
||||
h bnddir('CURL/CURL')
|
||||
|
||||
must figure in the program header, and line
|
||||
|
||||
d/copy curl/h,curl.inc
|
||||
d/include curl/h,curl.inc
|
||||
|
||||
in the global data section of the module's source code.
|
||||
|
||||
|
||||
@@ -1278,3 +1278,42 @@ curl_form_long_value(long value)
|
||||
|
||||
return (char *) value;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
|
||||
size_t num, unsigned int ccsid)
|
||||
|
||||
{
|
||||
char *d = (char *) NULL;
|
||||
char *s = curl_pushheader_bynum(h, num);
|
||||
|
||||
if(s)
|
||||
d = dynconvert(ccsid, s, -1, ASCII_CCSID);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
curl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header,
|
||||
unsigned int ccsidin, unsigned int ccsidout)
|
||||
|
||||
{
|
||||
char *d = (char *) NULL;
|
||||
char *s;
|
||||
|
||||
if(header) {
|
||||
header = dynconvert(ASCII_CCSID, header, -1, ccsidin);
|
||||
|
||||
if(header) {
|
||||
s = curl_pushheader_byname(h, header);
|
||||
free((char *) header);
|
||||
|
||||
if(s)
|
||||
d = dynconvert(ccsidout, s, -1, ASCII_CCSID);
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
@@ -61,5 +61,11 @@ CURL_EXTERN int curl_formget_ccsid(struct curl_httppost * form, void * arg,
|
||||
unsigned int ccsid);
|
||||
CURL_EXTERN CURLcode curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...);
|
||||
CURL_EXTERN void curl_certinfo_free_all(struct curl_certinfo *info);
|
||||
CURL_EXTERN char *curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
|
||||
size_t num, unsigned int ccsid);
|
||||
CURL_EXTERN char *curl_pushheader_byname_ccsid(struct curl_pushheaders *h,
|
||||
const char *header,
|
||||
unsigned int ccsidin,
|
||||
unsigned int ccsidout);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -221,6 +221,8 @@
|
||||
d CURL_HTTP_VERSION_1_1...
|
||||
d c 2
|
||||
d CURL_HTTP_VERSION_2_0...
|
||||
d c 3
|
||||
d CURL_HTTP_VERSION_2...
|
||||
d c 3
|
||||
*
|
||||
d CURL_NETRC_IGNORED...
|
||||
@@ -276,6 +278,9 @@
|
||||
d CURL_CSELECT_ERR...
|
||||
d c X'00000004'
|
||||
*
|
||||
d CURL_PUSH_OK c 0
|
||||
d CURL_PUSH_DENY c 1
|
||||
*
|
||||
d CURLPAUSE_RECV c X'00000001'
|
||||
d CURLPAUSE_RECV_CONT...
|
||||
d c X'00000000'
|
||||
@@ -676,7 +681,9 @@
|
||||
d c 3
|
||||
*
|
||||
d CURLSSLOPT_ALLOW_BEAST...
|
||||
d c 1
|
||||
d c X'0001'
|
||||
d CURLSSLOPT_NO_REVOKE...
|
||||
d c X'0002'
|
||||
*
|
||||
/if not defined(CURL_NO_OLDIES)
|
||||
d curl_ftpssl s like(curl_usessl)
|
||||
@@ -1215,6 +1222,8 @@
|
||||
d c 10235
|
||||
d CURLOPT_SERVICE_NAME...
|
||||
d c 10236
|
||||
d CURLOPT_PIPEWAIT...
|
||||
d c 00237
|
||||
*
|
||||
/if not defined(CURL_NO_OLDIES)
|
||||
d CURLOPT_FILE c 10001
|
||||
@@ -1573,6 +1582,18 @@
|
||||
d c 10012
|
||||
d CURLMOPT_MAX_TOTAL_CONNECTIONS...
|
||||
d c 00013
|
||||
d CURLMOPT_PUSHFUNCTION...
|
||||
d c 20014
|
||||
d CURLMOPT_PUSHDATA...
|
||||
d c 10015
|
||||
*
|
||||
* Bitmask bits for CURLMOPT_PIPELING.
|
||||
*
|
||||
d CURLPIPE_NOTHING...
|
||||
d c x'00000000'
|
||||
d CURLPIPE_HTTP1 c x'00000001'
|
||||
d CURLPIPE_MULTIPLEX...
|
||||
d c x'00000002'
|
||||
*
|
||||
* Public API enums for RTSP requests.
|
||||
*
|
||||
@@ -1789,6 +1810,12 @@
|
||||
d s * based(######ptr######) procptr
|
||||
*
|
||||
d curl_socket_callback...
|
||||
d s * based(######ptr######) procptr
|
||||
*
|
||||
d curl_multi_timer_callback...
|
||||
d s * based(######ptr######) procptr
|
||||
*
|
||||
d curl_push_callback...
|
||||
d s * based(######ptr######) procptr
|
||||
*
|
||||
d curl_opensocket_callback...
|
||||
@@ -2106,6 +2133,16 @@
|
||||
d pr * extproc('curl_multi_strerror') char *
|
||||
d code value like(CURLMcode)
|
||||
*
|
||||
d curl_pushheader_bynum...
|
||||
d pr * extproc('curl_pushheader_bynum') char *
|
||||
d h * value curl_pushheaders *
|
||||
d num 10u 0 value
|
||||
*
|
||||
d curl_pushheader_byname...
|
||||
d pr * extproc('curl_pushheader_byname') char *
|
||||
d h * value curl_pushheaders *
|
||||
d header * value options(*string) const char *
|
||||
*
|
||||
d curl_multi_socket...
|
||||
d pr extproc('curl_multi_socket')
|
||||
d like(CURLMcode)
|
||||
@@ -2273,4 +2310,19 @@
|
||||
d objectarg * value options(*string: *nopass)
|
||||
d ccsid 10u 0 value options(*nopass)
|
||||
*
|
||||
d curl_pushheader_bynum_ccsid...
|
||||
d pr * extproc( char *
|
||||
d 'curl_pushheader_bynum_ccsid')
|
||||
d h * value curl_pushheaders *
|
||||
d num 10u 0 value
|
||||
d ccsid 10u 0 value
|
||||
*
|
||||
d curl_pushheader_byname_ccsid...
|
||||
d pr * extproc( char *
|
||||
d 'curl_pushheader_byname_ccsid')
|
||||
d h * value curl_pushheaders *
|
||||
d header * value options(*string) const char *
|
||||
d ccsidin 10u 0 value
|
||||
d ccsidout 10u 0 value
|
||||
*
|
||||
/endif
|
||||
|
||||
@@ -21,7 +21,7 @@ fi
|
||||
# Create the DOCS source file if it does not exist.
|
||||
|
||||
if action_needed "${LIBIFSNAME}/DOCS.FILE"
|
||||
then CMD="CRTSRCPF FILE(${TARGETLIB}/DOCS) RCDLEN(112)"
|
||||
then CMD="CRTSRCPF FILE(${TARGETLIB}/DOCS) RCDLEN(240)"
|
||||
CMD="${CMD} CCSID(${TGTCCSID}) TEXT('Documentation texts')"
|
||||
system "${CMD}"
|
||||
fi
|
||||
|
||||
@@ -113,6 +113,7 @@ $! Required product dependencies.
|
||||
$!----------------------------------
|
||||
$ vmsprd = "DEC"
|
||||
$ if base .eqs. "I64VMS" then vmsprd = "HP"
|
||||
$ vsiprd = "VSI"
|
||||
$!
|
||||
$ write pdsc " software ''vmsprd' ''base' VMS ;"
|
||||
$ arch_type = f$getsyi("ARCH_NAME")
|
||||
@@ -126,8 +127,11 @@ $ if dashver .eqs. "-" then dashver = ""
|
||||
$ vmstag = majver + minver + dashver
|
||||
$ code = f$extract(0, 1, arch_type)
|
||||
$ arch_code = f$extract(0, 1, arch_type)
|
||||
$ write pdsc -
|
||||
" if (not <software ''vmsprd' ''base' VMS version minimum ''node_swvers'>) ;"
|
||||
$ line_out = -
|
||||
" if ((not <software ''vsiprd' ''base' VMS version minimum" + -
|
||||
" ''node_swvers'>) and" + -
|
||||
" (not <software ''vmsprd' ''base' VMS version minimum ''node_swvers'>));"
|
||||
$ write pdsc line_out
|
||||
$ write pdsc " error NEED_VMS''vmstag';"
|
||||
$ write pdsc " end if;"
|
||||
$!
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user