Tworzenie obiektu reprezentującego zasób serwera
Klasa dla obiektów reprezentujących zasób serwera posiada zestaw kilku publicznych metod niezbędnych do odczytania informacji o tym zasobie podczas generowaniu odpowiedzi i zawracających m.in:
-
ciało zasobu,
-
długość zasobu,
-
typ MIME zasobu,
-
datę jego ostatniej modyfikacji,
-
tag zasobu (pobierany jako hashCode() z obiektu String z zasobem)
Przy tworzeniu obiektu reprezentującego zasób serwera, branych jest pod uwagę wiele czynników. Jedną z pierwszych sprawdzanych opcji jest, czy klient odwołuje się do pojedynczego pliku czy folderu. Jeżeli odwołuje się do folderu, to następuje sprawdzenie, czy plik indeksowy istnieje (zdefiniowany w pliku konfiguracyjnym) i jeżeli tak, traktowane jest, jakby klient odwoływał się do niego bezpośrednio. Następnie sprawdzane są wskazówki z pliku konfiguracyjnego, odnośnie sposobu odczytu danego zasobu (wirtualne hosty, zasób zabezpieczony hasłem, CGI). Ważna jest tutaj kolejność sprawdzania różnych typów wskazówek, aby wskazówki mogły ze sobą się łączyć (np. zabezpieczony hasłem skrypt CGI działający na danym wirtualnym hoście). W pierwszej kolejności porównywane są wskazówki odnośnie wirtualnych hostów – po znalezieniu trafienia modyfikowany jest atrybut z lokalizacją pliku w systemie plików serwera. Następnie sprawdzane są uprawnienia, czy użytkownik może uzyskać dostęp do zasobu – jeżeli w pliku konfiguracyjnym znajduje się informacja pasująca do podanego zasobu, porównywane są nazwa użytkownika i hasło otrzymane od klienta. Jako ostatnie sprawdzane jest, czy klient odwołuje się do zasobu CGI czy zwykłego pliku.
Do sprawdzenia, czy klient posiada uprawnienia do zasobu, wykorzystywany jest mechanizm uwierzytelniania podstawowego (Basic access authentication). Klient w nagłówku „Authorization” wysyła zakodowane w Base64 nazwę użytkownika i hasło, następnie serwer porównuje tą informację z danymi zapisanymi w pliku konfiguracyjnym. Jeżeli dane się nie zgadzają, następuje przerwanie generowania odpowiedzi i zwracany jest status 401 Unauthorized.
Przy odczycie zasobu z pliku, sprawdzane są preferencje klienta odnośnie kompresji. Jeżeli klient zezwala na kompresje, odczytywany plik przepuszczany jest przez strumień GZIP (java.util.zip.GZIPOutputStream). Po odczycie następuje zmiana kodowania zasobu, na domyślne dla zasobów protokołu HTTP – ISO-8859-1.
Jeżeli zasób ma zostać wygenerowany przez zewnętrzną aplikację, należy stawić dla niej zestaw pewnych zmiennych środowiskowych. W tym celu wykorzystany został obiekt java.lang.ProcessBuilder i jako parametry przekazano do niego adres aplikacji do uruchomienia, oraz plik, który ta aplikacja ma przetworzyć. Po ustawieniu zmiennych środowiskowych następuje uruchomienie aplikacji, jako osobny proces i do jej standardowego wejścia przekazywane jest ciało zapytania. Wynik jest odczytywany ze standardowego wyjścia aplikacji. Po otrzymaniu odpowiedzi przez CGI analizowane są zwrócone nagłówki i dołączane do nich dodatkowe nagłówki, niezbędne dla zwrócenia poprawnej odpowiedzi klientowi.
W przypadku, gdy klient odwołuje się do zasobu na serwerze, który jest folderem i nie znajduje się w nim plik indeksujący, w odpowiedzi wygenerowana jest strona HTML wraz z łączami do poszczególnych plików znajdujących się w folderze – mechanizm taki jest implementowany w większości serwerów HTTP.
Serwer HTTP 