nginx+lua实现文件上传下载

  1. 当前环境

      0 11:26:57 root@test-a,172.16.15.21:~ # cat /etc/redhat-release 
    CentOS Linux release 7.9.2009 (Core)
      0 11:27:08 root@test-a,172.16.15.21:~ # uname -r
    3.10.0-1160.36.2.el7.x86_64
    
  2. 下载相关的安装包,并解压。

      0 11:27:14 root@test-a,172.16.15.21:~ # cd /usr/local/src/
      0 11:27:28 root@test-a,172.16.15.21:/usr/local/src # wget http://nginx.org/download/nginx-1.18.0.tar.gz
      0 11:27:39 root@test-a,172.16.15.21:/usr/local/src # wget https://github.com/vkholodkov/nginx-upload-module/archive/refs/tags/2.3.0.tar.gz
      0 11:28:06 root@test-a,172.16.15.21:/usr/local/src # wget https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20210510.tar.gz
      0 11:28:13 root@test-a,172.16.15.21:/usr/local/src # wget https://github.com/openresty/lua-resty-upload/archive/refs/tags/v0.10.tar.gz
      0 11:28:58 root@test-a,172.16.15.21:/usr/local/src # wget https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.14.tar.gz
      0 11:29:42 root@test-a,172.16.15.21:/usr/local/src # tar xf nginx-1.18.0.tar.gz 
      0 11:29:53 root@test-a,172.16.15.21:/usr/local/src # tar xf 2.3.0.tar.gz
      0 11:29:57 root@test-a,172.16.15.21:/usr/local/src # tar xf v0.10.14.tar.gz
      0 11:30:01 root@test-a,172.16.15.21:/usr/local/src # tar xf v0.10.tar.gz
      0 11:30:17 root@test-a,172.16.15.21:/usr/local/src # tar xf v2.1-20210510.tar.gz
    
  3. 安装配置各类依赖。

      0 11:30:25 root@test-a,172.16.15.21:/usr/local/src/luajit2-2.1-20210510 # yum -y install pcre-devel openssl-devel
      0 11:32:17 root@test-a,172.16.15.21:/usr/local/src/luajit2-2.1-20210510 # make PREFIX=/usr/local/luajit2
      0 11:32:48 root@test-a,172.16.15.21:/usr/local/src/luajit2-2.1-20210510 # make install PREFIX=/usr/local/luajit2
    
  4. 编译安装nginx。

      0 11:33:53 root@test-a,172.16.15.21:/usr/local/src/luajit2-2.1-20210510 # cd ../nginx-1.18.0/
      0 11:34:24 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # export LUAJIT_LIB=/usr/local/luajit2/lib
      0 11:34:45 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # export LUAJIT_INC=/usr/local/luajit2/include/luajit-2.1
      0 11:35:11 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # useradd -M -s /sbin/nologin www
      0 11:38:35 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # ./configure --user=www --group=www --prefix=/usr/local/nginx --with-stream --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_sub_module --with-http_gzip_static_module --with-http_v2_module --with-pcre --with-ld-opt=-Wl,-rpath,/usr/local/luajit2/lib --add-module=/usr/local/src/nginx-upload-module-2.3.0 --add-module=/usr/local/src/lua-nginx-module-0.10.14
      0 11:39:26 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # make && make install
    
  5. 配置resty。

      0 11:41:20 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # mkdir -p /usr/local/luajit2/lib/lua/5.1/resty
      0 11:41:44 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # cp ../lua-resty-upload-0.10/lib/resty/upload.lua /usr/local/luajit2/lib/lua/5.1/
      0 11:42:17 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # vim /usr/local/luajit2/lib/lua/5.1/my_upload.lua
    local upload = require "resty.upload"
    
    local function my_get_file_name(header)
        local file_name
        for i, ele in ipairs(header) do
            file_name = string.match(ele, 'filename="(.*)"')
            if file_name and file_name ~= '' then
                return file_name
            end
        end
        return nil
    end
    
    local chunk_size = 4096
    local form = upload:new(chunk_size)
    local file
    local file_path
    while true do
        local typ, res, err = form:read()
    
        if not typ then
             ngx.say("failed to read: ", err)
             return
        end
    
        if typ == "header" then
            local file_name = my_get_file_name(res)
            if file_name then
                file_path = ngx.var.store_path..file_name
                file = io.open(file_path, "w+")
                if not file then
                    ngx.say("failed to open file ", file_path)
                    return
                end
            end
    
        elseif typ == "body" then
            if file then
                file:write(res)
            end
    
        elseif typ == "part_end" then
            if file then
                file:close()
                file = nil
                ngx.say("upload to "..file_path.." successfully!")
            end
        elseif typ == "eof" then
            break
    
        else
            -- do nothing
        end
    end
    
  6. 配置并启动nginx。

    # 安全起见,配置访问密码。
      0 11:52:40 root@test-a,172.16.15.21:/usr/local/src/nginx-1.18.0 # cd /usr/local/nginx/
      0 11:52:48 root@test-a,172.16.15.21:/usr/local/nginx # echo -n 'merle:' >>conf/.httppasswd
      0 11:53:15 root@test-a,172.16.15.21:/usr/local/nginx # openssl passwd -apr1 >>conf/.httppasswd
      0 11:53:35 root@test-a,172.16.15.21:/usr/local/nginx # vim conf/nginx.conf
    user  www www;
    worker_processes  auto;
    error_log  logs/error.log;
    pid        logs/nginx.pid;
    
    events {
        use epoll;
        worker_connections  65535;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  logs/access.log  main;
        sendfile        on;
        keepalive_timeout  65;
        lua_package_path '/usr/local/luajit2/lib/lua/5.1/?.lua;;';
    
        server {
            listen       8888;
            server_name  localhost;
            client_max_body_size 500m;
    
            # auth
            auth_basic "security download area";
            auth_basic_user_file "/usr/local/nginx/conf/.httppasswd";
    
            # download
            autoindex on;
            autoindex_localtime on;
    
            location / {
                root   /server/web_files;		# 文件存储目录
            }
    
            location ~ ^/upload(/.*)?$ {
                set $store_path /server/web_files$1/;		# 文件存储目录
                content_by_lua_file /usr/local/luajit2/lib/lua/5.1/my_upload.lua;
            }
        }
    }
      0 11:59:03 root@test-a,172.16.15.21:/usr/local/nginx # \rm -r logs
      0 12:00:01 root@test-a,172.16.15.21:/usr/local/nginx # mkdir -p /server/logs/nginx /server/web_files
      0 12:00:06 root@test-a,172.16.15.21:/usr/local/nginx # ln -sf /server/logs/nginx /usr/local/nginx/logs
      0 12:00:12 root@test-a,172.16.15.21:/usr/local/nginx # ln -s /usr/local/nginx/sbin/nginx /usr/bin/
      0 12:00:39 root@test-a,172.16.15.21:/usr/local/nginx # nginx -t
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
      0 12:01:24 root@test-a,172.16.15.21:/usr/local/nginx # nginx
      0 12:01:30 root@test-a,172.16.15.21:/usr/local/nginx # netstat -lntp | grep 8888
    tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      9529/nginx: master
    # 创建几个测试文件,下面测试使用。
      0 12:05:41 root@test-a,172.16.15.21:/server/web_files # touch info{1..5}.txt
      0 12:06:39 root@test-a,172.16.15.21:/server/web_files # echo 'hello world' >info1.txt
    # 为文件存储目录授权,否则等下上传不上(root启动nginx请忽略)。
      0 12:07:32 root@test-a,172.16.15.21:/server/web_files # chown -R www. /server/web_files
    
  7. 测试访问(为了区分,使用内网其它主机访问测试)。

      0 12:09:54 root@test-b,172.16.15.22:~ # curl -u "merle:123456" http://172.16.15.21:8888
    <html>
    <head><title>Index of /</title></head>
    <body>
    <h1>Index of /</h1><hr><pre><a href="../">../</a>
    <a href="info1.txt">info1.txt</a>                                          23-Sep-2021 12:05                   0
    <a href="info2.txt">info2.txt</a>                                          23-Sep-2021 12:05                   0
    <a href="info3.txt">info3.txt</a>                                          23-Sep-2021 12:05                   0
    <a href="info4.txt">info4.txt</a>                                          23-Sep-2021 12:05                   0
    <a href="info5.txt">info5.txt</a>                                          23-Sep-2021 12:05                   0
    </pre><hr></body>
    </html>
    # 使用命令下载文件。
      0 12:13:24 root@test-b,172.16.15.22:~ # wget --user=merle --password="123456" -c -P /tmp http://172.16.15.21:8888/info1.txt
    --2021-09-23 12:13:30--  http://172.16.15.21:8888/info1.txt
    正在连接 172.16.15.21:8888... 已连接。
    已发出 HTTP 请求,正在等待回应... 401 Unauthorized
    再次使用存在的到 172.16.15.21:8888 的连接。
    已发出 HTTP 请求,正在等待回应... 200 OK
    长度:12 [text/plain]
    正在保存至: “/tmp/info1.txt”
    
    100%[==============================================================================================>] 12          --.-K/s 用时 0s      
    
    2021-09-23 12:13:30 (1.20 MB/s) - 已保存 “/tmp/info1.txt” [12/12])
      0 12:13:30 root@test-b,172.16.15.22:~ # cat /tmp/info1.txt 
    hello world
    # 使用命令上传文件。
      0 12:40:35 root@test-b,172.16.15.22:~ # curl -u "merle:123456" -F filea=@testaaa http://172.16.15.21:8888/upload
    upload to /server/web_files/testaaa successfully!
    # 在服务端查看文件
      0 12:42:49 root@test-a,172.16.15.21:/server/web_files # ll testaaa
    -rw-rw-rw- 1 www www 12 9月  23 12:40 testaaa
      0 12:42:56 root@test-a,172.16.15.21:/server/web_files # cat testaaa 
    How are you
    


写作不易,转载请注明出处,谢谢~~

上一篇:unity面试经验总结


下一篇:什么?网关还有这种操作!