本文主要解读下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