文件服务器open,使用OpenResty搭建简单的文件服务器

前言

前几天使用nginx+nginx_upload_module+python(回调处理程序)搭建了一个简单的文件服务器,网上很多人都建议使用Lua去扩展nginx的功能,所以琢磨了下如何使用Lua语言去对nginx去做功能扩展,网上查阅了许多资料,发现环境搭建还是比较麻烦的,需要安装LuaJIT,nginx的还需要一起编译ngx_devel_kit、lua-nginx-module模块,然后发现了openresty。

之前在了解kong网关的时候知道过openresty,但是没有去了解研究过,这次的机会恰好让我了解学习了一下。

关于openresty

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

​ -- 摘自官网

开始搭建

安装OpenResty

关于OpenResty的安装方法官方文档有非常详细的说明,而且非常全面,可能和章亦春的性格有关吧,非常简单,快速。

直接使用安装工具安装(推荐)

centos 示例

# add the yum repo:

wget https://openresty.org/package/centos/openresty.repo

sudo mv openresty.repo /etc/yum.repos.d/

# update the yum index:

sudo yum check-update

sudo yum install -y openresty

我是使用yum安装的,默认的安装位置在/usr/local/openresty

[root@cloudfile openresty]# pwd

/usr/local/openresty

[root@cloudfile openresty]# ls

bin conf COPYRIGHT luajit lualib nginx openssl pcre site zlib

编写文件处理的Lua脚本

文件位置:/usr/local/openresty/nginx/conf/lua/update.lua

-- upload.lua

--==========================================

-- 文件上传

--==========================================

-- 导入模块

local upload = require "resty.upload"

local cjson = require "cjson"

-- 定义回复的结构

-- 基本结构

local function response(status,msg,data)

local res = {}

res["status"] = status

res["msg"] = msg

res["data"] = data

local jsonData = cjson.encode(res)

return jsonData

end

-- 默认成功的response

local function success()

return response(0,"success",nil)

end

-- 默认带数据的response

local function successWithData(data)

return response(0,"success",data)

end

-- 失败的response

local function failed( msg )

return response(-1,msg,nil)

end

-- end

local chunk_size = 4096

-- 获取请求的form

local form, err = upload:new(chunk_size)

if not form then

ngx.log(ngx.ERR, "failed to new upload: ", err)

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)

ngx.say(failed("没有获取到文件"))

end

form:set_timeout(1000)

-- 定义 字符串 split 分割 属性

string.split = function(s, p)

local rt= {}

string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )

return rt

end

-- 定义 支持字符串前后 trim 属性

string.trim = function(s)

return (s:gsub("^%s*(.-)%s*$", "%1"))

end

-- 文件保存的根路径

local saveRootPath = ngx.var.store_dir

-- 保存的文件对象

local fileToSave

-- 标识文件是否成功保存

local ret_save = false

-- 实际收到的文件名

local rawFileName

-- 实际保存的文件名

local filename

-- 开始处理数据

while true do

-- 读取数据

local typ, res, err = form:read()

if not typ then

ngx.say(failed(err))

return

end

-- 开始读取 http header

if typ == "header" then

-- 解析出本次上传的文件名

local key = res[1]

local value = res[2]

if key == "Content-Disposition" then

-- 解析出本次上传的文件名

-- form-data; name="keyName"; filename="xxx.xx"

local kvlist = string.split(value, ';')

for _, kv in ipairs(kvlist) do

local seg = string.trim(kv)

if seg:find("filename") then

local kvfile = string.split(seg, "=")

-- 实际的文件名

rawFileName = string.sub(kvfile[2], 2, -2)

-- 重命文件名

filename = os.time().."-"..rawFileName

if filename then

-- 打开(创建)文件

fileToSave = io.open(saveRootPath .."/" .. filename, "w+")

if not fileToSave then

-- ngx.say("failed to open file ", filename)

ngx.say(failed("打开文件失败"))

return

end

break

end

end

end

end

elseif typ == "body" then

-- 开始读取 http body

if fileToSave then

-- 写入文件内容

fileToSave:write(res)

end

elseif typ == "part_end" then

-- 文件写结束,关闭文件

if fileToSave then

fileToSave:close()

fileToSave = nil

end

ret_save = true

-- 文件读取结束

elseif typ == "eof" then

break

else

ngx.log(ngx.INFO, "do other things")

end

end

if ret_save then

local uploadData = {}

uploadData["file"] = rawFileName

uploadData["url"] = "http://xxx.com/download/"..filename

ngx.say(successWithData(uploadData))

else

ngx.say(failed("系统异常"))

end

编写nginx配置文件

文件位置:/usr/local/openresty/nginx/conf/nginx.conf

user root;

worker_processes 20;

error_log logs/error.log notice;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application/octet-stream;

server {

listen 80;

server_name localhost;

# 最大允许上传的文件大小

client_max_body_size 300m;

set $store_dir "/var/www/download"; # 文件存储路径

# 文件上传接口:http://xxx.com/uploadfile

location /uploadfile {

# 实现文件上传的逻辑

content_by_lua_file conf/lua/upload.lua;

}

# 文件下载入口: http://xxx.com/download

location /download {

alias /var/www/download;

autoindex on;

autoindex_localtime on;

}

# redirect server error pages to the static page /50x.html

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

}

启动测试

这里启动nginx的方式和普通的nginx是一样的:

启动:/usr/local/openresty/nginx/sbin/nginx

关闭:/usr/local/openresty/nginx/sbin/nginx -s stop

重新加载配置:/usr/local/openresty/nginx/sbin/nginx -s reload

上传文件

POST /uploadfile

f6c607b3e8c2

上传文件

下载文件

访问GET /download即可

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值