本文主要解讀下nginx lua module的主要方法和api。html
用在http模塊,經常使用於全局變量的申請
在每一個nginx worker進程啓動時調用指定的lua代碼
設置一個變量,計算變量供後續使用nginx
可替代HttpRewriteModule的rewrite指令來使用的,優先級低於rewrite指令
能夠用來修改請求參數
由ngx返回內容,而不走proxied後端
能夠用來修改後端response的header
通常會在一次請求中被調用屢次, 由於這是實現基於 HTTP 1.1 chunked 編碼的所謂「流式輸出」的。
在請求結束的時候運行,能夠作些統計工做
ngx.cookie_time(ngx.time() + 60 * 30) -- 設置Cookie過時時間爲30分鐘
當前請求的上下文
decode爲table
local decoded_uri=ngx.decode_args("arg1=day1&arg2= monday"); print_t(decoded_uri); function print_t(t) for k, v in pairs(t) do if type(v) == table then ngx.say(k, ": ", table.concat(v), "<br/>"); else ngx.say(k, ": ", v, "<br/>"); end end end
將table編碼爲表單提交格式,a1=arg1&a2=arg2
ngx.say("encode args ", ngx.encode_args({a1="arg1", a2="arg2"}), "<br/>");
標識response結束,ngx.eof()只是結束響應流的輸出,中斷HTTP鏈接,後面的代碼邏輯還會繼續在服務端執行
ngx.req.read_body() local uri_args = ngx.req.get_uri_args(1) ngx.say(cjson.encode{result="refuse"}) ngx.eof()
uri編碼
local fileName = "專輯列表.csv" ngx.header.content_type = "text/csv;charset=utf-8" ngx.header["Content-disposition"] = "attachment;filename=" .. ngx.escape_uri(fileName)
內部重定向
location /foo { content_by_lua ' return ngx.exec('/some-location', 'a=3&b=5&c=6'); '; }
當傳入的status >= 200(200即爲ngx.HTTP_OK),ngx.exit() 會中斷當前請求,並將傳入的狀態碼(status)返回給nginx。當傳入的status == 0(0即爲ngx.OK)則 ngx.exit() 會中斷當前執行的phrase(ngx-lua模塊處理請求的階段,如content_by_lua*),進而繼續執行下面的phrase。json
對於 ngx.exit() 須要進一步注意的是參數status的使用,status能夠傳入ngx-lua所定義的全部的HTTP狀態碼常量(如:ngx.HTTP_OK、ngx.HTTP_GONE、ngx.HTTP_INTERNAL_SERVER_ERROR等)和兩個ngx-lua模塊內核常量(只支持NGX_OK和NGX_ERROR這兩個,若是傳入其餘的如ngx.AGAIN等則進程hang住)。segmentfault
文檔中推薦的 ngx.exit() 最佳實踐是同 return 語句組合使用,目的在於加強請求被終止的語義(return ngx.exit(...))。後端
if not ngx.var.arg_token then ngx.log(ngx.ERR, "Unauthorized") return ngx.exit(ngx.HTTP_UNAUTHORIZED) end
配合使用return,加強退出語義,防止出錯
ngx.say("Hello, Lua!") ngx.flush(true)
設置爲true的話,則ngx.print或者ngx.say的內容等寫入send buffer以後才返回
返回當前的處理階段,init, init_worker,
ssl_cert, set, rewrite, balancer, access, content, header_filter, body_filter, log, or
timer這幾個之一
ngx.header['Content-Type'] = 'application/json; charset=utf-8'; ngx.header['Expires'] = ngx.http_time( ngx.time() + max_age ); ngx.say(ngx.http_time(1290079655)) -- yields "Thu, 18 Nov 2010 11:27:35 GMT"
若是是subrequest則返回true
從NGINX's cache中返回yyyy-mm-dd hh:mm:ss格式的時間
用於子請求,返回: status, header, body, and truncated (a Boolean to represent if the body is truncated).
第一個參數是log基本(one of ngx.STDERR, ngx.EMERG, ngx.ALERT,ngx.CRIT, ngx.ERR, ngx.WARN, ngx.NOTICE, ngx.INFO, and ngx.DEBUG)
後續能夠接多個參數來打印log
從NGINX's cache返回epoch time以來的毫秒數
ngx.now() 是有偏差的,由於使用了nginx 自身的時間緩存。對於精度要求較高的計時,應使用下面的調用序列:
ngx.update_time() local now = ngx.now()
值得一提的是,ngx.now() 只有毫秒精度。api
local time = ngx.parse_http_time("Thu, 18 Nov 2010 11:27:35 GMT") if time == nil then ... end
打印到response body.
打印到response body並換行
http status狀態碼
從nginx cached返回epoch time以來的秒數(no syscall involved unlike Lua's date library).
從NGINX's cache返回當前日期,格式 yyyy-mm-dd
ngx.say(ngx.unescape_uri("b%20r56+7")) -- 返回b r56 7
更新NGINX's time cache
從NGINX's cache返回UTC time,格式yyyy-mm-dd hh:mm:ss