SCGI = Simple CGI
SCGI的产生
传统意义上的CGI程序,由Web Server在接收到客户端请求时,启动相应的程序。
这里主要有两个问题:
- CGI程序由Web服务器启动,两者之间的耦合较为紧密。
- CGI程序的启动是比较耗费系统资源的。
随后的FastCGI采用下面的方案来改进问题:
- FastCGI自身作为服务器接受来自Web服务器的请求。
- 这做到了与Web服务器的解耦。
- FastCGI自身提供相应的Web服务。
- 这避免了频繁启动外部程序的开销。
但是FastCGI的协议相对复杂。于是有了SCGI的产生。
SCGI协议概要
一个CGI请求,主要是传递相关的环境变量,和请求数据;其响应可以简单的输出结果就可以。
SCGI的协议可以概括为
- Web服务器向后端的SCGI服务建立连接。
- Web服务器向SCGI服务发送请求。
- SCGI服务接收请求,将相应响应数据发回Web服务器。
- SCGI服务最后关闭当前连接。
其中的请求部分内容概括如下:
- 用
[format "%s\0%s\0" $name $value]
来编码请求头中的字段 - 所用请求头中的字段合起来组成请求头
- 第一个字段必须是
CONTENT_LENGTH
SCGI
字段是必须的
- 第一个字段必须是
- 全部请求头用
netstring
格式进行编码 - 最后在附上请求数据的内容。
SCGI协议的代码示意
set header [dict create]
dict set header CONTENT_LENGTH [string length $body]
dict set header SCGI 1
dict set header ...
set request ""
dict for {name value} $header {
append request "$name\0$value\0"
}
set request [netstring $request]
append request $body
set sock [socket $scgi_host $scgi_port]
write $sock $request
set response [read $sock]
close $sock
netstring编码
proc netstring {bytes} {
return [format "%d:%s," [string length $bytes] $bytes]
}
上面代码中的$bytes
是二进制数据流。这意味着,实际程序中需要进行字符串编码转换。