各種* _by_lua,* _by_lua_block和* _by_lua_file配置指令用作nginx.conf檔案中Lua API的網關。 下面描述的Nginx Lua API隻能在這些配置指令的上下文中運作的使用者Lua代碼中調用。API以兩個标準軟體包ngx和ndk的形式暴露給Lua。 這些軟體包位于ngx_lua中的預設全局範圍内,并且始終可在ngx_lua指令中使用。
這些包可以像這樣引入外部Lua子產品:
強烈建議使用package.seeall标志,因為其各種不良的副作用。也可以直接要求外部Lua子產品中的包:
v0.2.1rc19版本中引入了需要這些軟體包的能力。
使用者代碼中的網絡I / O操作應該隻通過Nginx Lua API調用來完成,因為Nginx事件循環可能被阻塞,否則性能會明顯下降。 磁盤操作與相對少量的資料可以使用标準的Lua io庫,但巨大的檔案讀寫應盡可能避免,因為他們可能會顯着阻止Nginx程序。 強烈建議将所有網絡和磁盤I / O操作委派給Nginx的子請求(通過ngx.location.capture方法等),以獲得最佳性能。
文法:val = ngx.arg [index]
上下文:set_by_lua *,body_filter_by_lua *
描述:當在set_by_lua *指令的上下文中使用時,此表是隻讀的,并儲存config指令的輸入參數:
這裡是一個例子
CURL 運作輸出
寫出88,32和56的和。
當在body_filter_by_lua *的上下文中使用此表時,第一個元素将輸入資料塊儲存到輸出過濾器代碼,第二個元素儲存訓示整個輸出資料流結束的“eof”标志的布爾标志。
傳遞給下遊Nginx輸出過濾器的資料塊和“eof”标志也可以通過将值直接配置設定給相應的表元素來覆寫。 當将nil或空Lua字元串值設定為ngx.arg [1]時,根本不會将資料塊傳遞到下遊Nginx輸出過濾器。
ngx.null常量是一個NULL light使用者資料,通常用于在Lua表等中表示nil值,類似于lua-cjson庫的cjson.null常量。 這個常數首先在v0.5.0rc5版本中引入。
文法:ngx.var.VAR_NAME
上下文:set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*
讀取和寫入Nginx變量值
注意,隻有已經定義的nginx變量可以寫入。 例如:
也就是說,nginx變量不能在運作中建立。一些特殊的nginx變量,如$ args和$ limit_rate可以配置設定一個值,許多其他變量不是,如$ query_string,$ arg_PARAMETER和$ http_NAME。通過寫入ngx.var [1],ngx.var [2],ngx.var [3]等,也可以通過此接口讀取Nginx正規表達式組捕獲變量$ 1,$ 2,$ 3等。将ngx.var.Foo設定為nil值将取消設定$ Foo Nginx變量。
小心當從Nginx變量讀取時,Nginx将在每個請求的記憶體池中配置設定記憶體,隻有在請求終止時才釋放記憶體。 是以,當您需要在Lua代碼中重複讀取Nginx變量時,将Nginx變量值緩存到您自己的Lua變量中,例如:
以防止(臨時)記憶體在目前請求的生存期内洩漏。 緩存結果的另一種方法是使用ngx.ctx表。未定義的NGINX變量評估為nil,而未初始化(但已定義)的NGINX變量将被評估為空的Lua字元串。此API需要相對昂貴的元方法調用,建議避免在熱代碼路徑上使用它。
上下文: init_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*
待續.........
上下文: init_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 *。
上下文: 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。
文法: print(...)
上下文: 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*
寫參數值到nginx的<code>error.log</code>與檔案<code>ngx.NOTICE</code>日志級别。它相當于
Lua的<code>nil</code>參數被接受,并導緻文字<code>"nil"</code>字元串,而Lua的布爾導緻文字<code>"true"</code>或<code>"false"</code>字元串。和<code>ngx.null</code>常數将産生<code>"null"</code>串輸出。
有一個寫死<code>2048</code>在Nginx的核心錯誤資訊的長度位元組的限制。此限制包括尾随換行符和領先的時間戳。如果郵件的大小超出此限制,Nginx的将相應截斷消息文本。這個限制可以通過編輯手動修改<code>NGX_MAX_ERROR_STR</code>的宏定義<code>src/core/ngx_log.h</code>在Nginx的源代碼樹檔案。
上下文: 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*
這個表可以被用來存儲每個請求的Lua上下文資料,并具有使用壽命相同目前請求(與Nginx的變量)。考慮下面的例子,
然後<code>GET /test</code>将産生的輸出:79
即,<code>ngx.ctx.foo</code>條目橫跨重寫,通路和請求的内容相存在。每一項要求,其中包括子請求,有它自己的表的副本。例如:
然後<code>GET /main</code>會給輸出:
在此,改性<code>ngx.ctx.blah</code>的子請求條目不會影響所述一個在父請求。這是因為他們有兩個獨立的版本<code>ngx.ctx.blah</code>。内部重定向會破壞原來的請求<code>ngx.ctx</code>資料(如果有的話)和新要求将有一個空<code>ngx.ctx</code>表。例如:
然後<code>GET /orig</code>會給:nil
而不是原來的<code>"hello"</code>值。任意的資料值,包括Lua的關閉和嵌套表,可以插入到這個“神奇”的表。它還允許自定義元方法的注冊。覆寫<code>ngx.ctx</code>用一個新的Lua表也支援,例如:
改用以下内容:
也就是說,讓調用者通過<code>ctx</code>表明确地通過一個函數的參數。
文法: res = ngx.location.capture(uri, options?)
上下文: rewrite_by_lua *,* access_by_lua,content_by_lua *
是一個同步非阻塞的NGINX子請求uri
NGINX的子請求提供了一個非常強大的方式去實作非阻塞的内部請求,或者其他的C子產品,比如 ngx_proxy, ngx_fastcgi, ngx_memc, ngx_postgres, ngx_drizzle, 甚至ngx_lua自己等等。
當然,這些子請求僅僅是模拟HTTP請求,但是并沒有額外的 HTTP/TCP,所有的程序都是C級别的
子請求完全不同與HTTP 301/302。
這裡有個基本的例子:
傳回與4插槽,一個Lua表:<code>res.status</code>,<code>res.header</code>,<code>res.body</code>,和<code>res.truncated</code>。
<code>res.status</code> 用于儲存子請求響應的響應狀态代碼。
<code>res.header</code>持有子請求的響應頭,這是一個正常的Lua表。對于多值響應頭,該值是儲存所有的順序它們出現的值的Lua(陣列)表。例如,如果子請求響應報頭包含以下幾行:
傳回一個LUA的TABLE,三個值(res.status, res.header, and res.body)。
res.header包含了所有的子請求的頭的資訊,它是一個普通的LUA TABLE。比如多個值的相應頭,他們以數組的形式按照順序傳回出現。例如:子請求包含了如下資訊:
然後<code>res.header["Set-Cookie"]</code>将被評估,以表中的值 <code>{"a=3", "foo=bar", "baz=blah"}</code>。
<code> res.body</code>持有子請求的響應體資料,這些資料可能會被截斷。你總是需要檢查<code>res.truncated</code>布爾标志,看是否<code>res.body</code>包含截斷資料。這裡的資料截斷隻能由那些不可恢複的錯誤在你的子請求一樣,遠端中止在響應體資料流的中間,或當你的子請求接收從響應體資料的讀取逾時發生過早的連接配接的情況下造成的遙控器。URI查詢串可以串聯到的URI本身,例如:
像名為位置<code>@foo</code>不允許由于nginx的核心的限制。使用與組合正常位置<code>internal</code>指令準備僅供内部使用的位置。
可選選項表可以喂的第二個參數,它支援的選項:
<code>method</code> 指定子請求的請求方法,隻接受常量一樣<code>ngx.HTTP_POST</code>。
<code>body</code> 指定子請求的請求體(僅字元串值)。
<code>args</code> 指定子請求的URI查詢參數(這兩個字元串值和Lua表被接受)
<code>vars</code> 采取持有的值設定指定的Nginx變量在子請求作為此選項的值一個Lua表。此選項最初是在引進<code>v0.3.1rc31</code>發行。
<code>copy_all_vars</code> 指定是否在目前請求所讨論的子請求的所有的Nginx變量值複制。在子請求nginx的變量的修改将不會影響目前(父)的請求。此選項最初是在引進<code>v0.3.1rc31</code>發行。
<code>share_all_vars</code> 指定是否共享的子請求與目前(父)要求所有的Nginx變量。在子請求Nginx的變量的修改将影響目前(父)的請求。啟用此選項可能會導緻因不良副作用難以調試問題,被認為是不好的,有害的。隻有啟用該選項,當你完全知道自己在做什麼。
發出一個POST子請求,例如,可以做如下:
看到比其他POST HTTP方法的常量方法。該<code>method</code>選項是<code>ngx.HTTP_GET</code>預設。
該<code>args</code>選項可以指定額外的URI參數,例如:
相當于
這在功能上等同于前面的例子。
該<code>share_all_vars</code>選項控制是否将目前請求和子請求之間共享nginx的變量。如果此選項設定為<code>true</code>,那麼目前請求和相關的子請求将共享相同的Nginx變量的作用域。是以,通過一個子請求更改了Nginx的變量将影響到目前的請求。
應小心使用此選項,變量的作用域共享可以有意想不到的副作用。的<code>args</code>,<code>vars</code>或<code>copy_all_vars</code>選項通常優于代替。這個選項被設定為<code>false</code>預設
通路位置<code>/lua</code>給:
該<code>copy_all_vars</code>選項提供父請求的Nginx的變量的副本子請求時這樣子請求發出。由這樣子請求對這些變量所做的更改不會影響父請求或任何其他子請求共享父請求的變量。
請求<code>GET /lua</code>将給輸出
請注意,如果兩者<code>share_all_vars</code>并<code>copy_all_vars</code>都設定為true,則<code>share_all_vars</code>優先。
除了上述兩個設定,有可能使用在子請求變量的值<code>vars</code>選項。這些變量的變量共享或複制已評估後設定,并且提供了對編碼它們以URL參數,并在Nginx的配置檔案反向轉義它們傳遞特定值應用于一個子請求的更有效的方法:
通路<code>/lua</code>将産生的輸出:
然後請求<code>GET /lua 輸出:</code>
請求<code>GET /lua</code>産生的輸出:bar
如果<code>body</code>沒有指定選項,且<code>always_forward_body</code>選項為false(預設值),<code>POST</code>以及<code>PUT</code>子請求将繼承父請求(如果有的話)的請求主體。
上有可能為每一個主要請求并發子請求的數目的寫死上限。在舊版本Nginx的,下限為<code>50</code>并行子請求,并在最近的版本中,Nginx的<code>1.1.x</code>開始,這是提高到<code>200</code>并發子請求。當超過此限制時,以下錯誤消息被添加到<code>error.log</code>檔案中:
文法: secs = ngx.req.start_time()
上下文: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*
文法: num = ngx.req.http_version()
背景: set_by_lua *,* rewrite_by_lua,access_by_lua *,* content_by_lua,header_filter_by_lua *
傳回目前請求作為Lua的數字的HTTP版本号。
目前可能的值是2.0,1.0,1.1和0.9。傳回<code>nil</code>了無法識别的值。
文法: str = ngx.req.raw_header(no_request_line?)
傳回由Nginx的伺服器接收到的原始原始的HTTP協定頭。
預設情況下,請求行和尾随<code>CR LF</code>終止也将包括在内。例如,
給出這樣的事情:
你可以指定可選的 <code>no_request_line</code>參數作為<code>true</code>排除從結果的請求行的值。例如
輸出是這樣的:
此方法不會在HTTP / 2請求工作尚未
URL通路位址:http://127.0.0.1/hls/4953.m3u8
nginx.conf 配置
思路圖檔:
