菜单开关

周梦康 发表于 2019-10-15 148 次浏览

需求

将除了

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;

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表