ben*_*org 2 lua json github nginx webhooks
我现在确实想运行 lua 或任何类似的东西来解析 GitHub 的请求并验证它,然后删除一个文件(当然,如果请求有效)。
最好所有这一切都应该在没有维护额外 PHP 安装的麻烦的情况下发生,因为目前没有,或者需要使用 fcgiwrap 或类似的。
在 nginx 方面,我有相当于
location /deploy {
# execute lua (or equivalent) here
}
Run Code Online (Sandbox Code Playgroud)
要读取 GH webhook 的 json 正文,您需要使用JSON4Lua lib,并使用luacrypto验证 HMAC 签名。
安装所需模块
$ sudo luarocks install JSON4Lua
$ sudo luarocks install luacrypto
Run Code Online (Sandbox Code Playgroud)
在 Nginx 中定义部署位置
location /deploy {
client_body_buffer_size 3M;
client_max_body_size 3M;
content_by_lua_file /path/to/handler.lua;
}
Run Code Online (Sandbox Code Playgroud)
和应该等于以防止max_body_size错误body_buffer_size
不支持临时文件中的请求正文
https://github.com/openresty/lua-nginx-module/issues/521
获取请求负载数据并检查是否正确
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then
ngx.log(ngx.ERR, "failed to get request body")
return ngx.exit (ngx.HTTP_BAD_REQUEST)
end
Run Code Online (Sandbox Code Playgroud)
使用 luacrypto 验证 GH 签名
local function verify_signature (hub_sign, data)
local sign = 'sha1=' .. crypto.hmac.digest('sha1', data, secret)
-- this is simple comparison, but it's better to use a constant time comparison
return hub_sign == sign
end
-- validate GH signature
if not verify_signature(headers['X-Hub-Signature'], data) then
ngx.log(ngx.ERR, "wrong webhook signature")
return ngx.exit (ngx.HTTP_FORBIDDEN)
end
Run Code Online (Sandbox Code Playgroud)
将数据解析为 json 并检查是否为 master 分支,用于部署
data = json.decode(data)
-- on master branch
if data['ref'] ~= branch then
ngx.say("Skip branch ", data['ref'])
return ngx.exit (ngx.HTTP_OK)
end
Run Code Online (Sandbox Code Playgroud)
如果一切正确,调用部署函数
local function deploy ()
-- run command for deploy
local handle = io.popen("cd /path/to/repo && sudo -u username git pull")
local result = handle:read("*a")
handle:close()
ngx.say (result)
return ngx.exit (ngx.HTTP_OK)
end
Run Code Online (Sandbox Code Playgroud)
恒定时间字符串比较示例
local function const_eq (a, b)
-- Check is string equals, constant time exec
getmetatable('').__index = function (str, i)
return string.sub(str, i, i)
end
local diff = string.len(a) == string.len(b)
for i = 1, math.min(string.len(a), string.len(b)) do
diff = (a[i] == b[i]) and diff
end
return diff
end
Run Code Online (Sandbox Code Playgroud)
我如何在 github gist 中使用它的完整示例 https://gist.github.com/Samael500/5dbdf6d55838f841a08eb7847ad1c926
| 归档时间: |
|
| 查看次数: |
1073 次 |
| 最近记录: |