使用Nginx(openresty)进行代理/反代下载github文件
在分享一些github上面的releases文件资源的时候,github的下载链接有时候速度很慢。所以我自己服务器存一份,在自己服务器的下载会快一些。但是github上面更新了版本,我这还得在我服务器上也更新文件和下载地址,有些烦。所以我想实现nginx获取我的链接去github上下载再转手给我,相当于一个代理。
准备工作
一个服务器:此处示例是Debian 12
一个网站:搭建参考https://evlan.cc/archives/docker-nginx.html
安装http客户端
主要用到的文件就是这三个文件
- http_headers.lua
- http_connect.lua
- http.lua
获取软件包
先在服务器上下载软件包
wget https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.zip
# 解压 如果unzip命令未找到就安装解压软件`apt install unzip -y`
unzip v0.17.2.zip
复制文件到nginx容器内
假如按照我之前教程搭建的nginx,映射目录应该有一个/home/www
,docker容器内和宿主机都能访问,所以把文件放这
cp lua-resty-http-0.17.2/lib/resty/http*lua /home/www
进入容器并把文件放到指定位置完成安装
# 进入容器
docker exec -it nginx sh
# 转移文件
mv /home/www/http*lua /usr/local/openresty/lualib/resty/
# 退出容器
exit
写代码
代码流程就是通过路径获取下载连接,然后发起请求去下载,把取得的数据原封不动的返回给请求者
找到配置文件,加上下面这个location代码块
location /download/ {
resolver 8.8.8.8; # DNS解析
content_by_lua_block {
local ngx = require "ngx"
local http = require "resty.http"
local target_url = "https://github.com/" .. ngx.var.uri:gsub("^/download/", "")
local res, err
if not target_url or target_url == "" then
ngx.status = ngx.HTTP_BAD_REQUEST
ngx.say("Missing or invalid parameter")
return
end
local function parse_url(url)
local _, scheme, host, path = url:match("^((https?)://([^/]+))(/.*)$")
return scheme, host, path
end
local http_client = http.new()
local max_redirects = 5
local redirect_count = 0
repeat
if redirect_count > max_redirects then
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
ngx.say("Too many redirects")
return
end
local scheme, host, path = parse_url(target_url)
local ok, e = http_client:connect({ scheme = scheme, host = host, ssl_verify = false })
if not ok then
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
ngx.say("connection failed: ", e)
return
end
res, err = http_client:request({ path = path })
if not res then
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
ngx.say("request failed: ", err)
return
end
if res.status == ngx.HTTP_MOVED_PERMANENTLY or res.status == ngx.HTTP_MOVED_TEMPORARILY then
target_url = res.headers["Location"]
if not target_url then
target_url = res.headers["location"]
if not target_url then
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
ngx.say("Redirect without location header")
return
end
end
end
redirect_count = redirect_count + 1
until (res.status ~= ngx.HTTP_MOVED_PERMANENTLY and res.status ~= ngx.HTTP_MOVED_TEMPORARILY)
-- 复制响应头
for k, v in pairs(res.headers) do
if k:lower() ~= "content-encoding" and k:lower() ~= "transfer-encoding" then
ngx.header[k] = v
end
end
ngx.status = res.status
local reader = res.body_reader
local buffer_size = 8192
local buffer
repeat
buffer, err = reader(buffer_size)
if err then
ngx.log(ngx.ERR, err)
break
end
if buffer then
ngx.print(buffer)
ngx.flush(true)
end
until not buffer
http_client:close()
return
}
}
加上之后代码之后重启nginx生效
docker restart nginx
使用
比如我的网站是https://xxx.com
,我想下载https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.zip
,此时我只需要访问https:/xxx.com/download/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.zip
,就能通过我的https://xxx.com
网站的服务器做中转下载。
修改
这里只是下载github文件,其实可以可以不仅限这一个域名,只要稍微修改
local target_url = "https://github.com/" .. ngx.var.uri:gsub("^/download/", "")
这一行改成
local target_url = "https://" .. ngx.var.uri:gsub("^/download/", "")
然后下载文件只需要下载地址开头的https://
换成https:/xxx.com/download/
即可,
此时下载https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.zip
,就需要访问https:/xxx.com/download/github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.zip