2011-12-08 16 views
17

Próbuję zoptymalizować dyrektywy dotyczące "lokalizacji" i nie mogę znaleźć dobrego sposobu na określenie, czy próba dopasowania konkretnej lokalizacji została podjęta. Używanie echo wewnątrz bloku lokalizacji tutaj nie pomaga.Jak kontrolować kolejność zgodną z NGINX "Location"?

The NGINX ngx_http_core_module documentation jest nieco mylące.

Aby użyć wyrażeń regularnych, należy użyć prefiksu:

  1. ~ Dla przypadku wrażliwej pasującego

  2. ~* Na razie niewrażliwego pasującego

Jak mecz jest wykonywana:

  1. Dyrektywy z prefiksem = dokładnie pasujące do zapytania. Jeśli zostanie znaleziony, wyszukiwanie zostanie zatrzymane.

  2. Wszystkie pozostałe dyrektywy z konwencjonalnymi ciągami. Jeśli ten mecz użyje prefiksu ^~, wyszukiwanie zostanie zatrzymane.

  3. Wyrażenia regularne, w kolejności, w jakiej są zdefiniowane w pliku konfiguracyjnym.

  4. Jeśli wynik nr 3 jest zgodny, ten wynik jest używany. W przeciwnym razie używany jest mecz z # 2.

Numer 2 tutaj mówi „konwencjonalne ciągi”, ale potem mówi, że może on być stosowany z prefiksem ^~. Czy ~ nie oznacza RegExp? Jeśli nie, w jaki sposób określa, czym jest "nie jest RegExp"?

szczególności chcę następujące:

  1. Podawać nic z dosłownej /assets bezpośrednio. STOP SEARCH.

  2. Podawaj wszystko pasujące do RegExp \.php$|/$ przez szybkie wyszukiwanie CGI.

  3. Podawać wszystko inne bezpośrednio przez dosłownym /

ten sposób jest tylko próba / mecz dla niedynamicznych plików obsługiwanych z zewnątrz aktywów.

mam:

location ^~ /assets {}  # search-terminating literal? or regex? 
location ~ \.php$|/$ {} 
location/{}    # is this match always attempted? 

Z dokumentu, to wygląda jakby rzeczywista kolejność byłaby 1-3-2, zawsze działa dosłowne / mecz. Tak, ta optymalizacja nie będzie miała żadnego wpływu na rzeczywistą wydajność, ale chcę tylko wyjaśnić pewne niejasności.

Odpowiedz

7

Z wiki:

location =/{ 
    # matches the query/only. 
    [ configuration A ] 
} 
location/{ 
    # matches any query, since all queries begin with /, but regular 
    # expressions and any longer conventional blocks will be 
    # matched first. 
    [ configuration B ] 
} 

Tak, to będzie dopasowany pierwszy: location ~ \.php$ {}

Chociaż aktywa są podawane z location/{}

Wewnątrz bloku php chcemy także zapewnić przed złośliwym przesyłaniem przed przejściem na fastcgi:

if ($uri ~* "^/uploads/") { 
    return 404; 
} 

Jak widać, nginx działa nieco inaczej niż można się było spodziewać.

+0

nadal nie jestem pewien, dlaczego regex zostanie dopasowany jako pierwszy. przyznano, że nie ma żadnych dyrektyw "=". następna to "Wszystkie pozostałe dyrektywy z konwencjonalnymi ciągami". "/" jest konwencjonalnym ciągiem znaków i powinno być dopasowane przed dowolnym wyrażeniem regularnym. Całe ciągi-następnie-regex jest tutaj domniemaną, niejawną optymalizacją nginx, co sprawia, że ​​niemożliwe jest ustalenie prawdziwej kolejności oceny. Myślę, że apache/iptables etc uzyskać to prawo przez przewidywalne przetwarzanie w tej samej kolejności zdefiniowane jako blok if/else-if/else. bez żadnych niejawnych "więcej/mniej" konkretnych zasad. – leeoniya

+0

W porządku, jest to zdecydowanie mylące, jeśli chodzi o nginx, szczególnie nginx 'if', który powinien być używany tylko do przepisywania/zwracania. Myślę, że pracują nad uproszczeniem tego. Dla twojej sytuacji będzie to wyglądało tak: 1. php regex sprawdza z zatrzymaniem, jeśli jest to mecz 2./dla dowolnej statycznej treści. – m33lky

+0

jesteś niepoprawny odnośnie zamówienia. cały punkt mający na pierwszym miejscu regułę/assets ma na celu uniknięcie narzutu uruchamiania wyrażenia php na każde żądanie. w rzeczywistości, CHCĘ służyć coś jak asset/docs/example.php bez przekazywania go przez FCGI. Obecnie używam tej konfiguracji, a regex NIE przechwytuje dla przykładu.php. jest zamówiony jako^~/assets, /, ~ \ .php $ |/$ – leeoniya

Powiązane problemy