HTTP/2探索第二篇——工具及应用
版权声明:本文由张浩然原创文章,转载请注明出处:
文章原文链接:https://www.qcloud.com/community/article/88
来源:腾云阁 https://www.qcloud.com/community
由于不同环境过于复杂,本文仅基于Mac OS和Linux来讲解工具及应用。
一.HTTP/2环境搭建所需软件概览
本文需要安装的软件为(Mac用户请使用homebrew来安装,括号里都是Mac的安装方式)
-
curl (brew install nghttp2 —with-nghttp2)
Linux安装wget https://curl.haxx.se/download/curl-7.48.0.tar.gz
tar xvf curl-7.48.0.tar.gz && cd curl-7.48.0
然后输入以下命令,exit一次再进入然后版本是7.48就成功了:$ ./configure --with-nghttp2=/usr/local --with-ssl $ make $ sudo make install $ ldconfig $ usr/local/bin/curl -V
-
nghttp2 (brew install nghttp2)
安装网址sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \ zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \ libjemalloc-dev cython python3-dev python-setuptools
上面是安装依赖,之后就可以编译了:
$ autoreconf -i $ automake $ autoconf $ ./configure $ make $ sudo make install nginx (brew install nginx —devel)
-
nginx (brew install nginx —devel)
Linux安装
vim到/etc/apt/sources.list
增加以下两行,其中$codename
自行去该网站查询,比如Ubuntu 14.04 是 trusty;deb http://nginx.org/packages/mainline/ubuntu/ $codename nginx deb-src http://nginx.org/packages/mainline/ubuntu/ $codename nginx
然后
sudo apt-get update && sudo apt-get install nginx
就可以装最新支持HTTP2的nginx啦; -
apache (brew install httpd24 —with-http2)[本文重点讲解nginx]
Linux安装二.证书
1.自签发
打开提供的Demo文件,terminal打开/keys路径,输入
./ca.sh http2test.com
,也可以生成其他域名或泛域名(.xx.com).注意:也可以不用生成证书,直接使用keys文件下提供的http2test.com证书;
Let’s Encrypt
打开Let’s Encrypt的官网,这里讲解如果已经启动nginx的情况下,如何签发证书。
步骤: - 首先需要把代码克隆下来:
git clone https://github.com/letsencrypt/letsencrypt && cd letsencrypt
- 然后
./letsencrypt-auto --help
会执行一些初始化工作,并且显示支持的命令; -
比如我的web目录在
~/www
下,此步骤需要已搭建好服务器,并且可以通过example.com访问~/www
里的内容,如果是动态网站,需要在nginx层设置一个映射,将/.well-known/acme-challenge
映射到刚设置好的目录,也就是~/www
。location /.well-known/acme-challenge { root /home/$username/www; }
-
(需要nginx已经装好,没装好的完成下面的nginx部分后再回来设置)那么
./letsencrypt-auto certonly --webroot -w ~/www -d example.com
,example.com是你希望申请证书的域名,然后证书下发成功。 -
然后在nginx中设置证书信息
ssl_certificate /etc/letsencrypt/live/$example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$example.com/privkey.pem;
-
然后
sudo nginx -t && sudo nginx -s reload
就可以看到啦
三、基本工具
- curl
curl的基本用法是:curl -v -o /dev/null --http2 http://nghttp2.org
这里输入的是HTTP而不是HTTPS是因为,这里会采用HTTP2的ClearText模式,使用101 改变协议
协商升级为HTTP2协议。
Connected to nghttp2.org (106.186.112.116) port 80 (#0)> GET / HTTP/1.1> Host: nghttp2.org
> User-Agent: curl/7.48.0> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQAAP__>
< HTTP/1.1 101 Switching Protocols
< Connection: Upgrade
< Upgrade: h2c
* Received 101* Using HTTP2, server supports multi-use* Connection state changed (HTTP/2 confirmed)
* TCP_NODELAY set
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=21* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2.0 200< date:Sun, 10 Apr 2016 16:52:43 GMT
< content-type:text/html
< content-length:6646< last-modified:Sun, 03 Apr 2016 06:53:14 GMT
< etag:"5700bdda-19f6"< link:</stylesheets/screen.css>; rel=preload; as=stylesheet
< accept-ranges:bytes
< x-backend-header-rtt:0.000625< server:nghttpx nghttp2/1.10.0-DEV
< via:2 nghttpx
< x-frame-options:SAMEORIGIN
< x-xss-protection:1; mode=block
< x-content-type-options:nosniff
<
现在的大多数网站,都是通过302跳转到HTTPS网站来协商升级的,例如我厂的QQ邮箱;
Connected to mail.qq.com (183.60.15.162) port 80 (#0)
> GET / HTTP/1.1
> Host: mail.qq.com> User-Agent: curl/7.48.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQAAP__>
<
HTTP/1.1 302 Found
< Server: TWS
< Connection: close
< Date: Sun, 10 Apr 2016 16:58:48 GMT
< Content-Type: text/html; charset=GB18030
< Location: https://mail.qq.com/cgi-bin/loginpage
< Content-Length: 0
<
- nghttp
官方文档,安装nghttp2后有配套的nghttp 客户端、nghttpd 服务器、nghttpx 反向代理、h2load 负载测试等工具。
输入命令nghttp -nv https://nghttp2.org
(n代表不输出,v代表详细信息):
结果列出了连接过程中的HTTP2各个Stream信息,例如SETTINGS Frame,HEADER Frame等,也可以带上参数:
[ 0.170] Connected
The negotiated protocol: h2
[ 0.732] recv SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.732] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.732] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.732] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.732] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.732] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.732] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.732] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.732] send HEADERS frame <length=36, flags=0x25, stream_id=13>
; END_STREAM | END_HEADERS | PRIORITY
(padlen=0, dep_stream_id=11, weight=16, exclusive=0)
; Open new stream
:method: GET
:path: /
:scheme: https
:authority: nghttp2.org
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.9.1
[ 0.891] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.891] recv (stream_id=13) :method: GET
[ 0.891] recv (stream_id=13) :scheme: https
[ 0.892] recv (stream_id=13) :path: /stylesheets/screen.css
[ 0.892] recv (stream_id=13) :authority: nghttp2.org
[ 0.892] recv (stream_id=13) accept-encoding: gzip, deflate
[ 0.892] recv (stream_id=13) user-agent: nghttp2/1.9.1
[ 0.892] recv PUSH_PROMISE frame <length=47, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0, promised_stream_id=2)
[ 0.892] recv (stream_id=13) :status: 200
[ 0.892] recv (stream_id=13) date: Sun, 10 Apr 2016 17:00:25 GMT
[ 0.892] recv (stream_id=13) content-type: text/html
[ 0.892] recv (stream_id=13) content-length: 6646
[ 0.892] recv (stream_id=13) last-modified: Sun, 03 Apr 2016 06:53:14 GMT
[ 0.892] recv (stream_id=13) etag: "5700bdda-19f6"
[ 0.892] recv (stream_id=13) link: </stylesheets/screen.css>; rel=preload; as=stylesheet
[ 0.892] recv (stream_id=13) accept-ranges: bytes
[ 0.892] recv (stream_id=13) x-backend-header-rtt: 0.000663
[ 0.892] recv (stream_id=13) strict-transport-security: max-age=31536000
[ 0.892] recv (stream_id=13) server: nghttpx nghttp2/1.10.0-DEV
[ 0.892] recv (stream_id=13) via: 2 nghttpx
[ 0.892] recv (stream_id=13) x-frame-options: SAMEORIGIN
[ 0.892] recv (stream_id=13) x-xss-protection: 1; mode=block
[ 0.892] recv (stream_id=13) x-content-type-options: nosniff
[ 0.892] recv HEADERS frame <length=266, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0)
; First response header
[ 0.893] recv DATA frame <