nginx匹配位置中的特定单词

时间:2011-10-25 10:53:16

标签: regex nginx

我无法匹配nginx $ request_body变量中的特定单词。 如果正文请求中有特殊字,我想代理传递,

所以我的方法是:

 location ~ \.php$ {
if ($request_body ~* (.*)) {                                        
        proxy_pass http://test.proxy;
            break;
    }

# other case...
}

这匹配所有内容,if语句有效, 但如果我以任何方式更改正则表达式,我都无法获得成功。

所以现在我的问题是:

我如何才能正确定义nginx中的正则表达式以匹配“目标”?

提前致谢!

2 个答案:

答案 0 :(得分:2)

您的代码存在许多问题。

  1. “($ request_body~ *(。*))”永远不会匹配其他人所说的任何内容,因此“其他案例”始终是结果

  2. 更重要的是,它使用“proxy_pass”和“if”这是典型的邪恶。 http://wiki.nginx.org/IfIsEvil

  3. 要获得所需内容,请使用第三方ngx_lua模块(v0.3.1rc24及以上版本)......

    location ~ \.php$ { 
        rewrite_by_lua ' 
            ngx.req.read_body() 
            local match = ngx.re.match(ngx.var.request_body, "target") 
            if match then 
                ngx.exec("@proxy");
            else 
                ngx.exec("@other_case");     
            end 
        '; 
    } 
    
    location @proxy {    
        # test.proxy stuff 
        ... 
    }
    
    location @other_case {
        # other_case stuff 
        ... 
    }
    

    您可以在https://github.com/chaoslawful/lua-nginx-module/tags获取ngx_lua。

    PS。请记住,lua的重写总是在nginx重写指令之后执行,所以如果你在其他情况下放置任何这样的指令,它们将首先被执行,你将获得有趣的东西。

    您应该将所有重写放在lua上下文的重写中,以获得一致的结果。这就是“其他案例”的“if..else..end”安排的原因。


    您可能需要此较长版本


    location ~ \.php$ { 
        rewrite_by_lua '
            --request body only available for POST requests
            if ngx.var.request_method == "POST"
                -- Try to read in request body
                ngx.req.read_body()
                -- Try to load request body data to a variable
                local req_body = ngx.req.get_body_data()
                if not req_body then 
                    -- If empty, try to get buffered file name
                    local req_body_file_name = ngx.req.get_body_file()
                    --[[If the file had been buffered, open it, 
                    read contents to our variable and close]] 
                    if req_body_file_name then
                        file = io.open(req_body_file_name)
                        req_body = file:read("*a")
                        file:close()
                    end
                end
                -- If we got request body data, test for our text
                if req_body then
                    local match = ngx.re.match(req_body, "target") 
                    if match then 
                        -- If we got a match, redirect to @proxy
                        ngx.exec("@proxy")
                    else
                         -- If no match, redirect to @other_case
                        ngx.exec("@other_case")
                    end
                end
            else
                -- Pass non "POST" requests to @other_case
                ngx.exec("@other_case")
            end
        ';
    }
    

答案 1 :(得分:0)

Manual:

  

注意:对于花括号({和}),因为它们在正则表达式中都使用   和块控制,以避免冲突,花括号的正则表达式   用双引号(或单引号)括起来。

所以试试

if ($request_body ~* "(.*)")

其他评论:代码.*与所有内容相匹配。我会使用\w,因为Perl正则表达式似乎可用。

你当前的if -clause总是错误的,所以没有命中它是正确的输出。