Skip to content
Bloga Dönün
Eğitimler

Nginx location Önceliği: Eşleşme Sırası Açıklaması

nginx bir location bloğunu nasıl seçer: =, ^~, ~ ve önek eşleşmelerinin tam sırası, yapılandırmayı bozan tuzaklar ve ücretsiz çevrimiçi test aracı.

12 dakika okuma

Nginx location Önceliği: Eşleşme Sırası Açıklaması

Nginx, location bloklarınızı yukarıdan aşağıya okuyup uyan ilkinde durmaz. “location bloğum çalışmıyor” diye açılan hata kayıtlarının çoğunun ardında tek başına bu yanlış anlama vardır. Prefix location’larda bir bloğun dosyanın neresinde durduğunun hiçbir etkisi yoktur; nginx hepsini karşılaştırır ve en uzun eşleşmeyi tutar.

Gerçek nginx location önceliği, dört adımlı sabit bir sıradır:

  1. Tam eşleşme. Bir location = /path bloğu URI ile eşitse nginx onu kullanır ve durur. Ne prefix karşılaştırması ne de regex çalışır.
  2. En uzun prefix. URI’nin kendisiyle başladığı her prefix location’ı (location /path ve location ^~ /path) karşılaştırılır. En uzun olanı hatırlanır, henüz kullanılmaz.
  3. ^~ kısa devresi. Hatırlanan prefix ^~ taşıyorsa nginx regex aşamasını tamamen atlar ve o bloğu kullanır.
  4. Regex, dosya sırasına göre. Aksi hâlde ~ ve ~* location’ları yapılandırmada göründükleri sırayla denenir ve ilk eşleşme kazanır. Hiçbiri eşleşmezse 2. adımda hatırlanan prefix kullanılır.

Bu kuralların ikisi ters yönlere çeker: prefix’ler sıradan bağımsız olarak uzunluğa göre, regex’ler uzunluktan bağımsız olarak sıraya göre seçilir. Yapılandırmayı yukarıdan aşağıya okumak bu çelişkiyi hiçbir zaman görünür kılmaz. Aşağıdaki örnekler için değil de kendi dosyanız için cevap istiyorsanız, dosyayı ücretsiz nginx location test aracına yapıştırın. Araç bu sırayı yeniden oynatır ve kaybeden her bloğun hangi aşamada elendiğini gösterir. Araç tarayıcınızın içinde çalışır, dolayısıyla yapıştırdığınız üretim yapılandırması sayfadan dışarı çıkmaz. Burada anlatılan her eşleşme kuralı, ikincil yazılardan alınmak yerine çalışan bir nginx 1.27.5 üzerinde doğrulandı.

Nginx location önceliğine hızlı bakış

URI eşleşmesine beş değiştirici katılır, bir tanesi de katılmaz.

DeğiştiriciSözdizimiEşleşme ölçütüRegex aşamasını durdururTipik kullanım
=location = /pathEşitlikEvet/ veya /favicon.ico gibi kritik kod yolları
^~location ^~ /pathŞununla başlarEn uzun prefix ise evetAsla regex’e ulaşmaması gereken dizinler
~location ~ regexPCRE, büyük/küçük harfe duyarlıHayırHarf durumunun önemli olduğu uzantı yönlendirmesi
~*location ~* regexPCRE, büyük/küçük harfe duyarsızHayırHarf durumunun önemsiz olduğu uzantı yönlendirmesi
(yok)location /pathŞununla başlarHayırYola göre genel yönlendirme
@location @nameURI ile asla eşleşmezerror_page ve try_files hedefleri

Pratik kural: tam eşleşme her şeyi yener, regex prefix’i yener, prefix’ler de birbirini uzunlukla yener. Tek istisna ^~ ve göründüğünden çok daha dar kapsamlı.

Bu tablo ancak en gevşek anlamıyla bir sıralamadır. Tabloda ^~ işareti ~ işaretinin üzerinde duruyor, yine de bir ^~ bloğu düzenli olarak regex’e kaybeder; çünkü değiştiriciye yalnızca uzunluk yarışını zaten kazanmış olan prefix üzerinde bakılır.

Dört adımlı seçim algoritması

nginx location eşleşme sırasını öğrenmenin en kolay yolu, bütün kuralları aynı anda çalıştıran bir yapılandırmadır. Aşağıdaki örnek nginx belgelerinden geliyor:

server {
    location = /                   { return 200 "A\n"; }
    location /                     { return 200 "B\n"; }
    location /documents/           { return 200 "C\n"; }
    location ^~ /images/           { return 200 "D\n"; }
    location ~* \.(gif|jpg|jpeg)$  { return 200 "E\n"; }
}

Beş istek, beş farklı cevap:

İstekKazananNeden
/ATam eşleşme. Arama anında sona erer.
/index.htmlBHiçbir regex eşleşmedi, bu yüzden hatırlanan prefix kullanılır.
/documents/document.htmlC/ işaretinden daha uzun prefix.
/images/1.gifD^~ prefix aşamasını kazandı, bu yüzden regex hiç çalışmadı.
/documents/1.jpgERegex, ^~ taşımayan daha uzun bir prefix’i yendi.

Son iki satırı karşılaştırın. /images/ ve /documents/ ikisi de prefix, ikisi de eşleşiyor, ikisi de kendi isteği için en uzun eşleşme. Bir istek prefix bloğuna, öteki regex’e gidiyor. Aradaki tek fark iki karakter.

İnsanların atladığı yer 2. adımdır: nginx en uzun prefix’i kullanmaz, onu hatırlar. Blok yalnızca bir adaydır ve regex aşaması isteği hâlâ elinden alabilir. Aramayı yalnızca 1., 3. ve 4. adımlar bitirir.

Neden “en uzun prefix” yol segmentleriyle değil karakterlerle ölçülür

Prefix karşılaştırması düz bir karakter dizisi karşılaştırmasıdır. / işaretinin yol segmentlerini ayırdığını bilmez ve bir sınırda durmaz. Şu yapılandırmayı ele alalım:

server {
    location /static  { }
    location /static/ { }
}

Burada /staticfoo isteğini location /static karşılar. URI bu yedi karakterle başlar, dolayısıyla eşleşir. /static/ ise hiç eşleşmez, çünkü o konumda eğik çizgi yoktur. /static/x isteği tam tersi yöne gider ve ikisinden uzunu olan /static/ bloğuna düşer.

Yani location /static bloğu /static-backup, /staticfiles ve aynı harflerle başlayan başka her şeyi de karşılar. Kastettiğiniz şey bir dizinse sondaki eğik çizgiyi yazın ve çıplak yol için tam eşleşen bir location ekleyin:

server {
    location /static/ { root /var/www; }
    location = /static { return 301 /static/; }
}

Çoğu eğitim içeriği bunu hiç açığa çıkarmayan derli toplu yol örnekleri kullanır, dolayısıyla hata kod incelemesinden sık sık sağ çıkar. nginx location test aracı eşleşen her bloğu ve her birinin kaç karakter üzerinden eşleştiğini gösterir; kardeşlerini yutan bir prefix böylece doğrudan görünür olur.

^~ gerçekte ne anlama gelir (ve ne anlama gelmez)

nginx location ^~ değiştiricisi çoğunlukla “bu bloğu regex’lerin önüne geçirir” diye tarif edilir. Bu tarif, tehlikeli olacak kadar doğruya yakındır.

^~ işaretinin gerçekte yaptığı şey: prefix karşılaştırması sırasında hiçbir şey. Eşleşmeyi uzatmaz, bloğu diğer prefix’lerin üzerine çıkarmaz ve hangi prefix’in hatırlanacağını değiştirmez. Sonrasında, uzunluk yarışını zaten kazanmış olan tek prefix üzerinde kontrol edilir. O kazanan ^~ taşıyorsa regex aşaması atlanır. Taşımıyorsa regex aşaması her zamanki gibi çalışır.

Yani daha uzun ve sade bir prefix onu sessizce devre dışı bırakır:

server {
    location ^~ /a/    { }
    location /a/b/     { }
    location ~ \.php$  { }
}

/a/b/x.php isteğini ~ \.php$ karşılar. En uzun eşleşen prefix /a/b/ olduğu için nginx onu hatırlar; sade değiştiricisi regex aşamasına izin verir; regex önce eşleşir ve isteği alır. ^~ bloğu hâlâ dosyada duruyor, hâlâ koruyucu görünüyor ve bu istek üzerinde en ufak bir etkisi yok.

URI’yi /a/x.php olarak değiştirin, aynı yapılandırma bambaşka davranır: artık en uzun eşleşme ^~ /a/ olur, regex aşaması atlanır ve ^~ bloğu kazanır. Aynı dosya, aynı istek biçimi, zıt sonuç.

^~ işaretinin klasik kullanımı, yazılabilir bir dizini yorumlayıcıdan uzak tutmaktır:

server {
    location ^~ /uploads/ { }
    location ~ \.php$     { fastcgi_pass unix:/run/php-fpm.sock; }
}

^~ işaretini kaldırın, /uploads/evil.php isteği doğruca PHP-FPM’e gider. “Yükleme üzerinden RCE” bildirimlerinin arkasında uzun süredir bu kalıp var. Yenilmiş bir ^~ de aynı kapıya çıkar: location /uploads/thumbs/ gibi daha uzun ve sade bir prefix eklemek, altındaki her şey için deliği yeniden açar ve bunu yapan diff tümüyle zararsız görünür.

Kapsama da dikkat edin. ^~ yalnızca kendi düzeyinde tanımlanmış regex’leri bastırır; kendi bloğunun içinde iç içe duran regex’leri asla bastırmaz ve iç içe bir location üzerindeki ^~, server düzeyinde tanımlanmış bir regex’e karşı koruma sağlayamaz. Değiştiriciyi nginx location test aracında açıp kapatın ve kazananın nasıl değiştiğini izleyin. Araç, atladığı her regex’i tablodan silmek yerine etiketleyerek gösterir.

Regex location’ları: sıra, özgüllüğü yener

nginx location regex’i, büyük/küçük harfe duyarlı eşleşme için ~, duyarsız eşleşme için ~* kullanır. Buna karşılık prefix eşleşmesi Linux’ta her zaman büyük/küçük harfe duyarlıdır. (macOS gibi harf durumuna duyarsız dosya sistemlerinde nginx prefix’leri harf durumuna bakmadan karşılaştırır ve her regex location’ını ~* gibi davranmaya zorlar. Mac üzerinde geliştirip Linux’a dağıtıyorsanız bu fark, bozuk bir kuralı yayına çıkana kadar gizleyebilir.)

Regex’ler yapılandırma dosyasında göründükleri sırayla değerlendirilir ve ilk eşleşme aramayı bitirir. Özgüllüğün, uzunluğun ve çapaların sıra üzerinde hiçbir etkisi yoktur.

server {
    location ~ ^/a       { }
    location ~ ^/a/b/c$  { }
}

/a/b/c isteğini ~ ^/a alır. İkinci blok URI ile birebir eşleşiyor, çok daha kesin ve hiçbir istek için asla çalışmayacak. Bu, nginx -t komutunun tek kelime etmeden kabul ettiği ölü yapılandırmadır.

Regex’leri en özelden en genele doğru sıralayın ve listeyi kısa tutun. Üstlere yakın duran geniş bir desen altındaki her şeyi erişilemez kılar; yalnızca satırların sırasını değiştiren bir diff zararsız okunduğu için regresyon çoğu zaman bir özellik geliştirmesi sırasında değil, bir düzen toparlaması sırasında gelir.

Çapalar da aynı özeni hak eder. location ~ /admin iki uçta da çapalanmamıştır; bu yüzden URI’nin herhangi bir yerinde arama yapar ve /public/admin/x ile gönül rahatlığıyla eşleşir. Başlangıcı kastediyorsanız ~ ^/admin yazın. ~ \.php$ örneğindeki gibi yalnızca sonda çapalamak ise uzantı yönlendirmesi için normal ve doğrudur.

JavaScript kalıplarına alışmış sezgilerin yanlış bildiği birkaç PCRE ayrıntısı:

  • nginx, location desenlerini PCRE ile, UTF ya da çok satır kipi olmadan derler; dolayısıyla desenler baytlar üzerinde çalışır ve ^ yalnızca URI’nin başına çapalanır.
  • PCRE’nin $ işareti sondaki satır sonu karakterinin hemen öncesiyle de eşleşir. %0A ile biten bir URI yine de \.php$ koşulunu sağlar; bu da dosya uzantısına dayanan kuralların yanından sıyrılmanın bilinen bir yoludur.
  • JavaScript karşılığı bulunmayan yapılar PCRE’de yaygındır: atomik gruplar (?>…), sahiplenici niceleyiciler a*+, (?i) gibi satır içi değiştiriciler, [[:alpha:]] gibi POSIX sınıfları ve \A, \z, \K, \Q…\E gibi kaçış dizileri.
  • { ya da } içeren bir desen tırnak içine alınmalıdır. location ~ ^/a{2}$ satırı unknown directive "2}$" hatasıyla yüklenemez, çünkü küme parantezi belirteci sonlandırmıştır. Bunun yerine location ~ "^/a{2}$" yazın.

Yakalama grupları umduğunuz gibi çalışır ve $1’den itibaren blok içinde kullanılabilir:

upstream backend {
    server 127.0.0.1:8080;
}

server {
    location ~ ^/user/(\d+)/profile$ {
        proxy_pass http://backend/profiles/$1;
    }
}

Sorununuz desenin dosyadaki konumu değil de hâlâ desenin kendisiyse, önce Regex Test Aracı ile deneyin; Regex Cheat Sheet sözdizimini ayrıntısıyla anlatıyor.

Herkesin atladığı adım: URI normalleştirme

Herhangi bir location’a bakılmadan önce nginx istek hedefini yeniden yazar. Desenleriniz, hat üzerinden gelen baytlarla değil normalleştirilmiş yolla karşılaştırılır. Bu adımı neredeyse hiçbir kılavuz anlatmaz; oysa “location’ım eşleşmiyor” vakalarının bir bölümü tam olarak burada başlar.

Normalleştirme dört adımdan oluşur: query string’i ayırır, yolu yüzde kodundan çözer, . ve .. segmentlerini çözümler ve tekrarlanan eğik çizgileri birleştirir.

İstek hedefiNormalleştirilmiş $uriNot
//a//x/a/xTekrarlanan eğik çizgiler birleştirildi
/a/../b/x/b/x.. eşleşmeden önce çözümlendi
/a/b%2F..%2Fzz/a/zz%2F gerçek bir ayırıcıya çözülür ve çözümlemeye katılır
/a/%2e%2e/b/x/b/x%2E de çözümlemeye katılan bir noktaya çözülür
/a%20b/x/a b/x%20 gerçek bir boşluğa dönüşür
/a+b/x/a+b/x+ bir yolda boşluk değildir
/a?x=/b/aQuery string önce ayrılır
/a%3Fx=1/a?x=1%3F düz kalır; query string boştur

Çözülen üç karakter istisnadır ve yeniden yorumlanmadan olduğu gibi yazılır: %25, %23 ve %3F. /a%3Fx=1 isteği bu yüzden yolun içinde bir soru işaretiyle ve bomboş bir $args ile sonuçlanır.

İki tür hedef location seçimine hiç ulaşmaz. Kökün üstüne tırmanan .. segmentleri ve %00 gibi geçersiz bir kaçış dizisi, eşleşme başlamadan önce 400 ile reddedilir.

Bunun güvenlik tarafında bir karşılığı var. Bir location bloğunu erişim denetimi sınırı olarak kullanıyorsanız yazdığınız yol, çözümlenmiş yolla karşılaştırılır:

server {
    location /a/ { }
    location /b/ { }
}

/a/b%2F..%2Fzz isteği /a/b/ altında kalmaz. /a/zz hâline normalleşir ve location /a/ tarafından karşılanır. Burada $uri yerine ham hedef üzerinden akıl yürütmek yanlış cevap verir; erişim denetimi bağlamında “yanlış cevap”ın ise özel bir adı vardır. Bir şeyi korumak için location /admin bloğuna güvenmeden önce normalleştirilmiş yolun gerçekte ne olduğunu doğrulayın. nginx location test aracı ham hedefi, normalleştirilmiş $uri değerini ve ayrılan query string’i üç ayrı satır olarak gösterir; yalnızca kodlamanın kendisi üzerinde akıl yürütmeniz gerekiyorsa URL Kodlayıcı ve Çözücü bunu tek başına halleder.

Normalleştirmenin bir sonucu daha: query string eşleşmeye asla katılmaz. location /search?q= bloğu /search?q=1 isteğiyle eşleşemez, çünkü seçim yalnızca /search yolunu görür. Bir parametreye göre dallanmak için blok içinde $arg_name değişkenini okuyun.

Sandığınız işi yapmayan beş yapılandırma

Daha uzun ve sade bir prefix’e yenilen ^~ bloğu

Belirti: bir ^~ dizini korunuyor gibi görünür, yine de içindeki istekleri bir regex karşılar. Neden: ^~ yalnızca uzunluk yarışını zaten kazanmış olan prefix üzerinde dikkate alınır. Onun yerine daha uzun ve sade bir prefix hatırlanır ve o hiçbir şeyi bastırmaz. Çözüm: ^~ işaretini daha uzun prefix’e de koyun ya da uzun prefix’i kaldırın.

# Broken: /a/b/x.php goes to the regex
location ^~ /a/    { }
location /a/b/     { }
location ~ \.php$  { }

# Fixed: /a/b/x.php goes to ^~ /a/b/
location ^~ /a/    { }
location ^~ /a/b/  { }
location ~ \.php$  { }

Sondaki eğik çizgisi olmayan prefix’in kardeşlerini yakalaması

Belirti: tek bir dizin için tasarlanmış bir blok, yalnızca aynı harflerle başlayan yolları da karşılar. Neden: prefix eşleşmesi yol segmentlerini değil karakterleri karşılaştırır, bu yüzden location /app aynı zamanda /application ile de eşleşir. Çözüm: sondaki eğik çizgiyi yazın; çıplak yolun da karşılanması gerekiyorsa location = /app ekleyin.

Geniş regex’in altına yerleştirilen özel regex

Belirti: kesin bir kural hiç tetiklenmez ve hiçbir yerde hata görünmez. Neden: regex’ler dosya sırasına göre denenir ve ilk eşleşme aramayı bitirir; bu yüzden geniş bir desenin altındaki her şey erişilemez olur. Çözüm: özel deseni geniş olanın üstüne taşıyın ya da geniş olanı bir çapayla daraltın.

^~ sonrasına yazılan regex

Belirti: bir deny kuralı sorunsuz yüklenir ve hiçbir şeyi engellemez. Neden: ^~ bir desen değil, düz bir prefix alır. nginx hiç şikâyet etmez; blok basitçe hiçbir URI ile eşleşmez. Çözüm: regex değiştiricisini kullanın.

# Broken: matches nothing, loads without error
location ^~ "\.php$" { deny all; }

# Fixed
location ~ \.php$ { deny all; }

Query string’in eşleşmeye katıldığını varsaymak

Belirti: ? içeren bir location asla eşleşmez. Neden: query string normalleştirme sırasında ayrılır ve location seçimi yalnızca yol üzerinde çalışır. Çözüm: yol üzerinde eşleştirin ve blok içinde $arg_name değişkenine bakın.

location /search {
    if ($arg_q = "") { return 400; }
}

Hata ayıklama: hangi bloğun gerçekten kazandığını bulun

Hata ayıklama günlüğü yetkili cevabı verir, ama bunun için --with-debug ile derlenmiş bir ikili dosya gerekir; önce onu kontrol edin:

nginx -V 2>&1 | grep -o with-debug

Ardından günlüğü etkinleştirin ve seçilen bloğun adını veren satırı grep ile arayın:

error_log /var/log/nginx/debug.log debug;
grep "using configuration" /var/log/nginx/debug.log

Yanıt başlığı sondaları daha hızlıdır ve özel bir derleme gerektirmez. Her adayı etiketleyin, sonra başlıkları geri okuyun:

location ^~ /uploads/ {
    add_header X-Debug-Location "uploads-caret" always;
    return 204;
}
location ~ \.php$ {
    add_header X-Debug-Location "php-regex" always;
    return 204;
}
curl -sI --path-as-is 'http://localhost/uploads/evil.php' | grep -i x-debug-location

Burada --path-as-is önemlidir: o olmadan curl yardımsever davranıp .. ifadesini sizin adınıza çözümler ve kastettiğinizden başka bir URI’yi test etmiş olursunuz. Daha ayrıntılı bir istek kuruyorsanız cURL Komut Oluşturucu bayrakları sizin için yazar, curl Kopya Kâğıdı da gerisini anlatır. Sonda, beklediğiniz başlık yerine bir yönlendirme ya da 404 ile geri dönerse HTTP Durum Kodları başvurusu bunu genellikle hangi modülün ürettiğini söyler.

nginx -T birleştirilmiş yapılandırmanın tamamını, include dosyalarıyla birlikte yazdırır. Altı dosya bir araya geldikten sonra regex’lerinizin gerçekte hangi sırada olduğunu böyle öğrenirsiniz; bu sıra da düzenlediğiniz dosyada göründükleri sıra ile pek nadiren aynıdır.

nginx -T | grep -n "location"

Sunucuyu düzenlemeden önce arızayı nginx location test aracında yeniden üretin. Henüz dağıtmadığınız bir yapılandırma üzerinde denemeye devam etmek, yeniden yükleme turundan daha hızlıdır ve karar tablosu her bloğun hangi aşamada elendiğini adıyla söyler.

İç içe location’lar, try_files ve değiştirmedikleri şeyler

İç içe location’lar aynı algoritmayı bir düzey aşağıda çalıştırır. Bir prefix location kazandığında nginx onun çocuklarına iner ve aramayı orada tekrarlar; bu da iç içe bir regex’in üst düzeydeki regex’lerden önce denenmesi demektir:

server {
    location ~ \.php$ { }
    location /a/ {
        location ~ \.php$ { return 200 "nested\n"; }
    }
}

/a/x.php isteğini iç içe blok karşılar. İç içe yerleştirmenin daha az bariz bir etkisi daha var: genel olarak daha uzun bir prefix’i erişilemez kılabilir, çünkü her düzeyde yalnızca kazananın içine inilir. location /a/bb/ bloğu location /a/ içine yerleştirilmişse ve dış düzeyde kardeş bir location /a/b duruyorsa, /a/bb/x isteği /a/b bloğuna gider. Önce dış karşılaştırma yapılır ve onu /a/b kazanır. Hiçbir şey bulamayan bir iniş geri de dönmez; isteği ebeveyn blok elinde tutar.

try_files ve rewrite seçimin parçası değildir. Zaten kazanmış olan bloğun içinde çalışırlar ve geriye uzanıp bu sonucu değiştiremezler. Bir istek try_files yönergenizi içeren bloğa hiç ulaşmıyorsa yönerge konu dışıdır; olağan şüpheli de, prefix bloğuna sıra gelmeden isteği alan bir ~ \.php$ regex’idir. Bilmeye değer tek istisna şu: dahili bir yönlendirme (rewrite … last ya da bir error_page sıçraması) eşleşmeyi baştan başlatır, dolayısıyla yeniden yazılan URI location listesine karşı en baştan yeniden çözümlenir.

Sondaki eğik çizgi olmadan bir dizin istediğinizde aldığınız 301 de bir eşleşme hatası değildir. Bunu iki ayrı mekanizma üretir. Adı / ile biten bir location proxy_pass ya da başka bir *_pass yönergesi taşıyorsa, aynı yolun eğik çizgi içermeyen hâline yapılan istek, seçim sırasında, yani herhangi bir regex değerlendirilmeden önce 301 ile yanıtlanır; query string de korunur:

server {
    location /user/ { proxy_pass http://backend/; }
}
# GET /user?x=1  ->  301 to /user/?x=1

location = /user eklemek bu yönlendirmeyi bastırır. Bundan bağımsız olarak, statik dosya modülü bir yol diskte gerçek bir dizine çözümlendiğinde kendi 301 yanıtını üretir; bu da yapılandırmanıza değil dosya sisteminize bağlıdır.

SSS

Beş nginx location değiştiricisi nedir?

Beş nginx location değiştiricisi şunlardır: tam eşleşme için =, regex aşamasını atlayan bir prefix için ^~, sıradan bir prefix için değiştirici yokluğu, büyük/küçük harfe duyarlı regex için ~ ve duyarsız olanı için ~*. Altıncı bir biçim olan location @name ise URI eşleşmesine hiç katılmaz ve yalnızca error_page ile try_files için hedef olarak bulunur.

Tam = eşleşmesi nginx’i hızlandırır mı?

Tam eşleşen bir location aramayı anında bitirir; prefix taramasını ve her regex değerlendirmesini atlar. Kazanç gerçektir ama fark edilemeyecek kadar küçüktür. Sağlık kontrolleri ya da /favicon.ico gibi saniyede binlerce kez çağrılan uç noktalar için yazmaya değer. Sıradan sayfalar için bir yığın = bloğu ise yapılandırma karmaşıklığı olarak kazandırdığından fazlasına mal olur.

~*^/api gibi boşluksuz bir location değiştiricisi yazabilir miyim?

Evet. location ~*^/api/ ile location ~* ^/api/ tam olarak aynı anlama gelir, çünkü nginx değiştiriciyi adın önünden ayırır ve önce en uzun değiştiriciyi eşleştirir; bu yüzden ~* işareti ~ işaretinden önce tanınır. Yine de boşluğu koruyun. Yapışık bir değiştirici desenin parçasıymış gibi okunur ve inceleme sırasında insanları yanıltır.

Bir location bloğu içinde root ile alias arasındaki fark nedir?

root tüm URI’yi dizine ekler, alias ise eşleşen prefix’i dizinle değiştirir. location /static/ { root /var/www; } ile /static/x.css isteği /var/www/static/x.css dosyasını arar; alias /var/www/assets/; yönergesine geçtiğinizde /var/www/assets/x.css dosyası aranır. alias kullanırken ya hem location’a hem yola sondaki eğik çizgiyi verin ya da hiçbirine vermeyin.

Bir istek birden fazla location bloğuyla eşleşebilir mi?

Birden fazla blok eşleşebilir ama isteği tam olarak bir tanesi karşılar. nginx her prefix location’ını, gerektiğinde de her regex location’ını karşılaştırır, ardından isteği tek kazanana devreder. Kaybeden bloklardan yönerge miras alınmaz; her yerde ihtiyaç duyduğunuz şey server ya da http düzeyinde durmalı veya tekrar edilmelidir.

nginx -t hangi location’ın eşleşeceğini söyler mi?

Hayır. nginx -t sözdizimini ve yapılandırma geçerliliğini denetler; bir isteği asla benzetmez, dolayısıyla eşleşme sırası hakkında hiçbir şey bildirmez. Bir URI’nin hangi bloğa ait olduğunu öğrenmek için hata ayıklama günlüğünü okuyun, geçici bir yanıt başlığı ekleyin ya da yapılandırmayı nginx location test aracına yapıştırıp her bloğun neden kazandığını ya da kaybettiğini okuyun.

Etiketler: nginx web-server devops regex configuration