2011-10-25 34 views
7

Tôi gặp sự cố khi đối sánh một từ cụ thể trong biến nginx $ request_body. Tôi muốn để proxy vượt qua nếu yêu cầu cơ thể có một từ đặc biệt trong đó,nginx khớp từ cụ thể tại vị trí

Vì vậy, cách tiếp cận của tôi là thế này:

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

# other case... 
} 

này phù hợp với tất cả mọi thứ và nếu công trình tuyên bố, nhưng nếu tôi thay đổi regexp theo bất kỳ cách nào, tôi không thể bị trúng đòn.

Vì vậy, câu hỏi của tôi bây giờ là:

Làm thế nào để tôi cần phải xác định regexp trong nginx một cách chính xác để phù hợp với "mục tiêu" cho ví dụ?

Cảm ơn trước!

+0

Không giữ hơi thở của bạn. Bạn có thể chuyển đổi http://wiki.nginx.org/HttpCoreModule#client_body_in_single_buffer nếu nó được tính. Nhưng tôi không nghĩ rằng bạn có thể phù hợp với yêu cầu cơ thể – rzab

+0

Tôi bây giờ hiểu rằng vấn đề không phải là trong regexp, nhưng $ request_body dường như trống rỗng vào thời điểm này, tôi thậm chí đã thử các mô-đun echo cung cấp một phương pháp read_request_body, nhưng vẫn còn trống: ( – sharpner

+0

Chính xác) http://wiki.nginx.org/EmbeddedPerlModule gợi ý doc rằng $ request_body có sẵn khi nginx giữ cơ thể trong bộ nhớ như trái ngược với trong một tệp tạm thời. "Nó là cần thiết để hạn chế [ body] size với sự trợ giúp của client_max_body_size và gán đủ kích thước cho buffer bằng cách sử dụng client_body_buffer_size. "Tôi đoán nó được đề nghị đặt client_max_body_size thành giá trị client_body_buffer_size thấp hơn giá trị client_body_buffer_size" – rzab

Trả lời

2

Mã của bạn có một số vấn đề.

  1. "($ request_body ~ * (. *))" Không bao giờ phù hợp với bất cứ điều gì như đã nêu bởi người khác và vì vậy các "trường hợp khác" luôn luôn là kết quả

  2. Quan trọng hơn, nó sử dụng " proxy_pass "với" nếu "đó là ác cổ điển. http://wiki.nginx.org/IfIsEvil.

Để có được những gì bạn muốn, sử dụng các mô-đun bên ngx_lua thứ 3 (v0.3.1rc24 trở lên) ...

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

Bạn có thể nhận ngx_lua tại https://github.com/chaoslawful/lua-nginx-module/tags.

PS. Ghi nhớ rằng viết lại bởi lua luôn luôn được thực thi sau khi các chỉ thị viết lại nginx vì vậy nếu bạn đặt bất kỳ chỉ thị nào như vậy trong trường hợp khác, chúng sẽ được thực hiện trước và bạn sẽ nhận được các trò vui.

Bạn nên đặt tất cả các bài viết của mình trong ngữ cảnh lua viết lại để có kết quả nhất quán. Đây là lý do cho sự sắp xếp "if ..else..end" cho "trường hợp khác".


Bạn có thể cần phiên bản này còn


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

Tôi sẽ cố gắng cảm ơn, mặc dù tôi không muốn sử dụng lua cho điều này: ( – sharpner

+0

Tại sao không nếu tôi có thể yêu cầu? "NẾU" trong Nginx không phải là một tuyên bố điều kiện lập trình cổ điển và chỉ là một thuộc tính viết lại. nhiều sự nhầm lẫn nó sẽ gây ra, anh ta sẽ đặt tên nó khác đi khi đưa nó vào. Trong trường hợp của bạn, bạn cần câu lệnh điều kiện kịch bản cổ điển và bạn phải sử dụng một ngôn ngữ kịch bản để đạt được điều này.Không có cách nào xung quanh nó. về cơ bản có hai lựa chọn: Mô-đun Perl nhúng hoặc Mô-đun Lua. Chọn chất độc của bạn :) – Dayo

+0

có lẽ bạn đã đúng, tôi rất thích có được hành vi này mà không có bất kỳ mô-đun bên thứ ba nào;) nhưng tôi chỉ đọc tiếp là xấu: D nhờ sự giúp đỡ ... Tôi sẽ xem xét perl cho bây giờ xD – sharpner

0

Manual:

Lưu ý: đối với dấu ngoặc nhọn ({và}), vì chúng được sử dụng cả trong regexes và để kiểm soát khối, để tránh xung đột, regexes với dấu ngoặc nhọn phải được kèm theo đôi trích dẫn (hoặc dấu nháy đơn).

vì vậy hãy thử

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

Nhận xét khác:.* phù hợp với tất cả mọi thứ. Thay vào đó, tôi sẽ sử dụng \w vì Perl regex dường như có sẵn.

Hiện tại, nếu -nhấp chuột của bạn luôn sai vì vậy không có lần truy cập nào là kết quả phù hợp cho nó.

Các vấn đề liên quan