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