Apache i automatyczne wersje językowe serwisów
Napisał: Patryk Krawaczyński
26/09/2010 w Administracja Brak komentarzy. (artykuł nr 282, ilość słów: 706)
Z
łóżmy, że posiadamy prosty, ale wielojęzyczny serwis napisany w języku HTML, który jest obsługiwany przez serwer WWW Apache. Naszym celem jest automatyczne przekierowywanie po stronie serwera użytkowników z różnych krajów na odpowiednie wersje językowe znajdujące się w katalogach /en/ (angielski) /de/ (niemiecki) /ru/ (rosyjski). Pierwszym sposobem może być użycie mechanizmu geolokalizacji. Firma MaxMind udostępnia różne API dla swojej bazy, w tym również dla Apache’a.
W Slackware instalację tego modułu przeprowadzamy w następujący sposób:
tar -zxvf mod_geoip2.tar.gz cd mod_geoip2 apxs -i -a -L /usr/lib -I /usr/include -l GeoIP -c mod_geoip.c
Gdzie -I /usr/include jest lokalizacją, gdzie zainstalowany jest nagłówek GeoIP.h
oraz -L /usr/lib jest lokalizacją, gdzie zainstalowana jest biblioteka GeoIP
. Po poprawnym procesie kompilacji i instalacji na ekranie powinien pojawić się następujący komunikat:
chmod 755 /usr/lib/httpd/modules/mod_geoip.so [activating module `geoip' in /etc/httpd/httpd.conf]
Kolejną czynnością jest dodanie do pliku konfiguracyjnego Apache’a (/etc/httpd/httpd.conf
) w sekcji Dynamic Shared Object (DSO) Support informacji o załadowaniu modułu GeoIP:
LoadModule geoip_module lib/httpd/modules/mod_geoip.so
Oraz na/przy końcu – ścieżki do pliku konfiguracyjnego modułu:
# GeoIP settings Include /etc/httpd/extra/httpd-geoip.conf
W którym zawieramy odpowiednie wpisy konfiguracyjne:
<IfModule mod_geoip.c> GeoIPEnable On GeoIPDBFile /usr/share/GeoIP/GeoIP.dat </IfModule>
Opcja GeoIPDBFile wskazuje lokalizację darmowej lub komercyjnej bazy danych adresów IP krajów. W dystrybucji Debian powyższa czynność instalacji ogranicza się do wydania poleceń:
apt-get install libapache2-mod-geoip a2enmod geoip
Od tego momentu jesteśmy w stanie za pomocą wpisu w naszym wirtualnym hoście kierować ruchem pochodzącym z wybranych państw (wymagany aktywny moduł rewrite).
RewriteEngine On RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(EN|US)$ RewriteRule ^$ /en/ [R=301,L]
Wady tego rozwiązania wiążą się z faktem, że darmowa lub nawet komercyjna baza danych nie wyłapie nam wszystkich hostów, z wszystkich krajów. Istnieje, również duże prawdopodobieństwo, że dany procent osób korzysta z proxy, które delokalizuje ich geograficzne położenie lub osoby przebywające za granicą pragną odwiedzać strony w swoim narodowym języku. Uzupełnieniem tego rozwiązania jest wykrywanie wartości Accept-Language w nagłówku HTTP. W ten sposób możemy wykryć język, na jakim najbardziej “zależy” przeglądarce, czyli będzie to najprawdopodobniej narodowy język odwiedzającego:
RewriteEngine On RewriteCond %{HTTP:Accept-Language} ^en [NC] RewriteRule ^$ /en/ [R=301,L]
W przypadku używania dla każdego z serwisów osobnych, krajowych domen najwyższego poziomu reguły będą przyjmowały postać:
RewriteEngine On RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(EN|US)$ [OR] RewriteCond %{HTTP:Accept-Language} ^en [NC] RewriteRule ^(.*)$ http://nfsec.co.uk/ [R=301,L]
Dzięki połączeniu warunków przepisywania – RewriteCond za pomocą OR, możemy ustawić ich priorytety, jakie będą brane pod uwagę przy zastosowaniu reguły przepisywania – RewriteRule – tym samym uzupełniając językiem przeglądarki bazę danych adresów IP krajów. Trzecim sposobem dla rozpoznania wersji językowych może być użycie tzw. Ciasteczek (ang. cookies), które mogą być ustawiane przez serwer, a rozpoznawane przez naszą stronę internetową lub ustawiane przez naszą stronę, a rozpoznawane przez serwer Apache. Metoda ta praktykowana jest najczęściej w serwisach generowanych dynamicznie, niż w prostych stronach HTML, ze względu na fakt, że w prostych stronach można po prostu zamieścić odnośniki do odpowiednich wersji językowych. Załóżmy jednak, że nasza prosta strona w HTML posiada odnośniki w postaci flag, wyżej wymienionych wersji językowych, a po aktywacji np. angielskiej flagi – ustawione jest ciasteczko o nazwie curr_lang_code z wartością en. Dzięki ustawieniu odpowiedniej daty jego wygaśnięcia np. tydzień – zapewniamy użytkownikowi naszej strony, że zapamiętamy jego preferencje językowe, gdy wróci do nas po paru dniach:
RewriteEngine On RewriteCond %{HTTP_COOKIE} curr_lang_code=en [NC] RewriteRule ^$ /en/ [R=301,L] RewriteCond %{HTTP_COOKIE} curr_lang_code=de [NC] RewriteRule ^$ /de/ [R=301,L] RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(EN|US)$ [OR] RewriteCond %{HTTP:Accept-Language} ^en [NC] RewriteRule ^$ /en/ [R=301,L] RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^DE$ [OR] RewriteCond %{HTTP:Accept-Language} ^de [NC] RewriteRule ^$ /de/ [R=301,L]
Powyższy przykład rozdziela angielską oraz niemiecką wersję językową strony. Pierwszeństwo przed automatyczną detekcją języka ma ustawione ciasteczko przez serwis. Jeśli ciasteczko nie zostanie znalezione w przeglądarce, lub jego wartość będzie nieznana – zostanie uruchomiony mechanizm geolokalizacji – w przypadku niepowodzenia lokalizacji adresu IP – serwer przekieruje użytkownika na język preferowany w pierwszej kolejności przez przeglądarkę. Jeśli wszystkie warunki nie zostaną spełnione – zostanie załadowana standardowa treść strony z katalogu /.
Bonus:
#!/bin/sh if [ -e /usr/share/GeoIP/GeoIP.dat ] then rm /usr/share/GeoIP/GeoIP.dat fi wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz -O /usr/share/GeoIP/GeoIP.dat.gz > /dev/null 2>&1 gunzip /usr/share/GeoIP/GeoIP.dat.gz
Powyższy skrypt można zapisać pod nazwą geoip oraz umieścić w katalogu /etc/cron.monthly
, gdzie raz w miesiącu (cykl darmowej bazy) będzie aktualizowana baza danych adresów IP krajów.
Więcej informacji: RFC 1766, mod_rewrite, Język w przeglądarkach