ngx.req.socket
语法: tcpsock, err = ngx.req.socket()
语法: tcpsock, err = ngx.req.socket(raw)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
返回一个包含了下游连接的只读的cosocket对象。在这个对象里面,只支持receive和receiveuntil方法。
在发生错误的情况下,将会返回一个nil
值和一个描述错误的字符串。
这个方法返回的socket对象经常被用来读取请求的body,以一个流的方式。不要开启lua_need_request_body指令,并且不要将这个调用与ngx.req.read_body和ngx.req.discard_body混合使用。
如果任何请求的body数据已经被预读到Nginx内核请求header缓冲区中,结果cosocket对象要小心的处理这些来避免这种预读取中潜在的数据丢失。分块请求的body在这个API中不支持。
从v0.9.0
版本开始,这个方法接受一个可选的 boolean raw
参数。当这个参数是true
,这个方法返回一个全双工的cosocket对象包装原始的下游连接套接字,在这里你可以调用receive, receiveuntil, 和 send方法。
当raw
参数是true
,要求这里没有从之前ngx.say, ngx.print, 或者 ngx.send_headers 调用时未解决的数据存在。所以,如果你之前有这些下游输出调用,你应该在调用ngx.req.socket(true)
之前调用ngx.flush(true)来保证这里没有未解决的输出数据。如果请求body还没有被读取,那么"raw socket"也可以被用来读取请求的body。
你可以使用通过ngx.req.socket(true)
返回的“raw request socket”来实现花哨的协议例如WebSocket,或者只是发出你自己的未加工的HTTP响应头或者body数据。你可以参考lua-resty-websocket library的一个真实世界的例子。
这个方法首先从v0.5.0rc1
版本被介绍。
ngx.exec
语法: ngx.exec(uri,args?)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
做一个内部重定向到uri
附带参数arg
并且和echo-nginx-module中的echo_exec相似。
ngx.exec('/some-location');
ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6');
这个可选的第二个参数args
可以被用来指定额外的URI查询参数,例如:
ngx.exec("/foo", "a=3&b=hello%20world")
作为另一种选择,一个Lua table中可以被当做args
参数传递,ngx_lua来展开URI转义和字符串连接。
ngx.exec("/foo",{ a = 3, b = "hello world" })
这个结果和之前的例子是完全相同的。
通过Lua table传递args
参数的形式和通过使用ngx.encode_args方法是完全一样的。
同样也支持命名的location但是第二个args
参数将会被忽略掉,如果查询字符串存在并且新location会继承自以前的location(如果有的话)。
在下面的例子中,GET /foo/file.php?a=hello
将会返回“hello”而不是“goodbye”。
location /foo {
content_by_lua_block {
ngx.exec("@bar","a=goodbye");
}
}
location @bar {
content_by_lua_block {
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
if key == "a" then
ngx.say(val)
end
end
}
}
注意ngx.exec
方法和ngx.redirect并不一样,这是由于它是一个纯粹的外部重定向并且不包括额外的HTTP流量。
并且注意这个方法调用终止当前请求的处理并且它 必须 在ngx.send_headers或者ngx.print 或 ngx.say明确响应body输出之前调用。
建议编码时候,将这个方法调用和return
语句结合,例如:return ngx.exec(...)
可以在除了header_filter_by_lua*之外的上下文中使用,以强调程序已经被终止的事实。
ngx.redirect
语法: ngx.redirect(uri, status?)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
发出一个HTTP 301
或者302
重定向到uri
。
这个可选的status
参数指定要使用的HTTP状态。现在支持下面的状态码:
301
-
302
(默认) 303
307
默认的是 302
(ngx.HTTP_MOVED_TEMPORARILY
)
这里有一个例子,假设当前的服务器名称是localhost
,并且监听的端口是 1984:
return ngx.redirect("/foo")
等价于
return ngx.redirect("/foo", ngx.HTTP_MOVED_TEMPORARILY)
支持重定向任意外部的URL,例如:
return ngx.redirect("http://www.google.com")
我们也可以直接使用数值代码作为第二个status
参数:
return ngx.redirect("/foo",301)
这个方法和标准ngx_http_rewrite_module中的附带redirect
修饰符的rewrite 指令类似,例如,这个nginx.conf
片段
rewrite ^ /foo? redirect; # nginx config
等价于下面的Lua代码
return ngx.redirect('/foo'); -- Lua code
而
rewrite ^ foo? permanent; #nginx config
等价于
return ngx.redirect('/foo',ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
也可以指定URI参数,例如:
return ngx.redirect('/foo?a=3&b=4')
注意这个方法调用终止当前请求的运行并且它 必须 在ngx.send_headers调用或者通过ngx.print或者 ngx.say明确响应body输出之前。
建议的编码风格是,将这个方法调用与一个return
声明结合,例如,return ngx.redirect(...)
在除了header_filter_by_lua*之外的上下文中被接受,来强调一个事实就是这个请求处理已经被终止了。
ngx.send_headers
语法: ok, err = ngx.send_headers()
上下文: rewrite_by_lua*,access_by_lua*,content_by_lua*
显示的发送出响应头。
从v0.8.3
版本这个方法在成功的时候返回1
,在其他情况下返回一个nil
和一个字符串描述错误。
注意通常情况下不需要手动发送出响应头,因为ngx_lua会在内容通过 ngx.say 或者 ngx.print输出之前自动的将响应头发出,或者当content_by_lua*正常退出时。
ngx.headers_sent
语法: value = ngx.headers_sent
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*
如果响应头被发出去了(通过ngx_lua)将会返回true
,其他情况返回false
。
这个API首先在ngx_lua v0.3.1rc6版本中被介绍。
ngx.print
语法: ok,err = ngx.print(...)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
发出已经连接过的参数到HTTP客户端(作为响应body)。如果响应头没有被发送,这个方法将会首先发出headers然后发出body数据。
从v0.8.3
,这个方法在成功后返回1
,在其他情况下返回nil
和一个描述错误信息的字符串。
Lua nil
值将会输出"nil"
字符串并且Lua boolean值将会分别输出"true"
和"false"
文字字符串。
嵌套的字符串是数组是允许的并且数组中的元素将会被一个接着一个的输出:
local table = {
"hello, ",
{"world: ", true, " or ", false,
{": ", nil}}
}
ngx.print(table)
将会产生输出:
hello, world: true or false: nil
非数组的表参数将会导致抛出一个Lua异常。
这个ngx.null
常量将会产生"null"
字符串输出。
这是一个异步的调用并且将会立即返回而不需要等待所有的数据要写入系统发送缓存区中。要开启同步模式,在调用ngx.print
之后调用ngx.flush(true)
。这个对流输出特别有用。更多细节查看ngx.flush。
请注意一点ngx.print
和 ngx.say会总是调用整个Nginx输出body过滤链,这个是一个昂贵的操作。所以在一个紧密循环中无论调用哪一个都要小心。你自己在Lua中缓冲数据并且保存调用。
ngx.say
语法: ok, err = ngx.say(...)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
和ngx.print类似但是多发出一个换行符。
ngx.log
语法: ngx.log(log_level, ...)
上下文: init_by_lua*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
通过给定的logging级别来连接参数到error.log中。
Lua nil
参数是接受的,并且结果为文字的"nil"
字符串,同时Lua boolean结果为文字的"true"
或者"false"
字符串输出。并且ngx.null
常量将会产生"null"
字符串输出。
这个log_level
参数可以取常数例如ngx.ERR
和ngx.WARN
.检查Nginx log level constants来获取细节。
这里有个Nginx内核硬编码的2048
字节的限制在错误信息长度上。这个限制包含结尾换行开头的时间戳。如果信息大小超过了这个限制,Nginx会相应的截取信息字符串。这个限制可以通过编辑在Nginx源码树种的src/core/ngx_log.h
文件的NGX_MAX_ERROR_STR
宏定义来修改。
ngx.flush
语法: ok, err = ngx.flush(wait?)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
Flush 响应输出到客户端。
ngx.flush
接受一个可选的boolean wait
参数(默认:false
),首先在v0.3.1rc34
版本中介绍。当通过默认的参数调用的时候,它缠身给一个异步的调用(立即返回而不等待输出数据被写入到系统的发送缓冲中)。通过wait
参数设置为true
调用这个方法会转变为同步模式。
在同步模式,这个方法将会不会返回直到所有的输出数据已经被写入到系统输出缓冲中或者直到send_timeout设置已经过期了。注意使用Lua协同程序机制意味着这个方法并不阻塞Nginx事件循环及时在同步模式。
当ngx.flush(true)
在ngx.print或者ngx.say之后被立即调用,这回导致后者的方法在同步模式下运行。这个在流输出中特别有用。
注意ngx.flush
在HTTP 1.0输出缓冲模式中并不是一个功能。查看HTTP 1.0 support。
从v0.8.3
开始这个方法在成功之后返回1
,在其他情况下返回nil
和一个字符串来描述错误。
ngx.exit
语法: ngx.exit(status)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
当status >= 200
(例如,ngx.HTTP_OK
和以上),它将会中断当前的请求并且返回状态码给nginx。
当status == 0
(例如,ngx.OK
),它将会退出当前的阶段处理器(或者内容处理器如果 content_by_lua*指令被使用了)并且为当前请求继续运行后面的阶段(如果有的话)。
这个status
参数可以使ngx.OK
, ngx.ERROR
,ngx.HTTP_NOT_FOUND
,ngx.HTTP_MOVED_TEMPORARILY
,或者其他 HTTP status constants。
要返回一个包含当前内容的错误页,可以使用像这样的代码片段:
ngx.status = ngx.HTTP_GONE
ngx.say("This is our own content")
-- to cause quit the whole request rather than the current phase handler
ngx.exit(ngx.HTTP_OK)
执行的效果:
$ curl -i http://localhost/test
HTTP/1.1 410 Gone
Server: nginx/1.0.6
Date: Thu, 15 Sep 2011 00:51:48 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
This is our own content
数值文本可以直接被用在参数上,例如,
ngx.exit(501)
注意尽管这个方法接受所有的 HTTP status constants作为输入,它只接受core constants中的NGX_OK
和NGX_ERROR
。
还要注意,这个方法调用欧冠终止当前请求的处理并且建议的编码风格是将这个方法调用欧冠与一个return
声明连接,例如, return ngx.exit(...)
被用来强调一个事实是请求处理已经被终止了。
当用在header_filter_by_lua*, balancer_by_lua*, 和
ssl_session_store_by_lua*的上下中时,ngx.exit()
作为一个异步的操作将会立即返回。这个行为在未来可能会改变并且推荐用户使用上面推荐的return
来结合使用。
ngx.eof
语法: ok, err = ngx.eof()
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*
显示的指定响应输出流的结束。在HTTP 1.1分块编码输出的情况下,它将只是会触发Nginx内核发送出"last chunk"。
当你在你下游连接中禁用了HTTP 1.1的keep-alive特性时,你可以调用这个方法来写到HTTP client来主动的关闭连接。这个技巧可以用在做一些后台工作而不让HTTP客户端等待连接,例如下面的例子:
location = /async {
keepalive_timeout 0;
content_by_lua_block {
ngx.say("got the task!")
ngx.eof() -- well written HTTP clients will close the connection at this point
-- access MySQL, PostgreSQL, Redis, Memcached, and etc here...
}
}
但是如果你创建子请求来访问其他通过nginx upstream模块配置的location,那么你应该配置这些upstream模块来忽略客户端连接中断,如果他们不是默认情况的话。例如,在默认情况下标准的ngx_http_proxy_module将会同时中断子请求和主请求,当客户端重点连接时,所以在你的location块ngx_http_proxy_module配置中开启proxy_ignore_client_abort](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort) 指令是非常重要的。
proxy_ignore_client_abort on;
一个更好的来做后台工作的方式是使用ngx.timer.atAPI接口。
从v0.8.3
开始这个方法在成功时候返回1
,在其他错误情况下返回nil
和一个字符串描述。
ngx.sleep
语法: ngx.sleep(seconds)
上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*
睡眠指定的描述而不阻塞。可以指定一个时间分辨率达到0.001秒(例如:一毫秒)。
在后面的场景,这个方法使用的是Nginx timers。
从0.7.20
版本开始,这个0
时间参数也可以被指定。
这个方法首先在0.5.0rc30
版本中被介绍。
ngx.escape_uri
语法: newstr = ngx.escape_uri(str)
上下文: init_by_lua*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
编码str
来作为URI组件。
ngx.unescape_uri
语法: newstr = ngx.unescape_uri(str)
上下文: init_by_lua*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*
解码str
,str是一个编码过的URI组件。
例如:
ngx.say(ngx.unescape_uri("b%20r56+7"))
得到输出
b r56 7
ngx.encode_args
语法: str = ngx.encode_args(table)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*
根据URI的编码规则编码Lua table为一个查询参数字符串。
例如,
ngx.encode_args({foo = 3, ["b r"] = "hello world"})
产生
foo=3&b%20r=hello%20world
这个table的keys必须是Lua字符串。
同时也支持多值查询参数。使用一个lua table来作为参数值,例如:
ngx.encode_args({baz = {32, "hello"}})
得到
baz=32&baz=hello
如果这个value table为空那么影响等价于nil
值。
同时也支持boolean参数值,例如,
ngx.encode_args({a = true, b = 1})
产生
a&b=1
如果这个参数值为false,那么影响等价于nil
值。
这个方法首先在 v0.3.1rc27
版本中被介绍。
ngx.decode_args
语法: table = ngx.decode_args(str, max_args?)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
将一个编码过的查询字符串解码为一个Lua table。这个是ngx.encode_args的相反的方法。
这个可选的max_args
参数可以被用来指定通过str
参数解析的参数数量的最大值。默认情况下,默认解析100个请求参数(包括这些名字相同的)并且额外的URI参数会被默默的丢弃来防止潜在的拒绝服务攻击。
这个参数可以被设置为0来移除对接受请求参数处理的限制:
local args = ngx.decode_args(str, 0)
强烈不建议移除max_args
。
这个方法首先在v0.5.0rc29
版本中被介绍。
encode_base64
语法: newstr = ngx.encode_base64(str, no_padding?)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
编码str
成为一个base64摘要。
从0.9.16
版本开始,一个可选的boolean类型no_padding
参数可以被指定来控制是否base64摘要应该被追加到结果摘要中(默认是false
,例如,使用启用追加)。
ngx.decode_base64
语法: newstr = ngx.decode_base64(str)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
解码str
参数将base64摘要成为一个原始的形式。如果str
不是正常形式返回nil
。
ngx.crc32_short
语法: intval = ngx.crc32_short(str)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
计算str
字符串的CRC-32(循环冗余码)摘要。
这个方法对较短的str
输入(例如,小于30~60bytes)表现较好,和ngx.crc32_long相比。这个结果和ngx.crc32_long完全一样。
幕后的实现,这个只是一个薄薄的对Nginx核心中的ngx_crc32_short
的封装。
这个API首先在v0.3.1rc8
版本中被介绍。
ngx.crc32_long
语法: intval = ngx.crc32_long(str)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
计算参数str
的HMAC-SHA1摘要,并且返回使用密钥<secret_key>
的结果。
原始字节形式的HMAC-SHA1
证书将会生成,使用ngx.encode_base64,例如,如果需要的话将结果以结果的文本表示。
例如,
local key = "thisisverysecretstuff"
local src = "some string we want to sign"
local digest = ngx.hmac_sha1(key, src)
ngx.say(ngx.encode_base64(digest))
将会导致输出:
R/pvxzHC4NLtj7S+kXFg/NePTmk=
这个API需要在Nginx编译的时候开启OpenSSL库(通常在./configure
脚本里面传入--with-http_ssl_module
参数)
这个方法首先在v0.3.1rc29
版本中被介绍。
ngx.md5
语法: ngx.md5(str)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
返回str
参数的16进制的MD5摘要。
例如,
location = /md5 {
content_by_lua_block { ngx.say(ngx.md5("hello")) }
}
产生输出
5d41402abc4b2a76b9719d911017c592
查看ngx.md5_bin,如果需要原始的MD5摘要。
ngx.sha1_bin
语法: digest = ngx.sha1_bin(str)
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
返回str
参数的二级制形式的SHA-1摘要。
这个方法需要在Nginx编译时的SHA-1支持。(这个经常意味着在构建Nginx时需要安装OpenSSL)
这个方法首先在v0.5.0rc6
中被介绍。