2011-10-25 14 views
7

Tengo problemas para encontrar una palabra específica en nginx $ request_body variable. Quiero proxy de pasar si la solicitud cuerpo tiene una palabra especial en él,nginx buscar una palabra específica en la ubicación

Así que mi enfoque es la siguiente:

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

# other case... 
} 

Esto coincide con todo y el caso de obras declaración, pero si cambio de la expresión regular de ninguna manera, no puedo recibir un golpe.

Así que mi pregunta ahora es:

Cómo qué necesito para definir la expresión regular en nginx correctamente a contrastar, "objetivo", por ejemplo?

¡Gracias de antemano!

+0

No contenga la respiración. Puede alternar http://wiki.nginx.org/HttpCoreModule#client_body_in_single_buffer si cuenta. Pero no creo que pueda hacer coincidir el cuerpo de solicitud – rzab

+0

Ahora entiendo que el problema no está dentro de la expresión regular, pero que $ request_body parece estar vacío en este punto, incluso probé el módulo echo que proporciona un método read_request_body, pero sigue vacío :( – sharpner

+0

Exactamente. El documento http://wiki.nginx.org/EmbeddedPerlModule indica que $ request_body está disponible cuando nginx mantiene el cuerpo en la memoria como se opone en un archivo temporal. "Es necesario limitar su [ body] size con la ayuda de client_max_body_size y asignar el tamaño suficiente para el buffer utilizando client_body_buffer_size. "Supongo que se sugiere establecer client_max_body_size a un valor menor que client_body_buffer_size. – rzab

Respuesta

2

Su código tiene una serie de problemas.

  1. "($ request_body ~ * (. *))" No coincide con todo como se ha dicho por otra persona y por lo que el "el otro caso" es siempre el resultado

  2. Más importante aún, se utiliza " proxy_pass "con" if "que es clásicamente malvado. http://wiki.nginx.org/IfIsEvil.

para conseguir lo que desea, utilice el módulo ngx_lua 3 ª parte (v0.3.1rc24 y superior) ...

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 
    ... 
} 

, usted puede obtener ngx_lua en https://github.com/chaoslawful/lua-nginx-module/tags.

PS. Tenga en cuenta que la reescritura por lua siempre se ejecuta después de las directivas de reescritura de nginx, por lo que si coloca dichas directivas en el otro caso, se ejecutarán primero y obtendrá divertidos.

Debe poner todas sus reescrituras dentro del contexto de reescritura por lua para obtener resultados consistentes. Esta es la razón del arreglo "if ... else..end" para el "otro caso".


Es posible que necesite esta versión ya


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 
    '; 
} 
+0

Lo intentaré gracias, aunque prefiero no usar lua para esto :( – sharpner

+0

¿Por qué no si puedo preguntar? "IF" en Nginx no es una declaración condicional de programación clásica y es solo un atributo de reescritura. Si Igor hubiera sabido cómo mucha confusión causará, lo habrá nombrado de manera diferente al ponerlo. En su caso, necesita la declaración condicional de scripting clásica y tiene que usar un lenguaje de scripting para lograrlo. No hay forma de evitarlo. básicamente tiene dos opciones: el Módulo Perl incorporado o el Módulo Lua. Elija su veneno :) – Dayo

+0

probablemente tenga razón, me encantaría obtener este comportamiento sin ningún módulo de terceros;) pero acabo de leer sobre si realty es malvado: D gracias por la ayuda ... Echaré un vistazo a perl por ahora xD – sharpner

0

Manual:

Nota: para llaves ({y}), como los que se utilizan tanto en expresiones regulares y para el control del bloque, para evitar conflictos, expresiones regulares con llaves han de ser cerrado con doble citas (o comillas simples).

así que intenta

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

Otros comentarios: El código .* coincide con todo. En cambio, usaría \w, ya que Perl regex parece estar disponible.

Su cláusula-if actual es siempre incorrecta, por lo que no se obtiene ningún resultado correcto.

Cuestiones relacionadas