Build quiche and BoringSSL:
% git clone --recursive https://github.com/cloudflare/quiche % cd quiche % cargo build --release --features ffi,pkg-config-meta,qlog % mkdir deps/boringssl/src/lib % ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) deps/boringssl/src/lib/
Build curl:
% cd .. % git clone https://github.com/curl/curl % cd curl % ./buildconf % ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release % make
Run
Use HTTP/3 directly:
curl --http3 https://nghttp2.org:8443/
Upgrade via Alt-Svc:
curl --alt-svc altsvc.cache https://quic.aiortc.org/
See this list of public HTTP/3 servers
root@ubuntu:~/curl# ls acinclude.m4 buildconf CHANGES CMakeLists.txt COPYING docs include libcurl.pc.in MacOSX-Framework Makefile.dist packages projects README.md scripts src winbuild appveyor.yml buildconf.bat CMake configure.ac curl-config.in GIT-INFO lib m4 Makefile.am maketgz plan9 README RELEASE-NOTES SECURITY.md tests root@ubuntu:~/curl# ./buildconf *** Do not use buildconf. Instead, just use: autoreconf -fi ./buildconf: 4: exec: autoreconf: not found root@ubuntu:~/curl# autoreconf -fi
root@ubuntu:~/curl# apt install autoconf -y Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: golang-1.10-go golang-1.10-src golang-src Use 'apt autoremove' to remove them. The following additional packages will be installed: automake Suggested packages: autoconf-archive gnu-standards autoconf-doc gettext The following NEW packages will be installed: autoconf automake
root@ubuntu:~/curl# autoreconf -fi libtoolize: putting auxiliary files in '.'. libtoolize: copying file './ltmain.sh' libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'. libtoolize: copying file 'm4/libtool.m4' libtoolize: copying file 'm4/ltoptions.m4' libtoolize: copying file 'm4/ltsugar.m4' libtoolize: copying file 'm4/ltversion.m4' libtoolize: copying file 'm4/lt~obsolete.m4
./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release
root@ubuntu:~/curl# ./configure LDFLAGS="-Wl,-rpath,../quiche/target/release" --with-ssl=../quiche/deps/boringssl/src --with-quiche=../quiche/target/release
configure: WARNING: Cannot find libraries for IDN support: IDN disabled checking for pkg-config... (cached) /usr/bin/pkg-config checking for libnghttp2 options with pkg-config... no checking for pkg-config... (cached) /usr/bin/pkg-config checking for libngtcp2 options with pkg-config... no checking for pkg-config... (cached) /usr/bin/pkg-config checking for quiche options with pkg-config... no configure: error: --with-quiche was specified but could not find quiche pkg-config file.
没有执行
cargo build --release --features ffi,pkg-config-meta,qlog
root@ubuntu:~/quiche# cargo build --release --features ffi,pkg-config-meta,qlog Compiling proc-macro2 v1.0.24 Compiling unicode-xid v0.2.1 Compiling syn v1.0.64 Compiling fnv v1.0.7 Compiling ident_case v1.0.1 Compiling strsim v0.10.0 Compiling serde_derive v1.0.124 Compiling serde v1.0.124 Compiling autocfg v1.0.1 Compiling ryu v1.0.5 Compiling serde_json v1.0.64 Compiling hashbrown v0.9.1 Compiling itoa v0.4.7 Compiling quiche v0.7.0 (/root/quiche) Compiling indexmap v1.6.2 Compiling quote v1.0.9 Compiling darling_core v0.12.2 Compiling darling_macro v0.12.2 Compiling darling v0.12.2 Compiling serde_with_macros v1.4.1 Compiling serde_with v1.6.4 Compiling qlog v0.4.0 (/root/quiche/tools/qlog) Finished release [optimized + debuginfo] target(s) in 1m 10s root@ubuntu:~/quiche# mkdir deps/boringssl/src/lib root@ubuntu:~/quiche# ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) deps/boringssl/src/lib/ 'deps/boringssl/src/lib/libcrypto.a' => 'target/release/build/quiche-745ad2f3b756a444/out/build/libcrypto.a' 'deps/boringssl/src/lib/libssl.a' => 'target/release/build/quiche-745ad2f3b756a444/out/build/libssl.a' root@ubuntu:~/quiche#
tls/openssl.c: In function ‘ossl_seed’: vtls/openssl.c:471:15: error: implicit declaration of function ‘RAND_egd’ [-Werror=implicit-function-declaration] int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]? ^ cc1: some warnings being treated as errors Makefile:2634: recipe for target 'vtls/libcurl_la-openssl.lo' failed make[2]: *** [vtls/libcurl_la-openssl.lo] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: Leaving directory '/root/curl/lib' Makefile:1044: recipe for target 'all' failed make[1]: *** [all] Error 2 make[1]: Leaving directory '/root/curl/lib' Makefile:1253: recipe for target 'all-recursive' failed make: *** [all-recursive] Error 1 root@ubuntu:~/curl# make -j $(nproc)
配置 命令少了$PWD改成
root@ubuntu:~/curl# ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release
编译成功
root@ubuntu:~/curl# find ./ -name curl ./src/.libs/curl ./src/curl ./include/curl root@ubuntu:~/curl# ./src/.libs/curl -h ./src/.libs/curl: symbol lookup error: ./src/.libs/curl: undefined symbol: curl_multi_poll root@ubuntu:~/curl# file ./src/.libs/curl ./src/.libs/curl: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.7.0, BuildID[sha1]=a508623fb1cf562e9fa2066e74177c661549d7de, not stripped root@ubuntu:~/curl#
root@ubuntu:~/curl# find -name libcurl.so ./lib/.libs/libcurl.so root@ubuntu:~/curl# pwd /root/curl root@ubuntu:~/curl#
root@ubuntu:~/curl# cat /etc/ld.so.conf include /etc/ld.so.conf.d/*.conf /root/curl/lib/.libs/ root@ubuntu:~/curl# ls /root/curl/lib/.libs/ libcurl.a libcurl_la-curl_des.o libcurl_la-curl_threads.o libcurl_la-getinfo.o libcurl_la-http_negotiate.o libcurl_la-memdebug.o libcurl_la-rename.o libcurl_la-splay.o libcurl_la-warnless.o libcurl.exp libcurl_la-curl_endian.o libcurl_la-dict.o libcurl_la-gopher.o libcurl_la-http_ntlm.o libcurl_la-mime.o libcurl_la-rtsp.o libcurl_la-strcase.o libcurl_la-wildcard.o libcurl.la libcurl_la-curl_fnmatch.o libcurl_la-doh.o libcurl_la-hash.o libcurl_la-http.o libcurl_la-mprintf.o libcurl_la-select.o libcurl_la-strdup.o libcurl_la-x509asn1.o libcurl_la-altsvc.o libcurl_la-curl_gethostname.o libcurl_la-dotdot.o libcurl_la-hmac.o libcurl_la-http_proxy.o libcurl_la-mqtt.o libcurl_la-sendf.o libcurl_la-strerror.o libcurl.so libcurl_la-amigaos.o libcurl_la-curl_get_line.o libcurl_la-dynbuf.o libcurl_la-hostasyn.o libcurl.lai libcurl_la-multi.o libcurl_la-setopt.o libcurl_la-strtok.o libcurl.so.4 libcurl_la-asyn-ares.o libcurl_la-curl_gssapi.o libcurl_la-easygetopt.o libcurl_la-hostcheck.o libcurl_la-idn_win32.o libcurl_la-netrc.o libcurl_la-sha256.o libcurl_la-strtoofft.o libcurl.so.4.7.0 libcurl_la-asyn-thread.o libcurl_la-curl_memrchr.o libcurl_la-easy.o libcurl_la-hostip4.o libcurl_la-if2ip.o libcurl_la-non-ascii.o libcurl_la-share.o libcurl_la-system_win32.o libcurl.ver libcurl_la-base64.o libcurl_la-curl_multibyte.o libcurl_la-easyoptions.o libcurl_la-hostip6.o libcurl_la-imap.o libcurl_la-nonblock.o libcurl_la-slist.o libcurl_la-telnet.o libcurl_la-c-hyper.o libcurl_la-curl_ntlm_core.o libcurl_la-escape.o libcurl_la-hostip.o libcurl_la-inet_ntop.o libcurl_la-openldap.o libcurl_la-smb.o libcurl_la-tftp.o libcurl_la-conncache.o libcurl_la-curl_ntlm_wb.o libcurl_la-fileinfo.o libcurl_la-hostsyn.o libcurl_la-inet_pton.o libcurl_la-parsedate.o libcurl_la-smtp.o libcurl_la-timeval.o libcurl_la-connect.o libcurl_la-curl_path.o libcurl_la-file.o libcurl_la-hsts.o libcurl_la-krb5.o libcurl_la-pingpong.o libcurl_la-socketpair.o libcurl_la-transfer.o libcurl_la-content_encoding.o libcurl_la-curl_range.o libcurl_la-formdata.o libcurl_la-http2.o libcurl_la-ldap.o libcurl_la-pop3.o libcurl_la-socks_gssapi.o libcurl_la-urlapi.o libcurl_la-cookie.o libcurl_la-curl_rtmp.o libcurl_la-ftplistparser.o libcurl_la-http_aws_sigv4.o libcurl_la-llist.o libcurl_la-progress.o libcurl_la-socks.o libcurl_la-url.o libcurl_la-curl_addrinfo.o libcurl_la-curl_sasl.o libcurl_la-ftp.o libcurl_la-http_chunks.o libcurl_la-md4.o libcurl_la-psl.o libcurl_la-socks_sspi.o libcurl_la-version.o libcurl_la-curl_ctype.o libcurl_la-curl_sspi.o libcurl_la-getenv.o libcurl_la-http_digest.o libcurl_la-md5.o libcurl_la-rand.o libcurl_la-speedcheck.o libcurl_la-version_win32.o root@ubuntu:~/curl#
root@ubuntu:~/curl# ldconfig -v && ldconfig /etc/ld.so.conf
还是失败
LD_LIBRARY_PATH=/root/curl/lib/.libs/ ./src/.libs/curl --http3 https://www.cloudflare.com
root@ubuntu:~/curl# LD_LIBRARY_PATH=/root/curl/lib/.libs/ ./src/.libs/curl --http3 https://localhost:443 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> root@ubuntu:~/curl#
root@ubuntu:~/curl# LD_LIBRARY_PATH=/root/curl/lib/.libs/ ./src/.libs/curl --alt-svc altsvc.cache https://quic.aiortc.org/ <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>aioquic</title> <link rel="stylesheet" href="/style.css"/> </head> <body> <h1>Welcome to aioquic</h1> <p> This is a test page for <a href="https://github.com/aiortc/aioquic/">aioquic</a>, a QUIC and HTTP/3 implementation written in Python. </p> <h2>Available endpoints</h2> <ul> <li><strong>GET /</strong> returns the homepage</li> <li><strong>GET /NNNNN</strong> returns NNNNN bytes of plain text</li> <li><strong>POST /echo</strong> returns the request data</li> <li> <strong>CONNECT /ws</strong> runs a WebSocket echo service. You must set the <em>:protocol</em> pseudo-header to <em>"websocket"</em>. </li> <li>There is also an <a href="/httpbin/">httpbin instance</a>.</li> </ul> </body> </html>root@ubuntu:~/curl#
root@ubuntu:~/curl# LD_LIBRARY_PATH=/root/curl/lib/.libs/ ./src/.libs/curl --alt-svc altsvc.cache https://quic.aiortc.org/ -I HTTP/3 200 server: aioquic/0.9.11 date: Fri, 26 Mar 2021 08:45:55 GMT content-length: 1068 content-type: text/html; charset=utf-8
srv/curl脚本
root@ubuntu:~/curl# src/curl --http3 -s -o /dev/null -v https://geekflare.com * Trying 104.27.119.115:443... * Connect socket 5 over QUIC to 104.27.119.115:443 * Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27 * Connected to geekflare.com () port 443 (#0) * h3 [:method: GET] * h3 [:path: /] * h3 [:scheme: https] * h3 [:authority: geekflare.com] * h3 [user-agent: curl/7.76.0-DEV] * h3 [accept: */*] * Using HTTP/3 Stream ID: 0 (easy handle 0xaaab088ef2f0) > GET / HTTP/3 > Host: geekflare.com > user-agent: curl/7.76.0-DEV > accept: */* > < HTTP/3 403 < date: Fri, 26 Mar 2021 08:49:22 GMT < content-type: text/plain; charset=UTF-8 < content-length: 16 < x-frame-options: SAMEORIGIN < cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0 < expires: Thu, 01 Jan 1970 00:00:01 GMT < set-cookie: __cfduid=dd744cfa1ba74876711e4f678fbd376871616748562; expires=Sun, 25-Apr-21 08:49:22 GMT; path=/; domain=.geekflare.com; HttpOnly; SameSite=Lax; Secure < cf-request-id: 090f525ede0000d1f3ae833000000001 < expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" < report-to: {"max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report?s=NKPKlE7Mani75g%2B6ocGhYZZJdj%2BNHhK6FhRYDerxsZYtsv3L8GkWKovurnEKMDPeMzqSDJS7AlE0xHrjF06bFwaMvoR9RbJ%2B1Tn6U04Q"}],"group":"cf-nel"} < nel: {"max_age":604800,"report_to":"cf-nel"} < strict-transport-security: max-age=15552000; preload < x-content-type-options: nosniff < server: cloudflare < cf-ray: 635f201169aed1f3-HKG < alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400 < { [16 bytes data] * Connection #0 to host geekflare.com left intact root@ubuntu:~/curl#
root@ubuntu:~/curl# src/curl --http3 -I https://cloudflare-quic.com HTTP/3 200 date: Fri, 26 Mar 2021 09:12:24 GMT content-type: text/html content-length: 109425 set-cookie: __cfduid=de2a4d49fc1515d1309d25168d295d2671616749944; expires=Sun, 25-Apr-21 09:12:24 GMT; path=/; domain=.cloudflare-quic.com; HttpOnly; SameSite=Lax; Secure cf-request-id: 090f67763c000024c340b75000000001 expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 635f41d05a2224c3-HKG alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
root@ubuntu:~/curl# src/curl --http3 -I https://cloudflare-quic.com --tls-max 1.3 HTTP/3 200 date: Fri, 26 Mar 2021 09:14:29 GMT content-type: text/html content-length: 109425 set-cookie: __cfduid=d2bc25444b488993579bd7aa3a7cee3641616750069; expires=Sun, 25-Apr-21 09:14:29 GMT; path=/; domain=.cloudflare-quic.com; HttpOnly; SameSite=Lax; Secure cf-request-id: 090f69606100000bd64a1b3000000001 expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 635f44e098d80bd6-HKG alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400 root@ubuntu:~/curl# src/curl --http3 -I https://cloudflare-quic.com --tls-max 1.2 HTTP/3 200 date: Fri, 26 Mar 2021 09:14:43 GMT content-type: text/html content-length: 109425 set-cookie: __cfduid=d72e88601b714195d3276d5fa3a28305a1616750083; expires=Sun, 25-Apr-21 09:14:43 GMT; path=/; domain=.cloudflare-quic.com; HttpOnly; SameSite=Lax; Secure cf-request-id: 090f69967d000025a595bae000000001 expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 635f45372a2725a5-HKG alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400 root@ubuntu:~/curl#
root@ubuntu:~/curl# src/curl -I https://servermanager.guide --tls-max 1.3 HTTP/1.1 200 OK Date: Fri, 26 Mar 2021 09:15:27 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Set-Cookie: __cfduid=d8f1036fb7bf6dba91a6fa0d4f3801ac71616750127; expires=Sun, 25-Apr-21 09:15:27 GMT; path=/; domain=.servermanager.guide; HttpOnly; SameSite=Lax; Secure CF-Ray: 635f46466eda329d-HKG Age: 23358 Cache-Control: public, max-age=86400, stale-while-revalidate=60 Expires: Sat, 27 Mar 2021 09:15:27 GMT Link: <https://servermanager.guide/wp-json/>; rel="https://api.w.org/" Strict-Transport-Security: max-age=31536000; includeSubdomains; Vary: Accept-Encoding CF-Cache-Status: HIT CF-CacheTime: 2592000 CF-Default-Rule: 1 CF-Req-Country: CN cf-request-id: 090f6a3ffe0000329d62834000000001 CF-TLS: TLSv1.3 Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" Permissions-Policy: accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=() Referrer-Policy: strict-origin-when-cross-origin X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-Powered-By: centminmod X-Ua-Compatible: IE=edge X-Xss-Protection: 1; mode=block Server: cloudflare alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400