天天看點

重新認識 nginx 配置檔案解析規則需求嘗試解決問題排查

需求

将除了

http://a.mengkang.net/read/(\d+)\.html
http://a.mengkang.net/simple/t(\d+)\.html           

之外的請求都轉發到

https://mengkang.net

首頁。

嘗試解決

server  {
        listen  80;
        server_name  a.mengkang.net;
        root  /xxx;
        index index.html index.htm index.php;
    
        set $go2dev "1";
        if ($uri ~ "^/read/(\d+)\.html") {
                set $go2dev "0";
        }

        if ($uri ~ "^/simple/t(\d+)\.html") {
                set $go2dev "0";
        }

        if ($go2dev = "1") {
                rewrite ^(.*)$  https://mengkang.net? permanent;
        }

        rewrite ^/read/(\d+)\.html /read.php?tid=$1;
        rewrite ^/simple/t(\d+)\.html$ /simple/?t$1.html break;        
}           

測試發現

# 沒問題
curl -LI http://a.mengkang.net/read/1.html 

# 跳轉
curl -LI http://a.mengkang.net/simple/t1.html
HTTP/1.1 301 Moved Permanently
...
Location: https://mengkang.net           

很詭異第一個判斷生效了,第二個判斷沒有生效麼?

問題排查

if ($uri ~ "^/simple/t(\d+)\.html") {
-                set $go2dev "0";
+                rewrite ^(.*)$  https://baidu.com/?request_uri=$request_uri&uri=$uri? permanent;
        }           

再通路

http://a.mengkang.net/simple/t1.html

跳轉到了

https://baidu.com

。說明規則沒有問題。請求資訊如下

curl -LI http://a.mengkang.net/simple/t14743.html
HTTP/1.1 301 Moved Permanently
Server: Tengine
Date: Tue, 15 Oct 2019 10:51:06 GMT
Content-Type: text/html
Content-Length: 278
Connection: keep-alive
Location: https://baidu.com/?request_uri=/simple/t14743.html&uri=/simple/t14743.html           

那問題到底出在哪呢?把剛剛的修改恢複,然後我在最後的跳轉裡增加一些日志,修改如下

if ($go2dev = "1") {
-                rewrite ^(.*)$  https://mengkang.net? permanent;
+                rewrite ^(.*)$  https://mengkang.net?request_uri=$request_uri&uri=$uri? permanent;
        }           

再次請求

curl -LI http://bbs.aliyun.com/simple/t14743.html
HTTP/1.1 301 Moved Permanently
Server: Tengine
Date: Tue, 15 Oct 2019 10:41:25 GMT
Content-Type: text/html
Content-Length: 278
Connection: close
Location: https://mengkang.net/?request_uri=/simple/t14743.html&uri=/simple/index.php

HTTP/1.1 200           

似乎發現了問題症結所在,第一次的請求确實沒有進入

if ($go2dev = "1")

判斷,直到執行了

rewrite ^/simple/t(\d+)\.html$ /simple/?t$1.html break;           

由重新比對了一遍上面的規則,第二次比對的時候,

$uri

發生了變化,不再是

/simple/t14743.html

而變成了

/simple/index.php

,是以進入最後的跳轉規則裡面。

隻有把上面的規則做如下修改才不會導緻循環比對

- rewrite ^/simple/t(\d+)\.html$ /simple/?t$1.html break;
+ rewrite ^/simple/t(\d+)\.html$ /simple/index.php?t$1.html break;           

繼續閱讀