Delete upload.lua
parent
2eb22c20a3
commit
047e0278f9
267
upload.lua
267
upload.lua
|
@ -1,267 +0,0 @@
|
||||||
-- Copyright (C) Yichun Zhang (agentzh)
|
|
||||||
|
|
||||||
|
|
||||||
local sub = string.sub
|
|
||||||
local req_socket = ngx.req.socket
|
|
||||||
local null = ngx.null
|
|
||||||
local match = string.match
|
|
||||||
local setmetatable = setmetatable
|
|
||||||
local error = error
|
|
||||||
local get_headers = ngx.req.get_headers
|
|
||||||
local type = type
|
|
||||||
local print = print
|
|
||||||
|
|
||||||
|
|
||||||
local _M = { _VERSION = '0.08' }
|
|
||||||
|
|
||||||
|
|
||||||
local MAX_LINE_SIZE = 512
|
|
||||||
|
|
||||||
local STATE_BEGIN = 1
|
|
||||||
local STATE_READING_HEADER = 2
|
|
||||||
local STATE_READING_BODY = 3
|
|
||||||
local STATE_EOF = 4
|
|
||||||
|
|
||||||
|
|
||||||
local mt = { __index = _M }
|
|
||||||
|
|
||||||
local state_handlers
|
|
||||||
|
|
||||||
|
|
||||||
local function get_boundary()
|
|
||||||
local header = get_headers()["content-type"]
|
|
||||||
if not header then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(header) == "table" then
|
|
||||||
header = header[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
local m = match(header, ";%s*boundary=\"([^\"]+)\"")
|
|
||||||
if m then
|
|
||||||
return m
|
|
||||||
end
|
|
||||||
|
|
||||||
return match(header, ";%s*boundary=([^\",;]+)")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function _M.new(self, chunk_size)
|
|
||||||
local boundary = get_boundary()
|
|
||||||
|
|
||||||
print("boundary: ", boundary)
|
|
||||||
|
|
||||||
if not boundary then
|
|
||||||
return nil, "no boundary defined in Content-Type"
|
|
||||||
end
|
|
||||||
|
|
||||||
print('boundary: "', boundary, '"')
|
|
||||||
|
|
||||||
local sock, err = req_socket()
|
|
||||||
if not sock then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local read2boundary, err = sock:receiveuntil("--" .. boundary)
|
|
||||||
if not read2boundary then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local read_line, err = sock:receiveuntil("\r\n")
|
|
||||||
if not read_line then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
return setmetatable({
|
|
||||||
sock = sock,
|
|
||||||
size = chunk_size or 4096,
|
|
||||||
read2boundary = read2boundary,
|
|
||||||
read_line = read_line,
|
|
||||||
boundary = boundary,
|
|
||||||
state = STATE_BEGIN
|
|
||||||
}, mt)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function _M.set_timeout(self, timeout)
|
|
||||||
local sock = self.sock
|
|
||||||
if not sock then
|
|
||||||
return nil, "not initialized"
|
|
||||||
end
|
|
||||||
|
|
||||||
return sock:settimeout(timeout)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function discard_line(self)
|
|
||||||
local read_line = self.read_line
|
|
||||||
|
|
||||||
local line, err = self.read_line(MAX_LINE_SIZE)
|
|
||||||
if not line then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local dummy, err = self.read_line(1)
|
|
||||||
if dummy then
|
|
||||||
return nil, "line too long: " .. line .. dummy .. "..."
|
|
||||||
end
|
|
||||||
|
|
||||||
if err then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function discard_rest(self)
|
|
||||||
local sock = self.sock
|
|
||||||
local size = self.size
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local dummy, err = sock:receive(size)
|
|
||||||
if err and err ~= 'closed' then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
if not dummy then
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function read_body_part(self)
|
|
||||||
local read2boundary = self.read2boundary
|
|
||||||
|
|
||||||
local chunk, err = read2boundary(self.size)
|
|
||||||
if err then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
if not chunk then
|
|
||||||
local sock = self.sock
|
|
||||||
|
|
||||||
local data = sock:receive(2)
|
|
||||||
if data == "--" then
|
|
||||||
local ok, err = discard_rest(self)
|
|
||||||
if not ok then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
self.state = STATE_EOF
|
|
||||||
return "part_end"
|
|
||||||
end
|
|
||||||
|
|
||||||
if data ~= "\r\n" then
|
|
||||||
local ok, err = discard_line(self)
|
|
||||||
if not ok then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.state = STATE_READING_HEADER
|
|
||||||
return "part_end"
|
|
||||||
end
|
|
||||||
|
|
||||||
return "body", chunk
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function read_header(self)
|
|
||||||
local read_line = self.read_line
|
|
||||||
|
|
||||||
local line, err = read_line(MAX_LINE_SIZE)
|
|
||||||
if err then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local dummy, err = read_line(1)
|
|
||||||
if dummy then
|
|
||||||
return nil, nil, "line too long: " .. line .. dummy .. "..."
|
|
||||||
end
|
|
||||||
|
|
||||||
if err then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
-- print("read line: ", line)
|
|
||||||
|
|
||||||
if line == "" then
|
|
||||||
-- after the last header
|
|
||||||
self.state = STATE_READING_BODY
|
|
||||||
return read_body_part(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
local key, value = match(line, "([^: \t]+)%s*:%s*(.+)")
|
|
||||||
if not key then
|
|
||||||
return 'header', line
|
|
||||||
end
|
|
||||||
|
|
||||||
return 'header', {key, value, line}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function eof()
|
|
||||||
return "eof", nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function _M.read(self)
|
|
||||||
local size = self.size
|
|
||||||
|
|
||||||
local handler = state_handlers[self.state]
|
|
||||||
if handler then
|
|
||||||
return handler(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil, nil, "bad state: " .. self.state
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function read_preamble(self)
|
|
||||||
local sock = self.sock
|
|
||||||
if not sock then
|
|
||||||
return nil, nil, "not initialized"
|
|
||||||
end
|
|
||||||
|
|
||||||
local size = self.size
|
|
||||||
local read2boundary = self.read2boundary
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local preamble, err = read2boundary(size)
|
|
||||||
if not preamble then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
-- discard the preamble data chunk
|
|
||||||
-- print("read preamble: ", preamble)
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok, err = discard_line(self)
|
|
||||||
if not ok then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local read2boundary, err = sock:receiveuntil("\r\n--" .. self.boundary)
|
|
||||||
if not read2boundary then
|
|
||||||
return nil, nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
self.read2boundary = read2boundary
|
|
||||||
|
|
||||||
self.state = STATE_READING_HEADER
|
|
||||||
return read_header(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
state_handlers = {
|
|
||||||
read_preamble,
|
|
||||||
read_header,
|
|
||||||
read_body_part,
|
|
||||||
eof
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return _M
|
|
Loading…
Reference in New Issue