Nginx konum blokları bir URL sorgu dizesiyle eşleşebilir mi?


23

Can nginx locationbloklar bir URL sorgu dizesi maç?

Örneğin, hangi konum bloğu HTTP GETisteğiyle eşleşebilir?

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

Ben nginx sadece dize karşılaştırma yapar gibi "location / git / sample-repository / info / refs? Service = git-almak-pack" tahmin ediyorum.
JosefScript

Tüm URL'nin veya soru işaretinden önceki bölümün dize karşılaştırması ( ?)?
Derek Mahar



1
Bu sorun üzerinde kendi başıma tökezlediğim bazı son açıklamalar: nginx.org/en/docs/http/request_processing.html açıkça şunu belirtiyor: "Her tür konumun, istek satırının yalnızca URI bölümünü bağımsız değişkenler olmadan test ettiğini unutmayın. dizesinde birkaç yolla verilebilir "
Thomas Urban

Yanıtlar:


37

Nginx konum blokları bir URL sorgu dizesiyle eşleşebilir mi?

Kısa cevap : Hayır.

Uzun cevap : Bu tür konum bloklarından sadece birkaçı varsa bir çözüm var.

Aşağıda, belirli sorgu dizeleriyle eşleşmesi gereken 3 konum bloğu için örnek bir geçici çözüm verilmiştir:

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

$ Query_string, $ args veya $ arg_fieldname kullanabilirsiniz. Herkes işi yapacak. Resmi dokümanlardaki error_page hakkında daha fazla bilgi edinebilirsiniz .

Uyarı: emin olun değil kullanmak standart HTTP kodlarını .


1
İlginç bir yaklaşım! Ben tavsiye edebilir $args ~ "service=git-send-pack"yerine $args = "service=git-send-pack"? Bu formda birden çok sorgu parametresi bulunur.
Derek Mahar

1
stackoverflow.com/a/40313590/107158 , sorgu dizesi bağımsız değişkenlerini ele almak için izlediğim yaklaşımı gösterir. Cevabınızı gibi, mayın kullanan ifve $arg_fieldnamefakat kullanımları rewriteyerine error_pageve location @name. Bu örnekte, içinde değiştirilecek parametre @nameiçin kullanma denemelerimin başarısız olduğunu unutmayın. rewrite
Derek Mahar

1
Bu arada, olmalı $args ~ve $arg_somerandomfield =.
Derek Mahar

1
mapDaha hızlı olan bu amaç için nginx özelliği de kullanılabilir .
Tero Kilkanen

1
@PothiKalimuthu, bunu açıkladığın için teşekkürler. Bu arada ne yaptım queryparametre feedback/{auth_key}yerine böyle bir url yolu ile değiştirmektir /feedback?auth_key=abc. Bu şekilde kullanmama gerek yok if, kullanarak konum kalıbı tanımlayabilirim regexve hepsi bu kadar.
WM

4

Bu sorunun bir yıldan fazla olduğunu biliyorum, ama son birkaç günü benzer bir sorun yüzünden beynimi yok ederek geçirdim. Genel ve özel depolar için itme ve çekme de dahil olmak üzere farklı kimlik doğrulama ve işleme kuralları istedim. Sonunda bu kadar geldim, bu yüzden paylaşacağımı düşündüm. ifZor bir direktif olduğunu biliyorum , ama bu benim için işe yarıyor gibi görünüyor:

# 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;
    # ...

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.