想在api服务器里实现一个acl的功能,对某些请求(需要登录,需要检查appkey,需要限制频次等)做限制,对某些起始状态(比如登陆)或者终结状态(比如报错)的请求放行。

因为lua里木有switch case,因此通过一个acl_list的table去查找规则,因为需要限制的请求种类比较多,就把rule_check_token当成默认值了,一看是是这么写的:

然而却会在local token= xxxx那一行报stack overflow,想了半天也发现哪里有无限递归,因为query传进来的是http请求的query string解析出的键值对表。

把query打印出来一看,发现竟然是这个模块本身……

仔细看了文档才知道,原来__index后面的值是一个function时,lua会调用这个function去获得不存在的键,并且第一个参数是模块本身(即_M,一个table)。在这个例子里:

  1. 调用一个非默认规则的api
  2. lua调用了rule_check_token
  3. 参数query被传入了_M本身
  4. 运行到local token= xxxx这一行
  5. 这个table里(_M)又没有token这个键
  6. 回到2

所以就死循环了

 

所以要好好看文档

 

解决方法是可以套一个function

 

贴一个打印table的工具,方便调试:

可以打印出如下形式:

使用openresty请自行改写成local function和ngx.say的形式