libcurl 使用 http2

首先 http2 一定要是加密的,必须要 https 才行,所以第一步要先支持 https 。
如果是一个权威机构认证的证书,那么直接使用正常的请求方式也 OK 的,底层已经处理好了自动可以验证到证书的有效性。然而,如果是我们自己签名的证书底层没有办法自动验证证书,就需要我们自己来解决了。
如果服务器使用的是自签名,libcurl 会报证书无效的错误:
SSL certificate problem: Invalid certificate chain

有两个思路,一是干脆直接不做验证:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

当然,对于强迫症人群来说,我们怕 DNS 被劫持,所以要自己验证一下证书。当然其实也很简单:

curl_easy_setopt(curl, CURLOPT_CAINFO, "<your certificate path>");

只要证书传对就可以了。如果使用 ip 访问,然而证书中指定了主机名,那么会报错。
WARNING: using IP address, SNI is being disabled by the OS.
这种情况如果一定要使用这个证书并且使用不同域名访问的话,可以把域名验证关掉。

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

https 可以成功了之后,再看如何发出一个 http2 的消息。
起始只要库的版本没问题并且服务器端支持 http2,那么默认的 https 就被底层默认处理为 http2 消息了。当然,显示的设定一下 http 版本算是一种礼貌吧,而且即使设成2.0如果不被支持的话也会默认转为1.1的。

curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2);

如果需要使用 http2 的多路传输 pipelining 只需要做一个简单的设置:

curl_multi_setopt(curlm, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
// 尽可能多路复用 
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);

关于更多链接复用和 pipelining 的细节,我还没深入了解,之后有空再研究。

关于环境的搭建:
安装支持 http2 的 apache

mac 系统安装支持 http2 的 curl:
使用 brew 安装一个全新的 curl

brew install curl --with-nghttp2

强行将默认的 curl 连接为这个最新版本

brew link curl —force

然后重启终端就可以生效了。
可以试一试

curl -v --http2 https://10.10.10.109/test_http2.php

参考资料
如果不出意外,那么在返回数据中会有 HTTP/2.0 200 那么就说明环境没问题了。

我们在使用 libcurl 库的时候还要注意一下,一定要连接到新编译出的这个版本,如果是系统默认版本是不支持 http2 的。
我用的方法就是在 cmake 脚本简单指定了一下连接路径:

link_directories(/usr/local/Cellar/curl/7.48.0/lib)

毕竟这不是重点,实现功能最重要。

新的功能已经更新到 github 可以直接 点击前往

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

RSS
Follow by Email
YouTube
YouTube
Pinterest
fb-share-icon
LinkedIn
Share
VK
Weibo
WeChat
WhatsApp
Reddit
FbMessenger
Copy link
URL has been copied successfully!