Skip to content

Commit

Permalink
Merge 0b6ff0a into 952998c
Browse files Browse the repository at this point in the history
  • Loading branch information
bagder committed Jul 16, 2019
2 parents 952998c + 0b6ff0a commit e414ba6
Show file tree
Hide file tree
Showing 33 changed files with 2,508 additions and 20 deletions.
159 changes: 159 additions & 0 deletions configure.ac
Expand Up @@ -3337,6 +3337,160 @@ if test X"$want_h2" != Xno; then

fi

dnl **********************************************************************
dnl Check for ngtcp2 (QUIC)
dnl **********************************************************************

OPT_TCP2="yes"
curl_h3_msg="disabled (--with-ngtcp2, --with-quiche)"

if test "x$disable_http" = "xyes"; then
# without HTTP, ngtcp2 is no use
OPT_TCP2="no"
fi

AC_ARG_WITH(ngtcp2,
AC_HELP_STRING([--with-ngtcp2=PATH],[Enable ngtcp2 usage])
AC_HELP_STRING([--without-ngtcp2],[Disable ngtcp2 usage]),
[OPT_TCP2=$withval])
case "$OPT_TCP2" in
no)
dnl --without-ngtcp2 option used
want_tcp2="no"
;;
yes)
dnl --with-ngtcp2 option used without path
want_tcp2="default"
want_tcp2_path=""
;;
*)
dnl --with-ngtcp2 option used with path
want_tcp2="yes"
want_tcp2_path="$withval/lib/pkgconfig"
;;
esac

curl_tcp2_msg="disabled (--with-ngtcp2)"
if test X"$want_tcp2" != Xno; then
dnl backup the pre-ngtcp2 variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEANLIBS="$LIBS"

CURL_CHECK_PKGCONFIG(libngtcp2, $want_tcp2_path)

if test "$PKGCONFIG" != "no" ; then
LIB_TCP2=`CURL_EXPORT_PCDIR([$want_tcp2_path])
$PKGCONFIG --libs-only-l libngtcp2`
AC_MSG_NOTICE([-l is $LIB_TCP2])

CPP_TCP2=`CURL_EXPORT_PCDIR([$want_tcp2_path]) dnl
$PKGCONFIG --cflags-only-I libngtcp2`
AC_MSG_NOTICE([-I is $CPP_TCP2])

LD_TCP2=`CURL_EXPORT_PCDIR([$want_tcp2_path])
$PKGCONFIG --libs-only-L libngtcp2`
AC_MSG_NOTICE([-L is $LD_TCP2])

LDFLAGS="$LDFLAGS $LD_TCP2"
CPPFLAGS="$CPPFLAGS $CPP_TCP2"
LIBS="$LIB_TCP2 $LIBS"

if test "x$cross_compiling" != "xyes"; then
DIR_TCP2=`echo $LD_TCP2 | $SED -e 's/-L//'`
fi
AC_CHECK_LIB(ngtcp2, ngtcp2_conn_client_new,
[
AC_CHECK_HEADERS(ngtcp2/ngtcp2.h,
curl_h3_msg="enabled (ngtcp2)"
NGTCP2_ENABLED=1
AC_DEFINE(USE_NGTCP2, 1, [if ngtcp2 is in use])
AC_SUBST(USE_NGTCP2, [1])
CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_TCP2"
export CURL_LIBRARY_PATH
AC_MSG_NOTICE([Added $DIR_TCP2 to CURL_LIBRARY_PATH])
)
],
dnl not found, revert back to clean variables
LDFLAGS=$CLEANLDFLAGS
CPPFLAGS=$CLEANCPPFLAGS
LIBS=$CLEANLIBS
)

else
dnl no ngtcp2 pkg-config found, deal with it
if test X"$want_tcp2" != Xdefault; then
dnl To avoid link errors, we do not allow --with-ngtcp2 without
dnl a pkgconfig file
AC_MSG_ERROR([--with-ngtcp2 was specified but could not find ngtcp2 pkg-config file.])
fi
fi

fi

dnl **********************************************************************
dnl Check for quiche (QUIC)
dnl **********************************************************************

OPT_QUICHE="yes"

if test "x$disable_http" = "xyes" -o "x$USE_NGTCP" = "x1"; then
# without HTTP or with ngtcp2, quiche is no use
OPT_QUICHE="no"
fi

AC_ARG_WITH(quiche,
AC_HELP_STRING([--with-quiche=PATH],[Enable quiche usage])
AC_HELP_STRING([--without-quiche],[Disable quiche usage]),
[OPT_QUICHE=$withval])
case "$OPT_QUICHE" in
*)
dnl --with-quiche option used without path
want_quiche="default"
want_quiche_path=""
;;
no)
dnl --without-quiche option used
want_quiche="no"
;;
esac

if test X"$want_quiche" != Xno; then
dnl backup the pre-quiche variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEANLIBS="$LIBS"

LIB_QUICHE="-lquiche -ldl -lpthread"
CPP_QUICHE="-I$OPT_QUICHE/include"
LD_QUICHE="-L$OPT_QUICHE/target/debug"

LDFLAGS="$LDFLAGS $LD_QUICHE"
CPPFLAGS="$CPPFLAGS $CPP_QUICHE"
LIBS="$LIB_QUICHE $LIBS"

if test "x$cross_compiling" != "xyes"; then
DIR_QUICHE=`echo $LD_QUICHE | $SED -e 's/-L//'`
fi
AC_CHECK_LIB(quiche, quiche_connect,
[
AC_CHECK_HEADERS(quiche.h,
curl_h3_msg="enabled (quiche)"
QUICHE_ENABLED=1
AC_DEFINE(USE_QUICHE, 1, [if quiche is in use])
AC_SUBST(USE_QUICHE, [1])
CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_QUICHE"
export CURL_LIBRARY_PATH
AC_MSG_NOTICE([Added $DIR_QUICHE to CURL_LIBRARY_PATH]),
)
],
dnl not found, revert back to clean variables
LDFLAGS=$CLEANLDFLAGS
CPPFLAGS=$CLEANCPPFLAGS
LIBS=$CLEANLIBS
)
fi

dnl **********************************************************************
dnl Check for zsh completion path
dnl **********************************************************************
Expand Down Expand Up @@ -4280,6 +4434,10 @@ if test "x$USE_NGHTTP2" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2"
fi

if test "x$USE_NGTCP2" = "x1" -o "x$USE_QUICHE" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP3"
fi

if test "x$CURL_WITH_MULTI_SSL" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES MultiSSL"
fi
Expand Down Expand Up @@ -4471,6 +4629,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
PSL: ${curl_psl_msg}
Alt-svc: ${curl_altsvc_msg}
HTTP2: ${curl_h2_msg}
HTTP3: ${curl_h3_msg}
Protocols: ${SUPPORT_PROTOCOLS}
Features: ${SUPPORT_FEATURES}
])
Expand Down
85 changes: 85 additions & 0 deletions docs/HTTP3.md
@@ -0,0 +1,85 @@
# HTTP3 (and QUIC)

## Resources

[HTTP/3 Explained](https://daniel.haxx.se/http3-explained/) - the online free
book describing the protocols involved.

[QUIC implementation](https://github.com/curl/curl/wiki/QUIC-implementation) -
the wiki page describing the plan for how to support QUIC and HTTP/3 in curl
and libcurl.

[quicwg.org](https://quicwg.org/) - home of the official protocol drafts

## QUIC libraries

QUIC libraries we're experiementing with:

[ngtcp2](https://github.com/ngtcp2/ngtcp2)

[quiche](https://github.com/ghedo/quiche)

## Experimental!

HTTP/3 and QUIC support in curl is not yet working and this is early days.
Consider all QUIC and HTTP/3 code to be **EXPERIMENTAL** until further notice.

curl does not have HTTP/3 support (yet).

The bleeding edge QUIC work is done in the dedicated
[QUIC](https://github.com/curl/curl/tree/QUIC) branch, but the plan is to
merge as often as possible from there to master. All QUIC related code will
remain being build-time conditionally enabled.

# ngtcp2 version

## Build

1. clone ngtcp2 from git (the draft-17 branch)
2. build and install ngtcp2's custom OpenSSL version (the quic-draft-17 branch)
3. build and install ngtcp2 according to its instructions
4. configure curl with ngtcp2 support: `./configure --with-ngtcp2=<install prefix>`
5. build curl "normally"

## Running

Make sure the custom OpenSSL library is the one used at run-time, as otherwise
you'll just get ld.so linker errors.

## Invoke from command line

curl --http3-direct https://nghttp2.org:8443/

# quiche version

## build

Build BoringSSL (it needs to be built manually so it can be reused with curl):

% mkdir -p quiche/deps/boringssl/build
% cd quiche/deps/boringssl/build
% cmake -DCMAKE_POSITION_INDEPENDENT_CODE=on ..
% make -j`nproc`
% cd ..
% mkdir .openssl/lib -p
% cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
% ln -s $PWD/include .openssl

Build quiche:

% cd ../..
% QUICHE_BSSL_PATH=$PWD/deps/boringssl cargo build

Clone and build curl:

% cd ..
% git clone -b quiche https://github.com/ghedo/curl
% ./buildconf
% ./configure --with-ssl=$PWD/../quiche/deps/boringssl/.openssl --with-quiche=$PWD/../quiche --enable-debug
% make -j`nproc`

## Running

Make an HTTP/1.1 request to a QUIC server:

% src/curl --http3-direct https://cloudflare-quic.com/
1 change: 1 addition & 0 deletions docs/Makefile.am
Expand Up @@ -60,6 +60,7 @@ EXTRA_DIST = \
HISTORY.md \
HTTP-COOKIES.md \
HTTP2.md \
HTTP3.md \
INSTALL \
INSTALL.cmake \
INSTALL.md \
Expand Down
1 change: 1 addition & 0 deletions docs/cmdline-opts/Makefile.inc
Expand Up @@ -65,6 +65,7 @@ DPAGES = \
http1.0.d \
http1.1.d http2.d \
http2-prior-knowledge.d \
http3-direct.d \
ignore-content-length.d \
include.d \
insecure.d \
Expand Down
14 changes: 14 additions & 0 deletions docs/cmdline-opts/http3-direct.d
@@ -0,0 +1,14 @@
Long: http3-direct
Tags: Versions
Protocols: HTTP
Added: 7.66.0
Mutexed: http1.1 http1.0 http2 http2-prior-knowledge
Requires: HTTP/3
Help: Use HTTP v3
---

Tells curl to use HTTP version 3 directly to the host and port number used in
the URL. A normal HTTP/3 transaction will be done to a host and then get
redirected via Alt-SVc, but this option allows a user to circumvent that when
you know that the target speaks HTTP/3 on the given host and port.

2 changes: 2 additions & 0 deletions docs/libcurl/curl_easy_setopt.3
Expand Up @@ -321,6 +321,8 @@ Enable and configure Alt-Svc: treatment. See \fICURLOPT_ALTSVC_CTRL(3)\fP
Do an HTTP GET request. See \fICURLOPT_HTTPGET(3)\fP
.IP CURLOPT_REQUEST_TARGET
Set the request target. \fICURLOPT_REQUEST_TARGET(3)\fP
.IP CURLOPT_H3
Specify HTTP/3 behavior. \fICURLOPT_H3(3)\fP
.IP CURLOPT_HTTP_VERSION
HTTP version to use. \fICURLOPT_HTTP_VERSION(3)\fP
.IP CURLOPT_HTTP09_ALLOWED
Expand Down
56 changes: 56 additions & 0 deletions docs/libcurl/opts/CURLOPT_H3.3
@@ -0,0 +1,56 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.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 CURLOPT_H3 3 "27 Nov 2018" "libcurl 7.64.0" "curl_easy_setopt options"
.SH NAME
CURLOPT_H3 \- specify HTTP/3 protocol behavior
.SH SYNOPSIS
#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_H3, long bitmask);
.SH DESCRIPTION
This function accepts a long \fIbitmask\fP with a set of flags set that
controls the HTTP/3 behavior for this transfer.
.IP "CURLH3_DIRECT"
If this bit is set in \fIbitmask\fP, the host name and port number given in
the URL will be used to connect to directly with QUIC and the port number then
being a UDP port number.
.SH DEFAULT
0
.SH PROTOCOLS
HTTPS
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
if(curl) {
CURLcode ret;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(curl, CURLOPT_H3, (long)CURLH3_DIRECT);
ret = curl_easy_perform(curl);
}
.fi
.SH AVAILABILITY
Added in 7.64.0
.SH RETURN VALUE
Returns CURLE_OK if supported, an error otherwise.
.SH "SEE ALSO"
.BR CURLOPT_HTTP_VERSION "(3), "
1 change: 1 addition & 0 deletions docs/libcurl/opts/Makefile.inc
Expand Up @@ -150,6 +150,7 @@ man_MANS = \
CURLOPT_FTP_USE_EPSV.3 \
CURLOPT_FTP_USE_PRET.3 \
CURLOPT_GSSAPI_DELEGATION.3 \
CURLOPT_H3.3 \
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 \
CURLOPT_HAPROXYPROTOCOL.3 \
CURLOPT_HEADER.3 \
Expand Down
3 changes: 3 additions & 0 deletions docs/libcurl/symbols-in-versions
Expand Up @@ -209,6 +209,7 @@ CURLFTP_CREATE_DIR_RETRY 7.19.4
CURLGSSAPI_DELEGATION_FLAG 7.22.0
CURLGSSAPI_DELEGATION_NONE 7.22.0
CURLGSSAPI_DELEGATION_POLICY_FLAG 7.22.0
CURLH3_DIRECT 7.64.0
CURLHEADER_SEPARATE 7.37.0
CURLHEADER_UNIFIED 7.37.0
CURLINFO_ACTIVESOCKET 7.45.0
Expand Down Expand Up @@ -424,6 +425,7 @@ CURLOPT_FTP_USE_EPRT 7.10.5
CURLOPT_FTP_USE_EPSV 7.9.2
CURLOPT_FTP_USE_PRET 7.20.0
CURLOPT_GSSAPI_DELEGATION 7.22.0
CURLOPT_H3 7.64.0
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS 7.59.0
CURLOPT_HAPROXYPROTOCOL 7.60.0
CURLOPT_HEADER 7.1
Expand Down Expand Up @@ -924,6 +926,7 @@ CURL_VERSION_DEBUG 7.10.6
CURL_VERSION_GSSAPI 7.38.0
CURL_VERSION_GSSNEGOTIATE 7.10.6 7.38.0
CURL_VERSION_HTTP2 7.33.0
CURL_VERSION_HTTP3 7.64.0
CURL_VERSION_HTTPS_PROXY 7.52.0
CURL_VERSION_IDN 7.12.0
CURL_VERSION_IPV6 7.10
Expand Down

0 comments on commit e414ba6

Please sign in to comment.