nginx lua api解讀

本文主要解讀下nginx lua module的主要方法和api。html

ngx_lua運行階段

initialization phase

  • init_by_lua
用在http模塊,經常使用於全局變量的申請
  • init_worker_by_lua
在每一個nginx worker進程啓動時調用指定的lua代碼

rewrite / access phase

  • set_by_lua:

設置一個變量,計算變量供後續使用nginx

  • rewrite_by_lua
可替代HttpRewriteModule的rewrite指令來使用的,優先級低於rewrite指令
  • access_by_lua
能夠用來修改請求參數

content phase

  • content_by_lua
由ngx返回內容,而不走proxied後端
  • header_filter_by_lua
能夠用來修改後端response的header
  • body_filter_by_lua
通常會在一次請求中被調用屢次, 由於這是實現基於 HTTP 1.1 chunked 編碼的所謂「流式輸出」的。

log phase

  • log_by_lua
在請求結束的時候運行,能夠作些統計工做

nginx api for lua

ngx.cookie_time

ngx.cookie_time(ngx.time() + 60 * 30) -- 設置Cookie過時時間爲30分鐘

ngx.ctx

當前請求的上下文

ngx.decode_args

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

ngx.encode_args

將table編碼爲表單提交格式,a1=arg1&a2=arg2
ngx.say("encode args ", ngx.encode_args({a1="arg1", a2="arg2"}), "<br/>");

ngx.eof

標識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()

ngx.escape_uri

uri編碼
local fileName = "專輯列表.csv"
ngx.header.content_type = "text/csv;charset=utf-8"
ngx.header["Content-disposition"] = "attachment;filename=" .. ngx.escape_uri(fileName)

ngx.exec

內部重定向
location /foo {
    content_by_lua '
        return ngx.exec('/some-location', 'a=3&b=5&c=6');
    ';
}

ngx.exit

當傳入的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.flush

ngx.say("Hello, Lua!")
ngx.flush(true)
設置爲true的話,則ngx.print或者ngx.say的內容等寫入send buffer以後才返回

ngx.get_phase

返回當前的處理階段,init, init_worker,
ssl_cert, set, rewrite, balancer, access, content, header_filter, body_filter, log, or
timer這幾個之一

ngx.http_time

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"

ngx.is_subrequest

若是是subrequest則返回true

ngx.localtime

從NGINX's cache中返回yyyy-mm-dd hh:mm:ss格式的時間

ngx.location.capture

用於子請求,返回: status, header, body, and truncated (a Boolean to represent if the body is truncated).

ngx.log

第一個參數是log基本(one of ngx.STDERR, ngx.EMERG, ngx.ALERT,ngx.CRIT, ngx.ERR, ngx.WARN, ngx.NOTICE, ngx.INFO, and ngx.DEBUG)
後續能夠接多個參數來打印log

ngx.now

從NGINX's cache返回epoch time以來的毫秒數
ngx.now() 是有偏差的,由於使用了nginx 自身的時間緩存。對於精度要求較高的計時,應使用下面的調用序列:
ngx.update_time()
local now = ngx.now()

值得一提的是,ngx.now() 只有毫秒精度。api

ngx.parse_http_time

local time = ngx.parse_http_time("Thu, 18 Nov 2010 11:27:35 GMT")
 if time == nil then
     ...
 end

ngx.print

打印到response body.

ngx.say

打印到response body並換行

ngx.status

http status狀態碼

ngx.time

從nginx cached返回epoch time以來的秒數(no syscall involved unlike Lua's date library).

ngx.today

從NGINX's cache返回當前日期,格式 yyyy-mm-dd

ngx.unescape_uri

ngx.say(ngx.unescape_uri("b%20r56+7"))
-- 返回b r56 7

ngx.update_time

更新NGINX's time cache

ngx.utctime

從NGINX's cache返回UTC time,格式yyyy-mm-dd hh:mm:ss

doc

相關文章
相關標籤/搜索