Các khối vị trí nginx có thể khớp với chuỗi truy vấn URL không?


23

Các khối nginx có thể khớp với chuỗi truy vấn URL không?location

Ví dụ: khối vị trí nào có thể phù hợp với GETyêu cầu HTTP

GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1

Tôi đoán "location / git / sample-repository / information / refs? Service = git-receive-pack" vì nginx chỉ thực hiện so sánh chuỗi.
JosefScript

Chuỗi so sánh toàn bộ URL hoặc chỉ phần trước dấu chấm hỏi ( ?)?
Derek Mahar



1
Một số làm rõ cuối cùng khi tôi tự mình vấp phải vấn đề này: nginx.org/en/docs/http/request_ Processing.html nêu rõ: "Lưu ý rằng các vị trí của tất cả các loại chỉ kiểm tra một phần URI của dòng yêu cầu mà không cần đối số. trong chuỗi truy vấn có thể được đưa ra theo nhiều cách "
Thomas Urban

Câu trả lời:


37

Các khối vị trí nginx có thể khớp với chuỗi truy vấn URL không?

Câu trả lời ngắn gọn : Không.

Câu trả lời dài : Có một cách giải quyết nếu chúng ta chỉ có một số ít các khối vị trí như vậy.

Đây là một cách giải quyết mẫu cho 3 khối vị trí cần khớp với các chuỗi truy vấn cụ thể:

server {
  #... common definitions such as server, root

  location / {
    error_page 418 = @queryone;
    error_page 419 = @querytwo;
    error_page 420 = @querythree;

    if ( $query_string = "service=git-receive-pack" ) { return 418; }
    if ( $args ~ "service=git-upload-pack" ) { return 419; }
    if ( $arg_somerandomfield = "somerandomvaluetomatch" ) { return 420; }

    # do the remaining stuff
    # ex: try_files $uri =404;

  }

  location @queryone {
    # do stuff when queryone matches
  }

  location @querytwo {
    # do stuff when querytwo matches
  }

  location @querythree {
    # do stuff when querythree matches
  }
}

Bạn có thể sử dụng $ query_ chuỗi, $ args hoặc $ arg_fieldname. Tất cả sẽ làm công việc. Bạn có thể biết thêm về error_page trong các tài liệu chính thức .

Cảnh báo: Vui lòng đảm bảo không sử dụng mã HTTP tiêu chuẩn .


1
Cách tiếp cận thú vị! Tôi có thể đề nghị $args ~ "service=git-send-pack"thay vì $args = "service=git-send-pack"? Biểu mẫu này chứa nhiều tham số truy vấn.
Derek Mahar

1
stackoverflow.com/a/40313590/107158 minh họa cách tiếp cận mà tôi đã làm theo để xử lý các đối số chuỗi truy vấn. Giống như câu trả lời của bạn, tôi sử dụng if$arg_fieldname, nhưng sử dụng rewritethay vì error_pagelocation @name. Lưu ý rằng trong ví dụ đó, những nỗ lực của tôi lúc sử dụng @namecho thay thế tham số trong rewriteđã không thành công.
Derek Mahar

1
Nhân tiện, nó nên $args ~$arg_somerandomfield =.
Derek Mahar

1
Người ta cũng có thể sử dụng maptính năng nginx cho mục đích này, nhanh hơn.
Tero Kilkanen

1
@PothiKalimuthu, cảm ơn vì đã làm rõ điều này. Những gì tôi đã làm trong khi đó là thay thế querytham số bằng một đường dẫn url như thế này feedback/{auth_key}thay vì /feedback?auth_key=abc. Bằng cách này, tôi không cần sử dụng if, tôi có thể xác định mẫu vị trí bằng cách sử dụng regexvà đó là mẫu đó.
WM

4

Tôi biết câu hỏi này đã hơn một năm tuổi, nhưng tôi đã dành vài ngày qua để phá hủy bộ não của mình vì một vấn đề tương tự. Tôi muốn các quy tắc xác thực và xử lý khác nhau cho các repos công khai và riêng tư, bao gồm cả đẩy và kéo. Đây là những gì tôi cuối cùng đã đưa ra, vì vậy tôi nghĩ rằng tôi muốn chia sẻ. Tôi biết iflà một chỉ thị khó khăn, nhưng điều này có vẻ hiệu quả với tôi:

# pattern for all repos, public or private, followed by username and reponame
location ~ ^(?:\/(private))?\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?$ {

    # if this is a pull request
    if ( $arg_service = "git-upload-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /upload$uri;

    }

    # if this is a push request
    if ( $arg_service = "git-receive-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /receive$uri;

    }

}

# for pulling public repos
location ~ ^\/upload(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing public repos
location ~ ^\/receive(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pulling private repos
location ~ ^\/upload\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing private repos
location ~ ^\/receive\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.