lua - resty - upload 기반 간단 한 파일 업로드 서비스 구현
lua - resty - upload github 에 있 는 항목 주 소 는:https://github.com/openresty/lua-resty-upload
실현 을 통 해 알 수 있 듯 이 사실 upload 서비스의 실현 은 비교적 간단 하 다. 하나의 소스 파일 인 lualib / resty / upload. lua 만 있 고 전체 코드 줄 수도 300 줄 밖 에 안 된다.
다음은 파일 을 만들어 서 서 서 비 스 를 올 리 는 과정 을 정리 해 봤 습 니 다.
1. 전단 페이지 는 매우 간단 합 니 다. 바로 input file 의 폼 형식 으로 파일 업 로드 를 촉발 하 는 것 입 니 다. 코드 는 다음 과 같 습 니 다.
html>
File upload example
select file: 대응 하 는 my upload. html 파일 은 openresty / nginx / html / 아래 에 배 치 됩 니 다.
2. 파일 업로드 폼 정 보 를 수신 하고 로 컬 경로 에 저장 하 는 lua 코드 를 실현 합 니 다. 코드 는 다음 과 같 습 니 다.
-- myupload.lua
--==========================================
--
--==========================================
local upload = require "resty.upload"
local cjson = require "cjson"
local chunk_size = 4096
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)
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 = "/home/steven/openresty/nginx/upload/"
--
local fileToSave
--
local ret_save = false
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
-- http header
--
local key = res[1]
local value = res[2]
if key == "Content-Disposition" then
--
-- form-data; name="testFileName"; filename="testfile.txt"
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, "=")
local filename = string.sub(kvfile[2], 2, -2)
if filename then
fileToSave = io.open(saveRootPath .. filename, "w+")
if not fileToSave then
ngx.say("failed to open file ", filename)
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
ngx.say("save file ok")
end
lualib / resty / upload. lua 소스 코드 를 읽 습 니 다. 이 모듈 은 파일 업로드 요청 을 분석 하 는 과정 에서 유한 상태 기기 와 유사 한 간단 한 알고리즘 을 사용 하여 이 루어 집 니 다. 서로 다른 상태 에서 해당 하 는 handler 로 처리 되 고 지원 하 는 상 태 는 다음 과 같은 상 태 를 포함 합 니 다.
function _M.new(self, chunk_size, max_line_size)
local boundary = get_boundary()
local sock, err = req_socket()
local read2boundary, err = sock:receiveuntil("--" .. boundary)
local read_line, err = sock:receiveuntil("\r
")
return setmetatable({
sock = sock,
size = chunk_size or CHUNK_SIZE,
line_size = max_line_size or MAX_LINE_SIZE,
read2boundary = read2boundary,
read_line = read_line,
boundary = boundary,
state = STATE_BEGIN
}, mt)
end
이 네 가지 상태의 각각 handler 는:
state_handlers = {
read_preamble,
read_header,
read_body_part,
eof
}
- 여기 서 주의해 야 할 것 은 단계 / 상태 에 따라 read 가 되 돌아 오 는 구조 가 다 릅 니 다. 예 를 들 어 STATEREADING_HEADER 다음 에 돌아 오 는 구 조 는 "header", {key, value, line} 입 니 다.
- 업 로드 된 파일 은 로 컬 경로 에 저 장 됩 니 다. /home / steven / openresty / nginx / upload / 아래
3. nginx. conf 를 설정 하고 location / upfile 을 추가 하여 파일 업로드 액 션 을 받 고 my upload. lua 를 통 해 파일 업로드 내용 을 분석 한 후 로 컬 파일 시스템 에 저장 합 니 다. 다음 과 같 습 니 다.
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 19080;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /upfile {
content_by_lua_file lua/myupload.lua;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Laravel】 CSV 파일 업로드의 검증이 통과되지 않은 원인화면에서 CSV아일의 업로드를 하는 기능을 만들게 되어, 아무것도 없는 채로 구현했으므로, 조금 실행해 볼까와 동작 확인한 바, 밸리데이션이 통과하지 않는다. 가볍게 빠져서 해결까지의 흐름을 적어 둡니다. 이번에는별...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.