WordPress i sieć witryn – rewrite infinite loop

Przy okazji zmian na stronie wykorzystałem możliwość uruchomienia sieci witryn. W skrócie polega to na tym, że zamiast stawiać kilka instalacji WordPressa i kolejne strony/blogi uruchamiać na nich niezależnie, tworzymy tylko jedną instalacje, która obsługuje wszystkie strony. Poszczególne strony, choć są całkowicie niezależne, współdzielą kod WordPressa i wtyczek, całość jest więc prostsza w utrzymaniu (aktualizujemy tylko jedną instalację) i wydajniejsza. Oczywiście uruchomienie sieci witryn wymaga więcej zachodu niż proste zainstalowanie WordPressa, skutkuje też kilkoma niespodziankami (np domyślne ograniczenie wielkości dodawanych plików do 1 MB…) oraz… błędami.

Niedługo po instalacji zauważyłem, że próba wyświetlenia nieistniejącego pliku znajdującego się np w katalogu wp-content zwraca błąd 500 zamiast błędu 404.  Niby jedno i drugie to błąd dający podobny efekt – pliku nie udało się wyświetlić. Jednak błąd 500 świadczy, że w międzyczasie stało się coś niedobrego. W pierwszej kolejności podejrzenia padły na nowy hosting, ale test witryny na innym serwerze wypadł podobnie – to nie wina hostingu, tylko mojej strony. Szybki rzut oka na logi dał pierwszy trop:

Problemem jest Mod Rewrite i nieprawidłowe reguły w pliku .htaccess, które tworzą niekończącą się pętlę przekierowań – najwyraźniej coś zepsułem. Ale okazuje się, że to nie ja coś zepsułem, to efekt domyślnej konfiguracji WordPressa. Proponowana przez WordPressa treść pliku .htaccess dla konfiguracji, w której kolejne witryny uruchamiane są w „wirtualnych” podkatalogach (np http://domena.pl/strona/),  wygląda tak:

Problemem są dwie wyróżnione linie, które mają obsługiwać żądania do plików w wirtualnym katalogu strony, np http://rob006.net/en/wp-content/plik.jpg to w rzeczywistości plik http://rob006.net/wp-content/plik.jpg, serwer www musi więc zwrócić plik z drugiego adresu pod pierwszym adresem, i to właśnie robią te reguły. I wszystko działa świetnie, dopóki docelowy plik istnieje. Schody zaczynają się gdy pliku nie ma, wtedy reguła się zapętla i w efekcie powstaje błąd 500. Problemem jest znak ? w wyrażeniu ([_0-9a-zA-Z-]+/)?, które odpowiada za obsługę wirtualnego katalogu dla strony. Znak ? oznacza, że element dla poprzedzającej ją reguły może wystąpić, ale nie musi. Oznacza to, że reguła działa także dla adresów bez prefiksu dla wirtualnego podkatalogu, a więc także dla adresu http://rob006.net/wp-content/plik.jpg. Jeśli nasz plik nie istnieje, reguła próbuje przekierować plik http://rob006.net/wp-content/plik.jpg na http://rob006.net/wp-content/plik.jpg (tak, dokładnie ten sam adres), a ponieważ plik nie istnieje serwer znowu szuka reguły dla pliku, znajdując tą samą regułę znowu próbującą przekierować ten sam plik na ten sam adres – mamy nasza pętlę. Rozwiązaniem jest usunięcie znaku ? z tych dwóch reguł, tak aby nie działały dla adresów bez prefiksu dla wirtualnego katalogu strony.

TL;DR

Prawidłowa konfiguracja pliku .htaccess wygląda więc tak:

 

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *