Simple file uploading service based on Lua-resty-upload

Source: Internet
Author: User
Tags lua

Today I learned about the Lua-resty-upload module, and based on the Lua-resty-upload module simple implementation of a basic form file upload service.


Lua-resty-upload's project address on GitHub is: https://github.com/openresty/lua-resty-upload


From the implementation can be seen, in fact, the implementation of upload service is relatively simple, a source file Lualib/resty/upload.lua, the total number of lines of code is only 300 lines.


Below I have organized the process of building a file upload service:


1, the front page is very simple, is to use the form of input file to trigger the file upload, the code is as follows:


<!--myupload.html--><! DOCTYPE html>


The corresponding myupload.html file is deployed under openresty/nginx/html/.


2, implement the LUA code to receive the file Upload form information and save to the local path, the code is as follows:


-- myupload.lua--==========================================--  File Upload--================================ ==========local upload = require  "Resty.upload" local cjson = require  " Cjson "Local chunk_size = 4096local 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) Endform:set_timeout (-- ) string  split  split string.split =  function (s, p)     local rt= {}    string.gsub (s,  ' [^ ' ... P.. ') + ',  function (w)  table.insert (rt, w)  end )     return rtend--   supports strings before and after  trimstring.trim = function (s)     return  (S:gsub ("^%s* (.- %s*$ ", "%1 ")) end--  file saved root path Local saverootpath =  "/home/steven/openresty/nginx/upload/"--  saved file object local filetosave--file is saved successfully local  Ret_save = falsewhile true do    local typ, res, err  = form:read ()     if not typ then         ngx.say ("failed to read: ",  err)          return    end    if typ ==  "Header"   then        --  start reading  http header         --  parse out the file name of this upload         local key  = res[1]        local value = res[2]         if key ==  "Content-disposition"  then             --  parse out the file name of this upload              -- 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,  "=")                  &nbSp;   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        --  start reading  http body         if fileToSave then             filetosave:wRite (RES)         end    elseif typ ==   "Part_end"  then        --  file write end, close file          if fileToSave then             filetosave:close ()              fileToSave = nil        end                 ret_save = true     elseif typ ==  "EOF"  then        --   End of File read         break    else         ngx.log (ngx.info,  "do other things")      endendif ret_save theN    ngx.say ("Save file ok") end 


By reading the Lualib/resty/upload.lua source code, the module in the process of parsing the file upload request, the main use of a simple similar finite state machine algorithm to achieve, in different states by the corresponding handler processing, supported by the status of the following States include:


    • state_begin (1), the initial state, is initialized at the time of Upload:new instantiation, the following source code (only retained the backbone):


Function _m.new (self, chunk_size, max_line_size)     local boundary  = get_boundary ()     local sock, err = req_socket ()      local read2boundary, err = sock:receiveuntil ("--" &NBSP;  boundary)     local read_line, err = sock:receiveuntil ("\ r \ n")     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, &nBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;STATE&NBSP;=&NBSP;STATE_BEGIN&NBSP;&NBSP;&NBSP;&NBSP;},&NBSP;MT) End 


    • State_reading_header (2), start parsing HTTP header message, generally at this stage is mainly used to parse out the file name, boundary and other information; the corresponding handler is Read_header


    • state_reading_body (3), start parsing HTTP packet, this phase is to read the contents of the file;


    • state_eof (4), if all the files are parsed and read, then enter the state, generally this stage indicates that the file has been read;


The handler of these 4 states are:


State_handlers = {read_preamble, Read_header, Read_body_part, EOF}


-It is important to note that the structure of the read return in different stages/states is different, as the structure returned under state_reading_header is "HEADER", {key, value, line}

-The uploaded file will be saved in the local path /home/steven/openresty/nginx/upload/


3, configure nginx.conf, add location/upfile to receive File upload action, and through Myupload.lua to parse the file upload content after saving to the local file system, as follows:


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;         }    }}


This article is from the "Quiet lunatic" blog, please make sure to keep this source http://quietmadman.blog.51cto.com/3269500/1766034

Simple file uploading service based on Lua-resty-upload

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.