跟很多协议类似, cgi 协议也由 Header 和Body组成,其中Header为固定格式。
CGI Header
字段 |
长度 |
说明 |
version |
1 bytes |
取值一般为1 |
type |
1 bytes |
|
requestId |
2 bytes |
Big Endians |
contentLen |
2 bytes |
Big Endians |
PaddingLen |
1 bytes |
|
reserved |
1 bytes |
预留字段 |
其中type的可能取值如下:
值 |
名称 |
说明 |
1 |
FCGIBEGINREQUEST |
开始请求 |
2 |
FCGIABORTREQUEST |
异常终止请求 |
3 |
FCGIENDREQUEST |
正常终止请求 |
4 |
FCGI_PARAMS |
传递参数 |
5 |
FCGI_STDIN |
POST内容传递 |
6 |
FCGI_STDOUT |
正常响应内容 |
7 |
FCGI_STDERR |
错误输出 |
8 |
FCGI_DATA |
|
9 |
FCGIGETVALUES |
|
10 |
FCGIGETVALUES_RESULT |
|
11 |
FCGIUNKNOWNTYPE |
通知webserver所请求type非正常类型 |
CGI Body
StartRequestRecord协议
字段 |
长度 |
说明 |
role |
2 bytes |
Big Endians |
Flags |
1 byte |
>0表示 长连接 ,否则短连接 |
reserved |
5 bytes |
预留字段 |
包pack伪码如下:
type RecordBodyStartRequest struct {
Role uint16
Flags byte
}
func (r RecordBodyStartRequest) Encode() []byte {
var ret []byte = make([]byte, 0)
ret = append (ret, byte((r.Role >> 8) & 0xFF))
ret = append(ret, byte(r.Role & 0xFF))
ret = append(ret, r.Flags)
ret = common.AppendByteNums(ret, 0, 5)
return ret
}
SendParamRequest协议
这个协议用来通知php-fpm一些常量,例如:
·SCRIPT_FILENAME
·REQUEST_METHOD
协议格式如下:
字段 |
长度 |
说明 |
name_len |
1 bytes OR 4 bytes |
长度小于128用一个字节,大于128用4个字节 |
value_len |
同上 |
同上 |
name |
n bytes |
SCRIPTFILENAME/REQUESTMETHOD etc |
value |
n bytes |
/path/to/php etc |
包pack伪码如下:
type RecordBodySendParams struct {
Name string
Value string
}
func (r RecordBodySendParams) Encode() []byte {
var name string = r.Name
var value string = r.Value
var ret []byte = make([]byte, 0)
var nameLen int = len(name)
if nameLen < 128 {
ret = append(ret, byte(nameLen))
} else {
ret = append(ret, byte((nameLen >> 24) | 0x80))
ret = append(ret, byte(nameLen >> 16))
ret = append(ret, byte(nameLen >> 8))
ret = append(ret, byte(nameLen))
}
var valueLen int = len(value)
if valueLen < 128 {
ret = append(ret, byte(valueLen))
} else {
ret = append(ret, byte((valueLen >> 24) | 0x80))
ret = append(ret, byte(valueLen >> 16))
ret = append(ret, byte(valueLen >> 8))
ret = append(ret, byte(valueLen))
}
for _, v := range []byte(name) {
ret = append(ret, v)
}
for _, v := range []byte(value) {
ret = append(ret, v)
}
return ret
}
EndRequest 协议
这个协议没有包体,只要将Header中type置为FCGIENDREQUEST即可
There’s ALL
基础的协议全部讲完了,剩下的就可以和php-fpm进行简单的通讯了,更多协议格式还请参考官网规定.
Thank You