免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
第二章 Nginx+Lua開發(fā)入門

Nginx入門

本文目的是學(xué)習(xí)Nginx+Lua開發(fā),對(duì)于Nginx基本知識(shí)可以參考如下文章:

nginx啟動(dòng)、關(guān)閉、重啟

http://www.cnblogs.com/derekchen/archive/2011/02/17/1957209.html

agentzh 的 Nginx 教程

http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html

Nginx+Lua入門

http://17173ops.com/2013/11/01/17173-ngx-lua-manual.shtml

nginx 配置指令的執(zhí)行順序

http://zhongfox.github.io/blog/server/2013/05/15/nginx-exec-order/

nginx與lua的執(zhí)行順序和步驟說明

http://www.mrhaoting.com/?p=157

Nginx配置文件nginx.conf中文詳解

http://www.ha97.com/5194.html

Tengine的Nginx開發(fā)從入門到精通

http://tengine.taobao.org/book/

官方文檔

http://wiki.nginx.org/Configuration

 

Lua入門

本文目的是學(xué)習(xí)Nginx+Lua開發(fā),對(duì)于Lua基本知識(shí)可以參考如下文章:

Lua簡明教程

http://coolshell.cn/articles/10739.html

lua在線lua學(xué)習(xí)教程

http://book.luaer.cn/

Lua 5.1 參考手冊(cè)

http://www.codingnow.com/2000/download/lua_manual.html

Lua5.3 參考手冊(cè)

http://cloudwu.github.io/lua53doc/

Nginx Lua API

和一般的Web Server類似,我們需要接收請(qǐng)求、處理并輸出響應(yīng)。而對(duì)于請(qǐng)求我們需要獲取如請(qǐng)求參數(shù)、請(qǐng)求頭、Body體等信息;而對(duì)于處理就是調(diào)用相應(yīng)的Lua代碼即可;輸出響應(yīng)需要進(jìn)行響應(yīng)狀態(tài)碼、響應(yīng)頭和響應(yīng)內(nèi)容體的輸出。因此我們從如上幾個(gè)點(diǎn)出發(fā)即可。

 

接收請(qǐng)求

1、example.conf配置文件 

Java代碼  
  1. location ~ /lua_request/(\d+)/(\d+) {  
  2.     #設(shè)置nginx變量  
  3.     set $a $1;   
  4.     set $b $host;  
  5.     default_type "text/html";  
  6.     #nginx內(nèi)容處理  
  7.     content_by_lua_file /usr/example/lua/test_request.lua;  
  8.     #內(nèi)容體處理完成后調(diào)用  
  9.     echo_after_body "ngx.var.b $b";  
  10. }  

2、test_request.lua 

Java代碼  
  1. --nginx變量  
  2. local var = ngx.var  
  3. ngx.say("ngx.var.a : ", var.a, "<br/>")  
  4. ngx.say("ngx.var.b : ", var.b, "<br/>")  
  5. ngx.say("ngx.var[2] : ", var[2], "<br/>")  
  6. ngx.var.b = 2;  
  7.   
  8. ngx.say("<br/>")  
  9.   
  10. --請(qǐng)求頭  
  11. local headers = ngx.req.get_headers()  
  12. ngx.say("headers begin", "<br/>")  
  13. ngx.say("Host : ", headers["Host"], "<br/>")  
  14. ngx.say("user-agent : ", headers["user-agent"], "<br/>")  
  15. ngx.say("user-agent : ", headers.user_agent, "<br/>")  
  16. for k,v in pairs(headers) do  
  17.     if type(v) == "table" then  
  18.         ngx.say(k, " : ", table.concat(v, ","), "<br/>")  
  19.     else  
  20.         ngx.say(k, " : ", v, "<br/>")  
  21.     end  
  22. end  
  23. ngx.say("headers end", "<br/>")  
  24. ngx.say("<br/>")  
  25.   
  26. --get請(qǐng)求uri參數(shù)  
  27. ngx.say("uri args begin", "<br/>")  
  28. local uri_args = ngx.req.get_uri_args()  
  29. for k, v in pairs(uri_args) do  
  30.     if type(v) == "table" then  
  31.         ngx.say(k, " : ", table.concat(v, ", "), "<br/>")  
  32.     else  
  33.         ngx.say(k, ": ", v, "<br/>")  
  34.     end  
  35. end  
  36. ngx.say("uri args end", "<br/>")  
  37. ngx.say("<br/>")  
  38.   
  39. --post請(qǐng)求參數(shù)  
  40. ngx.req.read_body()  
  41. ngx.say("post args begin", "<br/>")  
  42. local post_args = ngx.req.get_post_args()  
  43. for k, v in pairs(post_args) do  
  44.     if type(v) == "table" then  
  45.         ngx.say(k, " : ", table.concat(v, ", "), "<br/>")  
  46.     else  
  47.         ngx.say(k, ": ", v, "<br/>")  
  48.     end  
  49. end  
  50. ngx.say("post args end", "<br/>")  
  51. ngx.say("<br/>")  
  52.   
  53. --請(qǐng)求的http協(xié)議版本  
  54. ngx.say("ngx.req.http_version : ", ngx.req.http_version(), "<br/>")  
  55. --請(qǐng)求方法  
  56. ngx.say("ngx.req.get_method : ", ngx.req.get_method(), "<br/>")  
  57. --原始的請(qǐng)求頭內(nèi)容  
  58. ngx.say("ngx.req.raw_header : ",  ngx.req.raw_header(), "<br/>")  
  59. --請(qǐng)求的body內(nèi)容體  
  60. ngx.say("ngx.req.get_body_data() : ", ngx.req.get_body_data(), "<br/>")  
  61. ngx.say("<br/>")  

ngx.var : nginx變量,如果要賦值如ngx.var.b = 2,此變量必須提前聲明;另外對(duì)于nginx location中使用正則捕獲的捕獲組可以使用ngx.var[捕獲組數(shù)字]獲??;

ngx.req.get_headers:獲取請(qǐng)求頭,默認(rèn)只獲取前100,如果想要獲取所以可以調(diào)用ngx.req.get_headers(0);獲取帶中劃線的請(qǐng)求頭時(shí)請(qǐng)使用如headers.user_agent這種方式;如果一個(gè)請(qǐng)求頭有多個(gè)值,則返回的是table;

ngx.req.get_uri_args:獲取url請(qǐng)求參數(shù),其用法和get_headers類似;

ngx.req.get_post_args:獲取post請(qǐng)求內(nèi)容體,其用法和get_headers類似,但是必須提前調(diào)用ngx.req.read_body()來讀取body體(也可以選擇在nginx配置文件使用lua_need_request_body on;開啟讀取body體,但是官方不推薦);

ngx.req.raw_header:未解析的請(qǐng)求頭字符串;

ngx.req.get_body_data:為解析的請(qǐng)求body體內(nèi)容字符串。

 

如上方法處理一般的請(qǐng)求基本夠用了。另外在讀取post內(nèi)容體時(shí)根據(jù)實(shí)際情況設(shè)置client_body_buffer_sizeclient_max_body_size來保證內(nèi)容在內(nèi)存而不是在文件中。

 

使用如下腳本測(cè)試

Java代碼  
  1. wget --post-data 'a=1&b=2' 'http://127.0.0.1/lua_request/1/2?a=3&b=4' -O -   

 

輸出響應(yīng) 

1.1、example.conf配置文件

Java代碼  
  1. location /lua_response_1 {  
  2.     default_type "text/html";  
  3.     content_by_lua_file /usr/example/lua/test_response_1.lua;  
  4. }  

1.2、test_response_1.lua 

Java代碼  
  1. --寫響應(yīng)頭  
  2. ngx.header.a = "1"  
  3. --多個(gè)響應(yīng)頭可以使用table  
  4. ngx.header.b = {"2", "3"}  
  5. --輸出響應(yīng)  
  6. ngx.say("a", "b", "<br/>")  
  7. ngx.print("c", "d", "<br/>")  
  8. --200狀態(tài)碼退出  
  9. return ngx.exit(200)  

ngx.header:輸出響應(yīng)頭;

ngx.print:輸出響應(yīng)內(nèi)容體;

ngx.say:通ngx.print,但是會(huì)最后輸出一個(gè)換行符;

ngx.exit:指定狀態(tài)碼退出。

 

2.1、example.conf配置文件

Java代碼  
  1. location /lua_response_2 {  
  2.     default_type "text/html";  
  3.     content_by_lua_file /usr/example/lua/test_response_2.lua;  
  4. }  

 

2.2、test_response_2.lua

Java代碼  
  1. ngx.redirect("http://jd.com", 302)  

ngx.redirect:重定向; 

 

ngx.status=狀態(tài)碼,設(shè)置響應(yīng)的狀態(tài)碼;ngx.resp.get_headers()獲取設(shè)置的響應(yīng)狀態(tài)碼;ngx.send_headers()發(fā)送響應(yīng)狀態(tài)碼,當(dāng)調(diào)用ngx.say/ngx.print時(shí)自動(dòng)發(fā)送響應(yīng)狀態(tài)碼;可以通過ngx.headers_sent=true判斷是否發(fā)送了響應(yīng)狀態(tài)碼。

 

其他API

1、example.conf配置文件

Java代碼  
  1. location /lua_other {  
  2.     default_type "text/html";  
  3.     content_by_lua_file /usr/example/lua/test_other.lua;  
  4. }  

 

2、test_other.lua

Java代碼  
  1. --未經(jīng)解碼的請(qǐng)求uri  
  2. local request_uri = ngx.var.request_uri;  
  3. ngx.say("request_uri : ", request_uri, "<br/>");  
  4. --解碼  
  5. ngx.say("decode request_uri : ", ngx.unescape_uri(request_uri), "<br/>");  
  6. --MD5  
  7. ngx.say("ngx.md5 : ", ngx.md5("123"), "<br/>")  
  8. --http time  
  9. ngx.say("ngx.http_time : ", ngx.http_time(ngx.time()), "<br/>")  

 

ngx.escape_uri/ngx.unescape_uri : uri編碼解碼;

ngx.encode_args/ngx.decode_args:參數(shù)編碼解碼;

ngx.encode_base64/ngx.decode_base64:BASE64編碼解碼;

ngx.re.match:nginx正則表達(dá)式匹配;

 

更多Nginx Lua API請(qǐng)參考 http://wiki.nginx.org/HttpLuaModule#Nginx_API_for_Lua。

 

Nginx全局內(nèi)存

使用過如Java的朋友可能知道如Ehcache等這種進(jìn)程內(nèi)本地緩存,Nginx是一個(gè)Master進(jìn)程多個(gè)Worker進(jìn)程的工作方式,因此我們可能需要在多個(gè)Worker進(jìn)程中共享數(shù)據(jù),那么此時(shí)就可以使用ngx.shared.DICT來實(shí)現(xiàn)全局內(nèi)存共享。

 

1、首先在nginx.conf的http部分分配內(nèi)存大小

Java代碼  
  1. #共享全局變量,在所有worker間共享  
  2. lua_shared_dict shared_data 1m;  

 

2、example.conf配置文件

Java代碼  
  1. location /lua_shared_dict {  
  2.     default_type "text/html";  
  3.     content_by_lua_file /usr/example/lua/test_lua_shared_dict.lua;  
  4. }  

3、 test_lua_shared_dict.lua

Java代碼  
  1. --1、獲取全局共享內(nèi)存變量  
  2. local shared_data = ngx.shared.shared_data  
  3.   
  4. --2、獲取字典值  
  5. local i = shared_data:get("i")  
  6. if not i then  
  7.     i = 1  
  8.     --3、惰性賦值  
  9.     shared_data:set("i", i)  
  10.     ngx.say("lazy set i ", i, "<br/>")  
  11. end  
  12. --遞增  
  13. i = shared_data:incr("i", 1)  
  14. ngx.say("i=", i, "<br/>")  

更多API請(qǐng)參考http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT。 

 

 

到此基本的Nginx Lua API就學(xué)完了,對(duì)于請(qǐng)求處理和輸出響應(yīng)如上介紹的API完全夠用了,更多API請(qǐng)參考官方文檔。

 

Nginx Lua模塊指令

Nginx共11個(gè)處理階段,而相應(yīng)的處理階段是可以做插入式處理,即可插拔式架構(gòu);另外指令可以在http、server、server if、location、location if幾個(gè)范圍進(jìn)行配置:

指令

所處處理階段

使用范圍

解釋

init_by_lua

init_by_lua_file

loading-config

http

nginx Master進(jìn)程加載配置時(shí)執(zhí)行;

通常用于初始化全局配置/預(yù)加載Lua模塊

init_worker_by_lua

init_worker_by_lua_file

starting-worker

http

每個(gè)Nginx Worker進(jìn)程啟動(dòng)時(shí)調(diào)用的計(jì)時(shí)器,如果Master進(jìn)程不允許則只會(huì)在init_by_lua之后調(diào)用;

通常用于定時(shí)拉取配置/數(shù)據(jù),或者后端服務(wù)的健康檢查

set_by_lua

set_by_lua_file

rewrite

server,server if,location,location if

設(shè)置nginx變量,可以實(shí)現(xiàn)復(fù)雜的賦值邏輯;此處是阻塞的,Lua代碼要做到非??欤?/p>

rewrite_by_lua

rewrite_by_lua_file

rewrite tail

http,server,location,location if

rrewrite階段處理,可以實(shí)現(xiàn)復(fù)雜的轉(zhuǎn)發(fā)/重定向邏輯;

access_by_lua

access_by_lua_file

access tail

http,server,location,location if

請(qǐng)求訪問階段處理,用于訪問控制

content_by_lua

content_by_lua_file

content

location,location if

內(nèi)容處理器,接收請(qǐng)求處理并輸出響應(yīng)

header_filter_by_lua

header_filter_by_lua_file

output-header-filter

http,server,location,location if

設(shè)置header和cookie

body_filter_by_lua

body_filter_by_lua_file

output-body-filter

http,server,location,location if

對(duì)響應(yīng)數(shù)據(jù)進(jìn)行過濾,比如截?cái)?、替換。

log_by_lua

log_by_lua_file

log

http,server,location,location if

log階段處理,比如記錄訪問量/統(tǒng)計(jì)平均響應(yīng)時(shí)間

 

更詳細(xì)的解釋請(qǐng)參考http://wiki.nginx.org/HttpLuaModule#Directives。如上指令很多并不常用,因此我們只拿其中的一部分做演示。

 

init_by_lua

每次Nginx重新加載配置時(shí)執(zhí)行,可以用它來完成一些耗時(shí)模塊的加載,或者初始化一些全局配置;在Master進(jìn)程創(chuàng)建Worker進(jìn)程時(shí),此指令中加載的全局變量會(huì)進(jìn)行Copy-OnWrite,即會(huì)復(fù)制到所有全局變量到Worker進(jìn)程。

 

1、nginx.conf配置文件中的http部分添加如下代碼

Java代碼  
  1. #共享全局變量,在所有worker間共享  
  2. lua_shared_dict shared_data 1m;  
  3.   
  4. init_by_lua_file /usr/example/lua/init.lua;  

  

2、init.lua

Java代碼  
  1. --初始化耗時(shí)的模塊  
  2. local redis = require 'resty.redis'  
  3. local cjson = require 'cjson'  
  4.   
  5. --全局變量,不推薦  
  6. count = 1  
  7.   
  8. --共享全局內(nèi)存  
  9. local shared_data = ngx.shared.shared_data  
  10. shared_data:set("count", 1)  

 

3、test.lua

Java代碼  
  1. count = count + 1  
  2. ngx.say("global variable : ", count)  
  3. local shared_data = ngx.shared.shared_data  
  4. ngx.say(", shared memory : ", shared_data:get("count"))  
  5. shared_data:incr("count", 1)  
  6. ngx.say("hello world")  

   

4、訪問如http://192.168.1.2/lua 會(huì)發(fā)現(xiàn)全局變量一直不變,而共享內(nèi)存一直遞增

global variable : 2 , shared memory : 8 hello world 

 

另外注意一定在生產(chǎn)環(huán)境開啟lua_code_cache,否則每個(gè)請(qǐng)求都會(huì)創(chuàng)建Lua VM實(shí)例。

 

init_worker_by_lua

用于啟動(dòng)一些定時(shí)任務(wù),比如心跳檢查,定時(shí)拉取服務(wù)器配置等等;此處的任務(wù)是跟Worker進(jìn)程數(shù)量有關(guān)系的,比如有2個(gè)Worker進(jìn)程那么就會(huì)啟動(dòng)兩個(gè)完全一樣的定時(shí)任務(wù)。

 

1、nginx.conf配置文件中的http部分添加如下代碼

Java代碼  
  1. init_worker_by_lua_file /usr/example/lua/init_worker.lua;  

  

2、init_worker.lua

Java代碼  
  1. local count = 0  
  2. local delayInSeconds = 3  
  3. local heartbeatCheck = nil  
  4.   
  5. heartbeatCheck = function(args)  
  6.    count = count + 1  
  7.    ngx.log(ngx.ERR, "do check ", count)  
  8.   
  9.    local ok, err = ngx.timer.at(delayInSeconds, heartbeatCheck)  
  10.   
  11.    if not ok then  
  12.       ngx.log(ngx.ERR, "failed to startup heartbeart worker...", err)  
  13.    end  
  14. end  
  15.   
  16. heartbeatCheck()  

ngx.timer.at:延時(shí)調(diào)用相應(yīng)的回調(diào)方法;ngx.timer.at(秒單位延時(shí),回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)列表);可以將延時(shí)設(shè)置為0即得到一個(gè)立即執(zhí)行的任務(wù),任務(wù)不會(huì)在當(dāng)前請(qǐng)求中執(zhí)行不會(huì)阻塞當(dāng)前請(qǐng)求,而是在一個(gè)輕量級(jí)線程中執(zhí)行。

 

另外根據(jù)實(shí)際情況設(shè)置如下指令

lua_max_pending_timers 1024;  #最大等待任務(wù)數(shù)

lua_max_running_timers 256;    #最大同時(shí)運(yùn)行任務(wù)數(shù)

 

 

set_by_lua 

設(shè)置nginx變量,我們用的set指令即使配合if指令也很難實(shí)現(xiàn)負(fù)責(zé)的賦值邏輯;

 

1.1、example.conf配置文件

Java代碼  
  1. location /lua_set_1 {  
  2.     default_type "text/html";  
  3.     set_by_lua_file $num /usr/example/lua/test_set_1.lua;  
  4.     echo $num;  
  5. }  

set_by_lua_file:語法set_by_lua_file $var lua_file arg1 arg2...; 在lua代碼中可以實(shí)現(xiàn)所有復(fù)雜的邏輯,但是要執(zhí)行速度很快,不要阻塞;

 

1.2、test_set_1.lua

Java代碼  
  1. local uri_args = ngx.req.get_uri_args()  
  2. local i = uri_args["i"] or 0  
  3. local j = uri_args["j"] or 0  
  4.   
  5. return i + j  

得到請(qǐng)求參數(shù)進(jìn)行相加然后返回。

 

訪問如http://192.168.1.2/lua_set_1?i=1&j=10進(jìn)行測(cè)試。 如果我們用純set指令是無法實(shí)現(xiàn)的。

 

再舉個(gè)實(shí)際例子,我們實(shí)際工作時(shí)經(jīng)常涉及到網(wǎng)站改版,有時(shí)候需要新老并存,或者切一部分流量到新版

 

2.1、首先在example.conf中使用map指令來映射host到指定nginx變量,方便我們測(cè)試

Java代碼  
  1. ############ 測(cè)試時(shí)使用的動(dòng)態(tài)請(qǐng)求  
  2. map $host $item_dynamic {  
  3.     default                     "0";  
  4.     item2014.jd.com            "1";  
  5. }  

如綁定hosts

192.168.1.2 item.jd.com;

192.168.1.2 item2014.jd.com;

 

此時(shí)我們想訪問item2014.jd.com時(shí)訪問新版,那么我們可以簡單的使用如

Java代碼  
  1. if ($item_dynamic = "1") {  
  2.    proxy_pass http://new;  
  3. }  
  4. proxy_pass http://old;  

 

但是我們想把商品編號(hào)為為8位(比如品類為圖書的)沒有改版完成,需要按照相應(yīng)規(guī)則跳轉(zhuǎn)到老版,但是其他的到新版;雖然使用if指令能實(shí)現(xiàn),但是比較麻煩,基本需要這樣

Java代碼  
  1. set jump "0";  
  2. if($item_dynamic = "1") {  
  3.     set $jump "1";  
  4. }  
  5. if(uri ~ "^/6[0-9]{7}.html") {  
  6.    set $jump "${jump}2";  
  7. }  
  8. #非強(qiáng)制訪問新版,且訪問指定范圍的商品  
  9. if (jump == "02") {  
  10.    proxy_pass http://old;  
  11. }  
  12. proxy_pass http://new;  

以上規(guī)則還是比較簡單的,如果涉及到更復(fù)雜的多重if/else或嵌套if/else實(shí)現(xiàn)起來就更痛苦了,可能需要到后端去做了;此時(shí)我們就可以借助lua了:

Java代碼  
  1. set_by_lua $to_book '  
  2.      local ngx_match = ngx.re.match  
  3.      local var = ngx.var  
  4.      local skuId = var.skuId  
  5.      local r = var.item_dynamic ~= "1" and ngx.re.match(skuId, "^[0-9]{8}$")  
  6.      if r then return "1" else return "0" end;  
  7. ';  
  8. set_by_lua $to_mvd '  
  9.      local ngx_match = ngx.re.match  
  10.      local var = ngx.var  
  11.      local skuId = var.skuId  
  12.      local r = var.item_dynamic ~= "1" and ngx.re.match(skuId, "^[0-9]{9}$")  
  13.      if r then return "1" else return "0" end;  
  14. ';  
  15. #自營圖書  
  16. if ($to_book) {  
  17.     proxy_pass http://127.0.0.1/old_book/$skuId.html;  
  18. }  
  19. #自營音像  
  20. if ($to_mvd) {  
  21.     proxy_pass http://127.0.0.1/old_mvd/$skuId.html;  
  22. }  
  23. #默認(rèn)  
  24. proxy_pass http://127.0.0.1/proxy/$skuId.html;  

  

 rewrite_by_lua 

執(zhí)行內(nèi)部URL重寫或者外部重定向,典型的如偽靜態(tài)化的URL重寫。其默認(rèn)執(zhí)行在rewrite處理階段的最后。

 

1.1、example.conf配置文件

Java代碼  
  1. location /lua_rewrite_1 {  
  2.     default_type "text/html";  
  3.     rewrite_by_lua_file /usr/example/lua/test_rewrite_1.lua;  
  4.     echo "no rewrite";  
  5. }  

 

1.2、test_rewrite_1.lua

Java代碼  
  1. if ngx.req.get_uri_args()["jump"] == "1" then  
  2.    return ngx.redirect("http://www.jd.com?jump=1", 302)  
  3. end  

當(dāng)我們請(qǐng)求http://192.168.1.2/lua_rewrite_1時(shí)發(fā)現(xiàn)沒有跳轉(zhuǎn),而請(qǐng)求http://192.168.1.2/lua_rewrite_1?jump=1時(shí)發(fā)現(xiàn)跳轉(zhuǎn)到京東首頁了。 此處需要301/302跳轉(zhuǎn)根據(jù)自己需求定義。

 

2.1、example.conf配置文件

Java代碼  
  1. location /lua_rewrite_2 {  
  2.     default_type "text/html";  
  3.     rewrite_by_lua_file /usr/example/lua/test_rewrite_2.lua;  
  4.     echo "rewrite2 uri : $uri, a : $arg_a";  
  5. }  

 

2.2、test_rewrite_2.lua

Java代碼  
  1. if ngx.req.get_uri_args()["jump"] == "1" then  
  2.    ngx.req.set_uri("/lua_rewrite_3", false);  
  3.    ngx.req.set_uri("/lua_rewrite_4", false);  
  4.    ngx.req.set_uri_args({a = 1, b = 2});  
  5. end   

ngx.req.set_uri(uri, false):可以內(nèi)部重寫uri(可以帶參數(shù)),等價(jià)于 rewrite ^ /lua_rewrite_3;通過配合if/else可以實(shí)現(xiàn) rewrite ^ /lua_rewrite_3 break;這種功能;此處兩者都是location內(nèi)部url重寫,不會(huì)重新發(fā)起新的location匹配;

ngx.req.set_uri_args:重寫請(qǐng)求參數(shù),可以是字符串(a=1&b=2)也可以是table;

 

訪問如http://192.168.1.2/lua_rewrite_2?jump=0時(shí)得到響應(yīng)

rewrite2 uri : /lua_rewrite_2, a :

 

訪問如http://192.168.1.2/lua_rewrite_2?jump=1時(shí)得到響應(yīng)

rewrite2 uri : /lua_rewrite_4, a : 1

 

3.1、example.conf配置文件

Java代碼  
  1. location /lua_rewrite_3 {  
  2.     default_type "text/html";  
  3.     rewrite_by_lua_file /usr/example/lua/test_rewrite_3.lua;  
  4.     echo "rewrite3 uri : $uri";  
  5. }  

 

3.2、test_rewrite_3.lua

Java代碼  
  1. if ngx.req.get_uri_args()["jump"] == "1" then  
  2.    ngx.req.set_uri("/lua_rewrite_4", true);  
  3.    ngx.log(ngx.ERR, "=========")  
  4.    ngx.req.set_uri_args({a = 1, b = 2});  
  5. end  

ngx.req.set_uri(uri, true):可以內(nèi)部重寫uri,即會(huì)發(fā)起新的匹配location請(qǐng)求,等價(jià)于 rewrite ^ /lua_rewrite_4 last;此處看error log是看不到我們記錄的log。

 

所以請(qǐng)求如http://192.168.1.2/lua_rewrite_3?jump=1會(huì)到新的location中得到響應(yīng),此處沒有/lua_rewrite_4,所以匹配到/lua請(qǐng)求,得到類似如下的響應(yīng)

global variable : 2 , shared memory : 1 hello world

 

rewrite ^ /lua_rewrite_3;                 等價(jià)于  ngx.req.set_uri("/lua_rewrite_3", false);

rewrite ^ /lua_rewrite_3 break;       等價(jià)于  ngx.req.set_uri("/lua_rewrite_3", false); 加 if/else判斷/break/return

rewrite ^ /lua_rewrite_4 last;           等價(jià)于  ngx.req.set_uri("/lua_rewrite_4", true);

 

注意,在使用rewrite_by_lua時(shí),開啟rewrite_log on;后也看不到相應(yīng)的rewrite log。

 

access_by_lua 

用于訪問控制,比如我們只允許內(nèi)網(wǎng)ip訪問,可以使用如下形式

Java代碼  
  1. allow     127.0.0.1;  
  2. allow     10.0.0.0/8;  
  3. allow     192.168.0.0/16;  
  4. allow     172.16.0.0/12;  
  5. deny      all;  

 

1.1、example.conf配置文件

Java代碼  
  1. location /lua_access {  
  2.     default_type "text/html";  
  3.     access_by_lua_file /usr/example/lua/test_access.lua;  
  4.     echo "access";  
  5. }  

 

 1.2、test_access.lua

Java代碼  
  1. if ngx.req.get_uri_args()["token"] ~= "123" then  
  2.    return ngx.exit(403)  
  3. end  

即如果訪問如http://192.168.1.2/lua_access?token=234將得到403 Forbidden的響應(yīng)。這樣我們可以根據(jù)如cookie/用戶token來決定是否有訪問權(quán)限。

 

 

content_by_lua   

此指令之前已經(jīng)用過了,此處就不講解了。

 

另外在使用PCRE進(jìn)行正則匹配時(shí)需要注意正則的寫法,具體規(guī)則請(qǐng)參考http://wiki.nginx.org/HttpLuaModule中的Special PCRE Sequences部分。還有其他的注意事項(xiàng)也請(qǐng)閱讀官方文檔。

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
通過nginx配置文件抵御攻擊,防御CC攻擊的經(jīng)典思路! | moon's blog
ngx_lua實(shí)現(xiàn)登錄邏輯
Docker+DockerCompose封裝web應(yīng)用的方法步驟
通過lua進(jìn)行nginx的權(quán)限控制
Nginx自定義模塊編寫:根據(jù)post參數(shù)路由到不同服務(wù)器
打破基于OpenResty的WEB安全防護(hù)(CVE
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服