想在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的形式