这是Google在C中的SPDY协议的实验实现。
该库提供SPDY版本2、3和3.1框架层实现。它不执行任何I/O操作。当库需要它们时,它将调用应用程序提供的回调函数。它还不包含任何事件轮询机制,因此应用程序可以自由选择处理事件的方式。此库代码不取决于任何特定的SSL库(除了依赖OpenSSL 1.0.1或更高版本的程序外)。
该项目还在Spdylay库的顶部开发了SPDY客户端,服务器和代理。请参阅SPDY客户端和服务器程序部分。
SPDY/2,SPDY/3和SPDY/3.1功能的大多数已经实现。在这两个版本中,尚不可用的Server-Push的直接支持。该应用程序可以使用原始API来实现服务器简介。
如下所述,我们可以使用当前的Spdylay API创建SPDY客户端和服务器。
构建库需要以下包装:
要构建和运行单元测试程序,需要以下包:
要构建和运行示例程序,需要以下包:
要在spdycat (示例程序之一)中启用-a选项(从下载资源中获取链接资产),需要以下软件包:
要将SPDY/HTTP构建为HTTP反向代理shrpx (示例程序之一),需要以下软件包:
如果您使用的是Ubuntu 12.04,则需要安装以下软件包:
$ apt-get安装autoconf autoconf autotools-dev libtool pkg-config zlib1g-dev libcunit1-dev libssl libssl dev libxml2 libxml2-dev libevent libevent-devent libevent-dev
从git构建很容易,但是请确保使用至少使用AutoConf 2.68:
$ autoreconf -i $汽车 $ AUTOCONF $ ./configure $制作
要构建文档,请运行:
$制作html
这些文档将根据doc/manual/html/生成。
生成的文档将不会安装make install 。
在本节中,我们简要介绍了如何使用Android NDK跨编译器在Debian Linux上构建Android二进制。
我们提供android-config和android-make脚本,以使构建更加容易。为了使这些脚本起作用,必须以以下方式安装NDK工具链。首先,让介绍ANDROID_HOME环境变量。我们需要在$ANDROID_HOME/toolchain下安装工具链。用户可以自由选择ANDROID_HOME的路径。例如,要在$ANDROID_HOME/toolchain下安装工具链,请在打开NDK的目录中执行此操作:
$ build/tools/make-standalone-toolchain.sh -platform = android-9-安装dir = $ android_home/tool链
平台级别在这里并不重要,因为我们不使用特定于Android的C/C ++ API。
依赖的库,例如OpenSL和Libevent,应使用工具链构建,并在$ANDROID_HOME/usr/local下安装。我们建议将这些库构建为静态库,以使部署更加容易。 LIBXML2支持当前被禁用。
我们使用Android NDK随附的Zlib,因此我们不必自己构建它。
在运行android-config和android-make之前,必须将ANDOIRD_HOME环境变量设置为指向正确的路径。
在android-config之后,运行android-make以编译来源。 android-make只是包括PATH中交叉编译器的路径。因此,如果您独自包含CORSS编译器的路径,则只需运行以照常构建Spdylay和工具即可。
公共API参考可以在线获得。访问http://tatsuhiro-t.github.io/spdylay/。所有公共API都在Spdylay/spdylay.h中。记录了所有公共API函数以及回调功能Typedefs。
SRC目录包含使用Spdylay库的SPDY客户端和服务器实现。这些程序旨在确保Spdylay API在实际实施和调试目的上可靠地使用。请注意,为了构建和运行这些程序,需要使用NPN支持的OPENSL。在撰写本文时,OpenSSL 1.0.1支持NPN。
SPDY客户端称为spdycat 。这是一个简单的下载器,例如WGET/Curl。它连接到SPDY服务器,并在命令行中获得资源:
$ src/spdycat -h
用法:spdycat [-oansv23] [-t <seconds>] [-w <window_bits>] [-cert = <cert>]
[-Key = <key>] [-no-tls] [-d <file>] [-m <n>] [-p <proxy_host>]
[-p <proxy_port>] <uri> ...
选项:
-v, - verbose打印调试信息,例如接收/
框架和名称/值对的传输。
-n, - 删除下载的数据。
-o, - remote-name将下载数据保存在当前目录中。
该文件名是从URI取下的。如果Uri
以'/','index.html'的结尾用作
文件名。尚未实施。
-2,-spdy2仅使用SPDY/2。
-3,-spdy3仅使用SPDY/3。
-SPDY3-1仅使用SPDY/3.1。
-t,-pimeout = <n> <n>秒后每个请求的超时。
-w, - 窗口= <n>
将初始窗口大小设置为2 ** <n>。
-a, - get-Assets下载资产,例如样式表,图像
和从下载中链接的脚本文件
资源。只有其起源的链接
与链接资源相同
下载。
-s, - 施加打印统计。
-h, - 标先在请求中添加标头。
-cert = <cert>使用指定的客户端证书文件。
该文件必须采用PEM格式。
-Key = <key>使用客户端私钥文件。文件
必须采用PEM格式。
-NO-TLS禁用SSL/TLS。使用-2,-3或-spdy3-1 to
指定要使用的SPDY协议版本。
-d,-data = <file>将文件发布到服务器。如果给出,数据
将从stdin阅读。
-m,-multiply = <n>请求每个URI <n>。默认情况下,相同
不要求URI两次。此选项
也禁用它。
-p,-proxy = <主机>使用此主机作为SPDY代理
-p,-proxy-port = <port>
如果
一个设置
- 色彩色对数输出。
$ src/spdycat -nv https://www.google.com/
[0.021] NPN选择下一个协议:远程服务器提供:
* SPDY/4A4
* SPDY/3.1
* SPDY/3
* http/1.1
NPN选择了协议:SPDY/3.1
[0.029]握手完成
[0.029] RECV设置帧<版本= 3,flags = 0,长度= 20>
(NIV = 2)
[4(1):100]
[7(0):1048576]
[0.029] recv window_update frame <版本= 3,flags = 0,长度= 8>
(stream_id = 0,delta_window_size = 983040)
[0.029]发送Syn_Stream Frame <版本= 3,flags = 1,长度= 221>
(stream_id = 1,Assoc_Stream_id = 0,pri = 3)
:主持人:www.google.com
:方法:获取
:小路: /
:方案:https
:版本:http/1.1
接受: */*
接受编码:GZIP,放气
用户代理:spdylay/1.2.0-dev
[0.080] recv syn_reply帧<版本= 3,flags = 0,长度= 619>
(stream_id = 1)
:状态:302找到
:版本:http/1.1
备用协议:443:quic
缓存控制:私人
内容长度:262
内容类型:text/html; charset = UTF-8
日期:2013年11月19日星期二13:47:18格林尼治标准时间
位置:https://www.google.co.jp/
服务器:GWS
X框架选项:Sameorigin
X-XSS保护:1;模式=块
[0.080] RECV数据框架(stream_id = 1,flags = 1,长度= 262)
[0.080]发送GOAWE框架<版本= 3,flags = 0,长度= 8>
(last_good_stream_id = 0)
SPDY服务器称为spdyd ,并提供静态文件。它是单线螺纹,使用非阻止套接字进行了多路复用连接。使用阻止I/O系统调用读取静态文件, read(2) 。它说SPDY/2和SPDY/3:
$ src/spdyd -htdocs =/your/htdocs/-v 3000 server.key server.crt
IPv4:在端口3000上听
IPv6:在端口3000上听
协商下一个协议:SPDY/3.1
[id = 1] [1.296]发送设置帧<版本= 3,flags = 0,长度= 12>
(NIV = 1)
[4(0):100]
[id = 1] [1.297] recv syn_stream frame <版本= 3,flags = 1,长度= 228>
(stream_id = 1,Assoc_Stream_id = 0,pri = 3)
:主机:Local主机:3000
:方法:获取
:路径: /readme
:方案:https
:版本:http/1.1
接受: */*
接受编码:GZIP,放气
用户代理:spdylay/1.2.0-dev
[id = 1] [1.297]发送Syn_reply Frame <版本= 3,flags = 0,长度= 116>
(stream_id = 1)
:状态:200可以
:版本:http/1.1
缓存控制:max-age = 3600
内容长度:66
日期:星期二,2013年11月19日14:35:24格林尼治标准时间
最后修饰:2012年1月17日星期二15:39:01格林尼治标准时间
服务器:SPDYD SPDYLAY/1.2.0-DEV
[id = 1] [1.297]发送数据框架(stream_id = 1,flags = 0,长度= 66)
[id = 1] [1.297]发送数据框架(stream_id = 1,flags = 1,长度= 0)
[id = 1] [1.297] stream_id = 1关闭
[id = 1] [1.297] recv goaway frame <版本= 3,flags = 0,长度= 8>
(last_good_stream_id = 0)
[id = 1] [1.297]关闭
目前, spdyd需要epoll或kqueue 。
对于使用SHRPX作为SPDY代理的SHRPX用户:请考虑在NGHTTP2 Project开发的NGHTTPX迁移到NGHTTPX。 NGHTTPX也支持SPDY代理。
shrpx是SPDY/HTTPS的多线程反向代理。它将SPDY/HTTPS流量转换为普通HTTP。它最初是作为反向代理而开发的,但现在它具有其他操作模式,例如前端向前代理。例如,使用--spdy-proxy ( -s in shorthand)选项,它可以用作后端中带有代理(例如,squid)的安全SPDY代理。使用--cliet-proxy ( -p )选项,它的作用像是一个典型的前锋代理,但期望后端安全的SPDY代理。因此,它成为确保不支持安全SPDY代理的客户的SPDY代理的适配器。另一个值得注意的操作模式是--spdy-relay ,它仅将SPDY/HTTPS流量转移到SPDY中的后端。下表总结了操作模式。
| 模式选项 | 前端 | 后端 | 笔记 |
|---|---|---|---|
| 默认 | SPDY/HTTPS | http | 反向代理 |
--spdy | SPDY/HTTPS | http | SPDY代理 |
--spdy-relay | SPDY/HTTPS | SPDY | |
--client | http | SPDY | |
--client-proxy | http | SPDY | 前锋代理 |
shrpx支持配置文件。请参阅--conf选项和示例配置文件shrpx.conf.sample 。
我们在此处简要描述shrpx的架构。它具有在服务器插座上倾听的专用线程。当它接受传入连接时,它将传入连接的文件描述符传递给工人线程之一。每个工作线程都有自己的事件循环,可以使用非阻止I/O处理许多连接。可以使用命令行选项指定工作线程的数量。 Libevent用于处理低级网络I/O。
这是命令行选项:
$ SRC/SHRPX -H
用法:shrpx [-dh] [-s | - client | -p] [-b <host,port>]
[-f <host,port>] [-n <cores>] [-c <num>] [-l <Level>]
[选项...] [<Private_Key> <cert>]
SPDY/HTTPS的反向代理。
位置论点:
<private_key>将路径设置为服务器的私钥。必需的
除非指定-p或 - client。
<cert>将路径设置为服务器证书。必需的
除非指定-p或 - client。
选项:
连接:
-b,-backend = <host,port>
设置后端主机和端口。
默认值:'127.0.0.1,80'
-f,-frontend = <host,port>
设置前端主机和端口。
默认值:'0.0.0.0,3000'
-backlog = <Num>设置收听积压大小。
默认值:256
-backend-ipv4解决后端主机名到IPv4地址
仅有的。
-backend-ipv6解决后端主机名到IPv6地址
仅有的。
表现:
-n,-workers = <cores>
设置工作线的数量。
默认值:1
- Read-Rate = <PARE>设置前端的最大平均读取率
联系。将0设置为此选项意味着
阅读率是无限的。
默认值:1048576
- Read-Burst = <size>
将最大读取突发大小设置在前端
联系。将0设置为此选项意味着
读取突发大小是无限的。
默认值:4194304
- 沃特率= <rate>
在前端设置最大平均写入率
联系。将0设置为此选项意味着
写入率是无限的。
默认值:0
- - - burst = <size>
在前端设置最大写突发大小
联系。将0设置为此选项意味着
写突发大小是无限的。
默认值:0
暂停:
-Frontend-spdy-Read-read-limeout = <sec>
为SPDY Frontend指定读取超时
联系。默认值:180
-frontend-read-readimout = <sec>
为非企业前端指定读取超时
联系。默认值:180
-frontend-write timeout = <sec>
指定SPDY和
非稳定前端。
联系。默认值:60
- backend-read termout = <sec>
为后端连接指定读取超时。
默认值:900
- backend-write timeout = <sec>
为后端指定写入超时
联系。默认值:60
- backend-keep-alive timeout = <sec>
为后端指定静止超时
联系。默认值:60
-backend-http-proxy-uri = <uri>
以形式指定代理URI
http:// [<user>:<pass>@] <proxy>:<port>。如果
代理需要身份验证,指定
<user>和<pass>。请注意他们一定是
正确编码的百分比。使用此代理
当后端连接为SPDY时。第一的,
向代理提出连接请求,
它代表后端连接
shrpx。这形成隧道。之后,shrpx
与
通过隧道下游。超时
连接和进行连接请求时
可以通过 - backend-read-timeout指定
和 - backend-write timeout选项。
SSL/TLS:
-ciphers = <Suite>设置允许的密码列表。格式
字符串在OpenSSL密码(1)中描述。
如果使用此选项,-Honor-Cipher-order
被隐式启用。
- honor-cipher-rorder
荣誉服务器密码订单,给出
减轻野兽攻击的能力。
-k, - 企图与-p或 - 委托人一起使用时,请勿验证
后端服务器的证书。
-CACERT = <PATH>与-p或-lient一起使用时,将路径设置为
受信任的CA证书文件。
该文件必须采用PEM格式。它可以
包含多个证书。如果是
链接的OpenSSL配置为加载系统
广泛的证书,已加载
在启动时,无论此选项如何。
- private-key-passwd-file = <filepath>
文件的途径,其中包含密码的密码
服务器的私钥。如果没有给出,并且
私钥是密码保护的
交互要求。
-subcert = <keypath>:<certPath>
指定其他证书和私人证书
密钥文件。 SHRPX会选择证书
基于客户端指示的主机名
使用TLS SNI扩展。这个选项可以是
多次使用。
-backend-tls-sni-field = <主机>
明确设置TLS SNI的内容
扩大。这将默认为后端
主机名。
-DH-PARAM-FILE = <PATH>
在包含DH参数的文件的途径
PEM格式。没有此选项,DHE密码
套房不可用。
- 授予客户要求并验证客户端证书。
- verify-client-cacert = <路径>
包含CA证书的文件途径
验证客户端证书。
该文件必须采用PEM格式。它可以
包含多个证书。
--lient-Provate-key-file = <Path>
包含客户端的文件的途径
键用于后端客户端身份验证。
- client-cert-file = <路径>
包含客户端的文件的途径
后端客户端使用的证书
验证。
-tls-proto-list = <list>
逗号界定的SSL/TLS协议列表
启用。
以下协议可用:
TLSV1.2,TLSV1.1,TLSV1.0,SSLV3
名称匹配是在案例不敏感的
方式。
该参数必须由单个界定
仅逗号,任何白色空间都得到处理
作为协议字符串的一部分。
默认值:TLSV1.2,TLSV1.1,TLSV1.0
SPDY:
-c,-spdy-max-concurrent-streams = <Num>
设置并发的最大数量
在一个SPDY会话中流式传输。
默认值:100
-frontend-spdy-window-bits = <n>
设置每次流的初始窗口大小
SPDY前端连接到2 ** <n>。
默认值:16
-Frontend-spdy-connection-window-bits = <n>
设置SPDY的每连接窗口大小
前端连接到2 ** <n>。
默认值:16
-Frontend-spdy-no-tls
在前端禁用SSL/TLS SPDY
连接。必须指定SPDY协议
使用 - -Frontend-spdy-proto。此选项
也禁用前端http/1.1。
-Frontend-spdy-proto
指定前端使用的SPDY协议
连接如果-Frontend-spdy-no-tls是
用过的。默认值:SPDY/3.1
-backend-spdy-window-bits = <n>
设置每次流的初始窗口大小
SPDY后端连接到2 ** <n>。
默认值:16
-backend-spdy-connection-window-bits = <n>
设置SPDY的每连接窗口大小
后端连接到2 ** <n>。
默认值:16
- backend-spdy-no-tls
在后端SPDY连接上禁用SSL/TLS。
SPDY协议必须使用
- backend-spdy-proto
- backend-spdy-proto
指定后端使用的SPDY协议
连接如果 - 使用-backend-spdy-no-tls。
默认值:SPDY/3.1
模式:
-s,-spdy-Proxy启用安全的SPDY代理模式。
- Spdy-Bridge与SPDY中的后端通信。因此
传入的SPDY/HTTPS连接是
转换为SPDY连接并继电器
后端。参见 - backend-http-proxy-uri
选项如果您在代理后面并想要
连接到外部SPDY代理。
- 客户而不是接受SPDY/HTTPS连接,而是
接受HTTP连接并与
SPDY中的后端服务器。将SHRPX用作
向前代理,使用-P选项。
-p, - client-proxy like - - client选项,但也需要
前端的请求路径必须是
绝对URI,适合用作
前锋代理。
记录:
-l, - log-level = <级别>
设置日志输出的严重程度。
信息,警告,错误和致命。
默认值:警告
- AccessLog打印简单访问件对stderr。
-Systlog将日志消息发送到Syslog。
- 系统 - 词素= <facity>
设置Syslog设施。
默认值:守护程序
杂项:
- add-x-forward-for
将X向后标头字段附加到
下游请求。
- 不via不要通过标头字段附加。如果通过
收到标头字段,留给
不变。
-d,-daemon在背景中运行。如果使用-d,
当前的工作目录已更改为'/'。
-pid-file = <路径>设置了保存此程序的PID的路径。
-user = <user>作为用户运行此程序。此选项是
打算用于降低根特权。
-conf = <路径>从路径加载配置。
默认值:/etc/shrpx/shrpx.conf
-v, - Version打印版本和退出。
-h, - 螺旋打印此帮助并退出。
对于那些好奇的人来说, shrpx是“ SPDY/HTTP到HTTP反向代理”的缩写。
shrpx没有任何-s -s --spdy-bridge , -p和--client选项,可作为后端服务器的反向代理:
客户端< - (spdy,https) - > shrpx < - (http) - > Web服务器
[反向代理]
使用-s选项,它可以用作安全的SPDY代理:
客户端< - (spdy,https) - > shrpx < - (http) - >代理
[SPDY代理](例如,鱿鱼)
需要将上述Client端配置为使用SHRPX作为安全SPDY代理。
在撰写本文时,Chrome是唯一支持安全SPDY代理的浏览器。配置Chrome以使用安全SPDY代理的一种方法是Create proxy.pac脚本:
功能FindProxyForurl(url,host){
返回“ HTTPS ServerAddr:port”;
}
SERVERADDR和PORT是机器SHRPX的主机名/地址。请注意,Chrome需要有效的安全SPDY代理证书。
然后以以下参数运行Chrome:
$ Google-chrome -proxy-pac-url = file:///path/to/proxy.pac-use-npn
笔记
在撰写本文时,Chrome 24将最大并发连接限制为代理到32。由于Chrome中插座池处理的限制,如果使用SPDY代理并且建立了许多SPDY会话,则很快就会填充。如果达到极限,则简单地阻止了新连接,直到定时出现现有连接为止。 (请参阅Chrome第92244页)。解决方法是使最大连接的最大连接数量为99,这是最高的。为此,您需要更改所谓的策略设置。有关如何更改您使用的平台上的策略设置的详细信息,请参见策略模板。我们正在寻找的策略名称是maxConnectionsperproxy,例如,如果您使用的是Linux,请按照Linux快速启动中所述的指令进行操作,并创建/etc/opt/chrome/policies/managed/test_policy.json File带有以下内容和Restart Chrome:Restart Chrome:
{
“ maxConnectionsperproxy”:99
}
使用--spdy-bridge ,它接受SPDY/HTTPS连接并与SPDY中的后端通信:
客户端< - (spdy,https) - > shrpx < - (spdy) - > web或spdy代理等
[SPDY桥](例如,SHRPX -S)
使用-p选项,它可以作为前向代理工作,并期望后端是安全的SPDY代理:
客户端< - (http) - > shrpx < - (spdy) - >安全spdy代理
[正向代理](例如,shrpx -s或node -spdyproxy)
需要将Client配置为使用SHRPX作为前向代理。
在这种配置中,不支持安全SPDY代理的客户端可以通过shrpx使用安全的SPDY代理。将shrpx与客户端放置在同一框或同一网络中,这种配置可以为这些客户带来安全SPDY代理的好处。由于每个服务器的最大连接数仍然适用于代理连接,因此性能增益并不明显。例如,如果每个服务器的最大连接数为6,则在向代理发送6个请求后,客户端将封锁进一步的请求,这会杀死可能在SPDY连接中获得的性能。对于可以调整这些值的客户(例如,firefox中的network.http.max-connections-per-server ),增加它们可能会提高性能。
借助--client选项,它可以作为反向代理,并期望后端是支持SPDY的Web服务器:
客户端< - (http) - > shrpx < - (spdy) - > Web服务器
[反向代理]
对于与SPDY中后端交谈的操作模式,可以通过HTTP代理来隧道隧道。使用--backend-http-proxy-uri选项指定代理。下图说明了--spdy-bridge和--backend-http-proxy-uri选项的示例,可以通过HTTP代理与外部SPDY代理进行交谈:
客户端< - (spdy,https) - > shrpx < - (spdy) -
[SPDY桥]
- =================== ---> SPDY代理
(HTTP代理隧道)(例如,SHRPX -S)
示例目录在C中包含一个简单的SPDY客户端实现。
图书馆配备了Python包装纸python-spdylay 。请参阅python目录。