在分享一些github上面的releases文件资源的时候,github的下载链接有时候速度很慢。所以我自己服务器存一份,在自己服务器的下载会快一些。但是github上面更新了版本,我这还得在我服务器上也更新文件和下载地址,有些烦。所以我想实现nginx获取我的链接去github上下载再转手给我,相当于一个代理。

准备工作

一个服务器:此处示例是Debian 12
一个网站:搭建参考https://evlan.cc/archives/docker-nginx.html

安装http客户端

主要用到的文件就是这三个文件

QQ20241010-220839.jpg

  • 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 _, host, path = url:match("^(https?://([^/]+))(/.*)$")
            return 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 host, path = parse_url(target_url)
        
            local ok, e = http_client:connect({ scheme = "https", 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
                    ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
                    ngx.say("Redirect without location header")
                    return
                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

标签: Nginx, Lua, Openresty

添加新评论

Loading...
Fullscreen Image