mod_rewrite na home, Gengo 0.5
Friday, April 7th, 2006Dwie dobre wiadomości i jedna zła, niekoniecznie w tej kolejności:
- wczoraj pojawiło się nowa wersja Gengo – wtyczki do Wordpressa pozwalającej na wygodne pisanie tekstów w więcej niż jednym języku. W wersji 0.5 autor, Jamie Talbot, poprawił zdaje się wszystkie błędy które znalazłem podczas prób używania 0.4 na moim blogu, więc może będę już mógł z niej skorzystać,
- niestety, podczas prób instalacji 0.5 na moim Business Server w home.pl chyba trafiłem na błąd w tutejszym serwerze WWW; szczegóły dalej,
- podczas szukania informacji na temat tego serwera dowiedziałem się, że home w końcu udostępnił mod_rewrite. Sprawdzone, działa, nareszcie będzie można korzystać z ładnych i czytelnych adresów.
Teraz o problemie z serwerem, na przykładzie pliku phpinfo.php:
if ($HTTP_GET_VARS['test'])
{
phpinfo();
}
else
{
header("Location: /phpinfo.php/en/?test=1");
}
?>
Sens działania jest prosty: otwieram w przeglądarce adres http://elksoft.pl/phpinfo.php, skrypt powinien przekierować na samego siebie z dodatkowymi parametrami i wtedy wyświetlić informacje o środowisku (funkcja phpinfo()). Tak robi, a interesujący fragment tego co wyświetla to:
| QUERY_STRING | test=1 |
| REQUEST_METHOD | GET |
| REQUEST_URI | /phpinfo.php |
| SCRIPT_NAME | /phpinfo.php |
| SCRIPT_FILENAME | /phpinfo.php |
| SCRIPT_URL | /phpinfo.php |
| SCRIPT_URI | http://elksoft.pl/phpinfo.php |
I to jest to miejsce, w którym coś tu oszukuje. Według specyfikacji po przekierowaniu lokalnym (bez podania protokołu i adresu maszyny) serwer musi utworzyć stronę identyczną z tą, jaką otrzymałbym wpisując w przeglądarce adres http://elksoft.pl/phpinfo.php/en/?test=1. A tego nie robi, bo wpisując ten adres w przeglądarce otrzymuję:
| QUERY_STRING | test=1 |
| REQUEST_METHOD | GET |
| REQUEST_URI | /phpinfo.php/en/?test=1 |
| SCRIPT_NAME | /phpinfo.php |
| SCRIPT_FILENAME | /phpinfo.php |
| SCRIPT_URL | /phpinfo.php/en/ |
| SCRIPT_URI | http://elksoft.pl/phpinfo.php/en/ |
Niestety Gengo polega na zawartości REQUEST_URI i, niestety, głupieje przy takim zachowaniu serwera. Pozostaje poszukać, może uda się to niedużym nakładem pracy obejść.
Dodane: przekombinowałem, da się to sprawdzić w sposób bardziej czytelny i dający więcej informacji. Dwa skrypty, /a.php tylko przekierowuje na /b.php?test=1, który z kolei wypisuje wyżej opisaną tabelkę. Wynik otwarcia strony http://elksoft.pl/a.php:
| QUERY_STRING | test=1 |
| REQUEST_METHOD | GET |
| REQUEST_URI | /a.php |
| SCRIPT_NAME | /b.php |
| SCRIPT_FILENAME | /b.php |
| SCRIPT_URL | /a.php |
| SCRIPT_URI | http://elksoft.pl/a.php |
Czyli na przemian, część zmiennych jest ustawiana poprawnie (QUERY_STRING, SCRIPT_NAME, SCRIPT_FILENAME), a część pozostaje z pierwszego wykonania (REQUEST_URI, SCRIPT_URL, SCRIPT_URI).
Sprawy trochę komplikuje fakt, że stara, oficjalna specyfikacja CGI nie definiuje zachowania Location aż tak dokładnie, a nowa wyszła tylko jako draft. Apache, jak się okazuje, idzie na łatwiznę i przy każdym przekierowaniu, niezależnie od tego, czy lokalnym czy z nazwą protokołu i serwera, odsyła do klienta 302 z nowym adresem, co działa bardzo dobrze, chociaż na pewno wolniej.
Jako obejście najprościej będzie wymusić przekierowania na "pełne" adresy, ze wskazaniem nazwy serwera.
