nginx上傳文件

nginx上傳文件

主要包括以下四種方法:

nginx-upload-module

已經用於生產環境,安裝需要編譯nginx。
主要的配置參數:
upload_pass 指明瞭需要後續處理的php地址
upload_cleanup 如果php出現400 404 499 500-505之類的錯誤,則刪除上傳的文件
upload_store 上傳文件存放地址
upload_store_access 上傳文件的訪問權限,user:r是指用戶可讀
upload_limit_rate 上傳限速,如果設置爲0則表示不限制
upload_pass_form_field 從表單原樣轉到後端的參數,可以正則表達式表示
官方的例子是upload_pass_form_field "^submit$|^description$";
意思是把submit,description這兩個字段也原樣通過upload_pass傳遞到後端php處理。如果希望把所有的 表單字段都傳給後端可以用upload_pass_f orm_field "^.*$";

upload_set_form_field可以使用的幾個變量
    $upload_field_name    表單的name值
    $upload_content_type    上傳文件的類型
    $upload_file_name    客戶端上傳的原始文件名稱
    $upload_tmp_path    文件上傳後保存在服務端的位置

upload_aggregate_form_field 可以多使用的幾個變量,文件接收完畢後生成的
    $upload_file_md5    文件的MD5校驗值
    $upload_file_md5_uc    大寫字母表示的MD5校驗值
    $upload_file_sha1    文件的SHA1校驗值
    $upload_file_sha1_uc    大寫字母表示的SHA1校驗值
    $upload_file_crc32    16進製表示的文件CRC32值
    $upload_file_size    文件大小


需要在nginx.conf文件中配置,如下:
location /upload {
        # 文件上傳以後轉給後端的PHP代碼去處理
        upload_pass /movefile.php;

        # 上傳的文件臨時存儲位置
        # 此處注意,我把臨時文件目錄放到了tmpfs中,爲了速度,但有丟失數據的風險!
        upload_store /dev/shm;
        
        # Allow uploaded files to be read only by user
        upload_store_access user:r;

        # Set specified fields in request body
        upload_set_form_field $upload_field_name.name "$upload_file_name";
        upload_set_form_field $upload_field_name.content_type "$upload_content_type";
        upload_set_form_field $upload_field_name.path "$upload_tmp_path";


        # Inform backend about hash and size of a file
        upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
        upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

        upload_pass_form_field "^submit$|^description$";

        upload_cleanup 400 404 499 500-505;
        }

nginx-big-upload

該module與nginx-upload-module主要區別:
  • Linear resumability - there is no way to upload last chunk as first in row, thus there is no risk of bomb file DoS attack. Chunks must be uploaded sequentially, therefore there is also no need to keep fragments layout (.status files) on server.
  • nginx-upload-module doesn't work currently with nginx 1.3.9 and newer, see #41.
  • Easy to enhance/fork, Lua modules are easy to develop, it took me 2 days to learn Lua and create first production version.
  • Multi-part POST requests (form uploads) are not supported only RAW file in PUT/POST request; check lua-resty-upload;
  • No upload rate limit setting - only one client can upload a given file so it is better to throttle downloads.
  • nginx-upload-module doesn't provide CRC32 or SHA1 calculation in resumable mode.
安裝和使用請查看github上的文檔:https://github.com/pgaertig/nginx-big-upload

lua-resty-upload

https://github.com/openresty/lua-resty-upload

主要依賴一個upload.lua,所以自然需要安裝lua執行環境和nginx-lua,例子如下:

nginx.conf配置文件:
 location /uploadfile{
              
                content_by_lua_file 'conf/lua/savefile.lua';
        }

只需要自己寫一個處理文件

package.path = '/usr/local/share/lua/5.1/?.lua;'
package.cpath = '/usr/local/lib/lua/5.1/?.so;'
local upload = require "upload"  

local chunk_size = 8192
local form = upload:new(chunk_size) 

local file  
local filename
local osfilepath = /tmp/

local filelen=0

form:set_timeout(1000) -- 1 sec  



while true do  
    local typ, res, err = form:read()  
    if not typ then  
        return  
    end  
    if typ == "header" then  
        if res[1] ~= "Content-Type" then  
            oldfilename = get_filename(res[2])
			
            if oldfilename then  
				newfilename = string.gsub(string.gsub(string.gsub(oldfilename,'%(',''),'%)',''),' ','')
                filepath = osfilepath  .. newfilename  
                file = io.open(filepath,"w+")  
                if not file then     
                    return  
                end
				
            else  
            end  
        end  
    elseif typ == "body" then  
        if file then  
            filelen= tonumber(string.len(res))      
            file:write(res)  
        else  
        end  
    elseif typ == "part_end" then  	
        if file then
            file:close()  
            file = nil
	end
		
    elseif typ == "eof" then 
        break  
    else  
    end 
end

clientbodyinfileonly















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章