regex - nginx 匹配位置中的特定单词

标签 regex nginx

我在匹配 nginx $request_body 变量中的特定单词时遇到问题。
如果正文请求中有特殊单词,我想代理传递,

所以我的方法是这样的:

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

# other case...
}

这匹配所有内容并且 if 语句有效,
但如果我以任何方式更改正则表达式,我就不会受到打击。

所以我现在的问题是:

我如何需要在 nginx 中正确定义正则表达式以匹配,例如“目标”?

提前致谢!

最佳答案

你的代码有很多问题。

  • "($request_body ~* (.*))"永远不会匹配其他人所说的任何内容,因此“其他情况”始终是结果
  • 更重要的是,它使用“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 重写指令之后执行,因此如果您将任何此类指令放在其他情况下,它们将首先执行,您会得到乐趣。

    你应该把所有的重写都放在 rewrite by 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
        ';
    }
    

    关于regex - nginx 匹配位置中的特定单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7888165/

    相关文章:

    nginx - Nginx "large_client_header_buffers"指令最大大小的含义

    amazon-web-services - Nginx 代理 Amazon S3 资源

    javascript - JavaScript 中的 match 是什么意思

    c# - .NET 对象列表中的正则表达式样式模式匹配

    concurrency - Openresty 中的并发模型是什么?

    php - 无法通过phpmyadmin导入数据库

    java - 使用 Spring mvc 无法在 Tomcat 和 nginx proxypass 中保持 Http session

    javascript - mongo 查找数组中至少一项不存在于另一项中的文档

    php - 对潜在的正则表达式滥用的担忧?

    regex - Grep特定IP地址