31
Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: [email protected] PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ IDZ DO IDZ DO ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG KATALOG KSI¥¯EK KATALOG KSI¥¯EK TWÓJ KOSZYK TWÓJ KOSZYK CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOCIACH ZAMÓW INFORMACJE O NOWOCIACH ZAMÓW CENNIK ZAMÓW CENNI K CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE SPIS TRECI SPIS TRECI DODAJ DO KOSZYKA DODAJ DO KOSZYKA KATALOG ONLINE KATALOG ONLINE mod_perl. Podrêcznik programisty Autorzy: Geoffrey Young, Paul Lindner, Randy Kobes T³umaczenie: Przemys³aw Kowalczyk ISBN: 83-7197-799-9 Tytu³ orygina³u: mod_perl Developer's Cookbook Format: B5, stron: 564 Przyk³ady na ftp: 105 kB Byæ mo¿e Perl jest najlepszym jêzykiem s³u¿¹cym do pisania skryptów CGI, ale skrypty CGI nie s¹ najlepszym sposobem tworzenia aplikacji internetowych. Potrzeba wiêkszej wydajnoci, lepszej integracji z serwerem WWW i pe³niejszego wykorzystania jego mo¿liwoci doprowadzi³a do stworzenia modu³u mod_perl. Pozwala on na pisanie modu³ów serwera Apache w Perlu i na pe³ny dostêp do funkcji API Apache'a z poziomu Perla. mod_perl jest bardzo rozbudowany, dziêki czemu daje programicie ogromne mo¿liwoci. Ksi¹¿ka „mod_perl. Kompendium programisty” bêdzie nieocenion¹ pomoc¹ w poznawaniu jego potencja³u. Nauczysz siê z niej podstaw mod_perla, a gdy ju¿ je opanujesz, poznasz tajniki pisania du¿ych i skomplikowanych aplikacji. W ksi¹¿ce opisano miêdzy innymi: • Instalacjê i konfiguracjê mod_perla • Komunikacjê mod_perla z Apache • Dzia³ania na adresach URL • Obs³ugê plików w rodowisku mod_perla • Tworzenie w³asnych aplikacji w oparciu o mod_perla • Osi¹gania maksymalnej wydajnoci aplikacji u¿ywaj¹cych mod_perla • Dodatkowe modu³y wspó³pracuj¹ce z mod_perlem Po przeczytaniu tej ksi¹¿ki uzyskasz now¹ perspektywê na programowanie aplikacji sieciowych w Perlu. Programici Slashdot.org, Internet Movie Database i Wired wybrali mod_perl jako platformê do tworzenia aplikacji. Mo¿e i Ty powiniene pójæ w ich lady?

mod_perl. Podręcznik programisty

Embed Size (px)

DESCRIPTION

Być może Perl jest najlepszym językiem służącym do pisania skryptów CGI, ale skrypty CGI nie są najlepszym sposobem tworzenia aplikacji internetowych. Potrzeba większej wydajności, lepszej integracji z serwerem WWW i pełniejszego wykorzystania jego możliwości doprowadziła do stworzenia modułu mod_perl. Pozwala on na pisanie modułów serwera Apache w Perlu i na pełny dostęp do funkcji API Apache"a z poziomu Perla.mod_perl jest bardzo rozbudowany, dzięki czemu daje programiście ogromne możliwości. Książka "mod_perl. Podręcznik programisty" będzie nieocenioną pomocą w poznawaniu jego potencjału. Nauczysz się z niej podstaw mod_perla, a gdy już je opanujesz, poznasz tajniki pisania dużych i skomplikowanych aplikacji. W książce opisano między innymi: * Instalację i konfigurację mod_perla * Komunikację mod_perla z Apache * Działania na adresach URL * Obsługę plików w środowisku mod_perla * Tworzenie własnych aplikacji w oparciu o mod_perla * Osiągania maksymalnej wydajności aplikacji używających mod_perla * Dodatkowe moduły współpracujące z mod_perlemPo przeczytaniu tej książki uzyskasz nową perspektywę na programowanie aplikacji sieciowych w Perlu. Programiści Slashdot.org, Internet Movie Database i Wired wybrali mod_perl jako platformę do tworzenia aplikacji. Może i Ty powinieneś pójść w ich ślady?

Citation preview

Page 1: mod_perl. Podręcznik programisty

Wydawnictwo Helion

ul. Chopina 6

44-100 Gliwice

tel. (32)230-98-63

e-mail: [email protected]

PRZYK£ADOWY ROZDZIA£PRZYK£ADOWY ROZDZIA£

IDZ DOIDZ DO

ZAMÓW DRUKOWANY KATALOGZAMÓW DRUKOWANY KATALOG

KATALOG KSI¥¯EKKATALOG KSI¥¯EK

TWÓJ KOSZYKTWÓJ KOSZYK

CENNIK I INFORMACJECENNIK I INFORMACJE

ZAMÓW INFORMACJEO NOWO�CIACH

ZAMÓW INFORMACJEO NOWO�CIACH

ZAMÓW CENNIKZAMÓW CENNIK

CZYTELNIACZYTELNIA

FRAGMENTY KSI¥¯EK ONLINEFRAGMENTY KSI¥¯EK ONLINE

SPIS TRE�CISPIS TRE�CI

DODAJ DO KOSZYKADODAJ DO KOSZYKA

KATALOG ONLINEKATALOG ONLINE

mod_perl. Podrêcznik

programistyAutorzy: Geoffrey Young, Paul Lindner, Randy Kobes

T³umaczenie: Przemys³aw Kowalczyk

ISBN: 83-7197-799-9

Tytu³ orygina³u: mod_perl Developer's Cookbook

Format: B5, stron: 564

Przyk³ady na ftp: 105 kB

Byæ mo¿e Perl jest najlepszym jêzykiem s³u¿¹cym do pisania skryptów CGI, ale skrypty

CGI nie s¹ najlepszym sposobem tworzenia aplikacji internetowych. Potrzeba wiêkszej

wydajno�ci, lepszej integracji z serwerem WWW i pe³niejszego wykorzystania jego

mo¿liwo�ci doprowadzi³a do stworzenia modu³u mod_perl. Pozwala on na pisanie

modu³ów serwera Apache w Perlu i na pe³ny dostêp do funkcji API Apache'a z poziomu

Perla.

mod_perl jest bardzo rozbudowany, dziêki czemu daje programi�cie ogromne

mo¿liwo�ci. Ksi¹¿ka „mod_perl. Kompendium programisty” bêdzie nieocenion¹ pomoc¹

w poznawaniu jego potencja³u. Nauczysz siê z niej podstaw mod_perla, a gdy ju¿ je

opanujesz, poznasz tajniki pisania du¿ych i skomplikowanych aplikacji.

W ksi¹¿ce opisano miêdzy innymi:

• Instalacjê i konfiguracjê mod_perla

• Komunikacjê mod_perla z Apache

• Dzia³ania na adresach URL

• Obs³ugê plików w �rodowisku mod_perla

• Tworzenie w³asnych aplikacji w oparciu o mod_perla

• Osi¹gania maksymalnej wydajno�ci aplikacji u¿ywaj¹cych mod_perla

• Dodatkowe modu³y wspó³pracuj¹ce z mod_perlem

Po przeczytaniu tej ksi¹¿ki uzyskasz now¹ perspektywê na programowanie aplikacji

sieciowych w Perlu. Programi�ci Slashdot.org, Internet Movie Database i Wired wybrali

mod_perl jako platformê do tworzenia aplikacji. Mo¿e i Ty powiniene� pój�æ w ich

�lady?

Page 2: mod_perl. Podręcznik programisty

Spis treściPodziękowania................................................................................................................................................. 9

O Autorach ..................................................................................................................................................... 12

Przedmowa ...................................................................................................................................................... 13

Wprowadzenie ............................................................................................................................................... 15

Część I Instalacja i konfiguracja................................................................................. 19

Rozdział 1. Instalacja modułu mod_perl ..................................................................................................................... 21Wprowadzenie...................................................................................................................211.1. Dystrybucja binarna dla Uniksa .................................................................................221.2. Instalacja w systemie Windows .................................................................................251.3. Instalacja w systemie Mac OS X................................................................................271.4. Kompilacja w systemie Unix .....................................................................................271.5. Kompilacja w systemie Windows ..............................................................................311.6. Kompilacja w systemie Mac OS X ............................................................................351.7. Kompilacja modułu mod_perl jako biblioteki dzielonej............................................371.8. Testowanie instalacji ..................................................................................................381.9. Zmiana katalogów instalacji serwera Apache............................................................391.10. Dodawanie modułu mod_perl do działającego serwera Apache .............................401.11. Ponowne użycie opcji kompilacji ............................................................................401.12. Odtwarzanie instalacji modułu mod_perl ................................................................411.13. Instalacja modułu mod_perl na wielu komputerach ................................................421.14. Sprawdzanie istniejącego serwera............................................................................451.15. Instalacja modułów serwera Apache z archiwum CPAN ........................................461.16. Śledzenie rozwoju modułu mod_perl.......................................................................471.17. Więcej niż dostęp przez CVS...................................................................................481.18. Kompilacja modułu mod_perl przy użyciu innej wersji Perla.................................50

Page 3: mod_perl. Podręcznik programisty

4 mod_perl. Kompendium programisty

Rozdział 2. Konfigurowanie modułu mod_perl ....................................................................................................... 53Wprowadzenie...................................................................................................................532.1. Przenoszenie skryptów CGI .......................................................................................532.2. Moduł Apache::Registry ............................................................................................552.3. Skrypt startup.pl .........................................................................................................582.4. Dzielenie przestrzeni nazw w środowisku Apache::Registry ....................................612.5. Wczesne ładowanie skryptów w środowisku Apache::Registry................................622.6. Ustawianie zmiennych środowiskowych CGI ...........................................................632.7. Ustawianie innych zmiennych środowiskowych .......................................................642.8. Ustawianie opcji interpretera Perla ............................................................................652.9. Bloki BEGIN i END w skrypcie startup.pl ................................................................662.10. Zarządzanie własnymi bibliotekami.........................................................................672.11. Trwałe połączenia z bazą danych.............................................................................692.12. Wcześniejsze nawiązywanie połączeń .....................................................................702.13. Nietrwałe połączenia do bazy danych w środowisku Apache::DBI ........................722.14. Ustawianie zmiennych specyficznych dla modułu mod_perl ..................................732.15. Ustawianie bardziej skomplikowanych zmiennych .................................................742.16. Dynamiczna konfiguracja serwera Apache..............................................................752.17. Zachowywanie kolejności w sekcjach <Perl> .........................................................772.18. Używanie opcji w wierszu poleceń..........................................................................782.19. Uruchamianie podwójnego serwera .........................................................................792.20. Używanie modułu mod_proxy do przekazywania żądań

do serwera Apache z modułem mod_perl ................................................................802.21. Używanie modułu mod_proxy_add_forward...........................................................80

Część II Interfejs API modułu mod_perl.................................................................. 83

Rozdział 3. Obiekt żądania ..............................................................................................................................................87Wprowadzenie...................................................................................................................873.1. Obiekt żądania............................................................................................................873.2. Komunikat żądania HTTP..........................................................................................893.3. Żądanie klienta ...........................................................................................................913.4. Dostęp do nagłówków żądania...................................................................................923.5. Dostęp do pól formularzy HTML ..............................................................................953.6. Dane wysłane metodą POST......................................................................................973.7. Obsługa cookies .........................................................................................................983.8. Obsługa plików wysyłanych na serwer....................................................................1003.9. Ustawianie nagłówków odpowiedzi serwera ...........................................................1033.10. Sterowanie pamięcią podręczną .............................................................................1053.11. Wysyłanie nagłówków odpowiedzi serwera ..........................................................1063.12. Ustawianie statusu odpowiedzi ..............................................................................1083.13. Ustawianie nagłówków w przypadku błędu...........................................................1113.14. Nagłówki o wielu wartościach ...............................................................................1133.15. Żądania wewnętrzne...............................................................................................1153.16. Ustawianie nagłówków żądania wewnętrznego.....................................................1173.17. Rozpoznawanie żądań wewnętrznych....................................................................1183.18. Metoda HTTP żądania ...........................................................................................1183.19. Dostęp do obiektu żądania z podprogramu XS......................................................120

Page 4: mod_perl. Podręcznik programisty

Spis treści 5

Rozdział 4. Komunikacja z serwerem Apache....................................................................................................... 127Wprowadzenie.................................................................................................................1274.1. Obiekt Apache::Server .............................................................................................1274.2. Symulowanie dyrektyw IfModule i IfDefine ...........................................................1304.3. Dostęp do dyrektyw ServerRoot i DocumentRoot...................................................1324.4. Zapis do dziennika błędów.......................................................................................1344.5. Dostęp do dyrektywy ErrorLog................................................................................1364.6. Wartość LogLevel ....................................................................................................1384.7. Obiekt Apache::Connection .....................................................................................1404.8. Zdalne adresy IP i nazwy serwerów.........................................................................1414.9. Wykrywanie zerwania połączenia............................................................................1434.10. Zamykanie procesu potomnego serwera Apache...................................................145

Rozdział 5. Przetwarzanie adresów URI ................................................................................................................. 149Wprowadzenie.................................................................................................................1495.1. Żądany adres URI.....................................................................................................1505.2. Określanie dyrektywy <Location> dla adresu URI .................................................1525.3. Zmiana żądanego adresu URI ..................................................................................1555.4. Konstruowanie nowego adresu URI ........................................................................1575.5. Kodowanie znaków specjalnych w adresie URI ......................................................1595.6. Wymuszenie typu MIME za pomocą adresu URI ...................................................1615.7. Pobieranie zawartości żądania wewnętrznego .........................................................1625.8. Użycie klasy Apache::Util poza środowiskiem modułu mod_perl ..........................166

Rozdział 6. Obsługa plików .......................................................................................................................................... 169Wprowadzenie.................................................................................................................1696.1. Tworzenie uchwytów plików...................................................................................1706.2. Tworzenie plików tymczasowych............................................................................1726.3. Wysyłanie całego pliku ............................................................................................1736.4. Wczytywanie zawartości plików do zmiennych ......................................................1766.5. Pobieranie informacji o żądanym pliku ...................................................................1766.6. Nagłówki warunkowe ..............................................................................................1806.7. Żądania fragmentów plików.....................................................................................1836.8. Nagłówki związane z datami....................................................................................1876.9. Opróżnianie buforów wyjściowych .........................................................................1886.10. Przekierowanie uchwytów plików wyjściowych ...................................................190

Rozdział 7. Tworzenie programów obsługi ..............................................................................................................193Wprowadzenie.................................................................................................................1937.1. Tworzenie programu obsługi ...................................................................................1947.2. Konfiguracja programów obsługi.............................................................................1977.3. Dodawanie niewielkich programów obsługi............................................................1997.4. Przygotowanie modułu do publikacji.......................................................................2017.5. Tworzenie archiwum programu TAR ......................................................................2027.6. Tworzenie binarnej dystrybucji PPM.......................................................................2047.7. Testowanie modułu ..................................................................................................2077.8. Własne dyrektywy konfiguracyjne...........................................................................2147.9. Rozszerzanie prototypów własnych dyrektyw.........................................................2237.10. Łączenie własnych dyrektyw .................................................................................2257.11. Zastępowanie dyrektyw rdzeniowych....................................................................2317.12. Dodawanie znaczników serwera ............................................................................2367.13. Publikowanie modułu w archiwum CPAN ............................................................237

Page 5: mod_perl. Podręcznik programisty

6 mod_perl. Kompendium programisty

Rozdział 8. Współpraca z programami obsługi ..................................................................................................... 239Wprowadzenie.................................................................................................................2398.1. Wykrywanie zmian programów obsługi ..................................................................2398.2. Dzielenie danych wewnątrz procesu potomnego .....................................................2418.3. Tworzenie dzielonego bufora...................................................................................2448.4. Zachowywanie stanu ................................................................................................2478.5. Wewnętrzne przekierowania ....................................................................................2518.6. Tworzenie własnych stron o błędach .......................................................................2548.7. Przywracanie domyślnych stron o błędach ..............................................................2578.8. Łańcuchy programów obsługi..................................................................................2598.9. Łańcuchy programów obsługi w języku C...............................................................2618.10. Dostęp do zmiennych środowiskowych.................................................................2648.11. Dzielenie danych między fazami ...........................................................................2658.12. Określanie aktualnej fazy żądania..........................................................................2688.13. Dane konfiguracyjne modułu Perla........................................................................2698.14. Dane konfiguracyjne modułu języka C..................................................................270

Rozdział 9. Dostrajanie serwera Apache i modułu mod_perl ......................................................................... 275Wprowadzenie.................................................................................................................2759.1. Zbieranie podstawowych informacji o serwerze......................................................2779.2. Tworzenie raportu zużycia pamięci .........................................................................2819.3. Zużycie pamięci przez procesy serwera Apache......................................................2839.4. Bardziej szczegółowe informacje o zużyciu pamięci przez procesy serwera..........2849.5. Zużycie pamięci przez moduły Perla .......................................................................2869.6. Redukcja narzutu przy imporcie modułów ..............................................................2889.7. Zmniejszanie całkowitego zużycia pamięci .............................................................2899.8. Zwiększanie obszaru pamięci dzielonej ...................................................................2919.9. Regulacja liczby procesów potomnych....................................................................2939.10. Ograniczanie wzrostu zużycia pamięci przez procesy...........................................2949.11. Zamykanie niekontrolowanych procesów..............................................................2969.12. Profilowanie programów obsługi ...........................................................................2989.13. Znajdowanie wąskich gardeł wydajności...............................................................2999.14. Dostrajanie wydajności serwera.............................................................................3019.15. Serwer Apache jako serwer proxy .........................................................................3059.16. Używanie programu uruchomieniowego Perla z modułem mod_perl...................3089.17. Wyszukiwanie błędów w skryptach Apache::Registry..........................................3109.18. Redukcja narzutu uruchomieniowego....................................................................3119.19. Wyszukiwanie błędów przy naruszeniach segmentacji .........................................313

Rozdział 10. Programowanie obiektowe przy użyciu modułu mod_perl......................................................315Wprowadzenie.................................................................................................................31510.1. Tworzenie klas i obiektów .....................................................................................31610.2. Dziedziczenie metod ..............................................................................................31810.3. Tworzenie obiektowych programów obsługi.........................................................32110.4. Używanie obiektowych programów obsługi..........................................................32310.5. Dziedziczenie po klasie Apache.............................................................................32610.6. Dziedziczenie po klasie Apache przy użyciu modułów XS...................................32810.7. Dziedziczenie po klasie Apache::Registry.............................................................33010.8. Dziedziczenie po klasie Apache::Request..............................................................333

Page 6: mod_perl. Podręcznik programisty

Spis treści 7

Część III Oprogramowywanie cyklu życiowego serwera Apache...............339

Rozdział 11. PerlInitHandler .......................................................................................................................................... 345Wprowadzenie.................................................................................................................34511.1. Przetwarzanie każdego żądania..............................................................................34611.2. Przetwarzanie każdego żądania w danej dyrektywie zbiorczej .............................34711.3. Mierzenie czasu żądania.........................................................................................34811.4. Przerywanie cyklu obsługi żądania ........................................................................350

Rozdział 12. PerlTransHandler .......................................................................................................................................353Wprowadzenie.................................................................................................................35312.1. Żądania pliku favicon.ico.......................................................................................35412.2. Rozpoznawanie serwerów wirtualnych w żądaniach.............................................35512.3. Identyfikatory sesji w adresach URL.....................................................................35812.4. Współdzielenie dyrektywy DocumentRoot ...........................................................36012.5. Sterowanie wbudowanym serwerem proxy ...........................................................36212.6. Redukcja wywołań funkcji stat()............................................................................364

Rozdział 13. PerlAccessHandler, PerlAuthenHandler i PerlAuthzHandler .................................................371Wprowadzenie.................................................................................................................37113.1. Prosta kontrola dostępu ..........................................................................................37213.2. Ograniczanie dostępu „chciwym” klientom...........................................................37513.3. Identyfikacja podstawowa......................................................................................37613.4. Ustawianie danych użytkownika............................................................................37913.5. Warunkowa identyfikacja ......................................................................................38113.6. Autoryzacja użytkownika.......................................................................................38313.7. Tworzenie własnego mechanizmu autoryzacji ......................................................38613.8. Identyfikacja przy użyciu funkcji skrótu................................................................392

Rozdział 14. PerlTypeHandler i PerlFixupHandler ............................................................................................. 401Wprowadzenie.................................................................................................................40114.1. Przywracanie domyślnego programu obsługi generowania zawartości.................40214.2. Wybór programu obsługi na podstawie rozszerzenia nazwy pliku........................40414.3. Zmiana typu MIME i programu obsługi ................................................................40914.4. Zmiana domyślnych typów MIME ........................................................................41314.5. Własny mechanizm buforujący..............................................................................414

Rozdział 15. PerlHandler .................................................................................................................................................. 421Wprowadzenie.................................................................................................................42115.1. Podstawowy PerlHandler .......................................................................................42215.2. Zarządzanie wieloma programami obsługi typu PerlHandler................................42515.3. Wysyłanie poczty ...................................................................................................42715.4. Filtrowanie generowanej zawartości ......................................................................43115.5. Zapobieganie atakom skryptowym ........................................................................43515.6. Moduł Text::Template............................................................................................43915.7. Moduł HTML::Template........................................................................................44315.8. Moduł Apache::ASP ..............................................................................................44515.9. Pakiet Template Toolkit .........................................................................................45015.10. Moduł HTML::Embperl.......................................................................................45415.11. Moduł HTML::Mason..........................................................................................45815.12. Generowanie dokumentów XML.........................................................................461

Page 7: mod_perl. Podręcznik programisty

8 mod_perl. Kompendium programisty

15.13. Generowanie ogólnych dokumentów XML.........................................................46415.14. Dokumenty XML i arkusze XSLT.......................................................................46715.15. Pakiet AxKit.........................................................................................................47015.16. Tworzenie serwera SOAP ....................................................................................472

Rozdział 16. PerlLogHandler i PerlCleanupHandler............................................................................................ 481Wprowadzenie.................................................................................................................48116.1. Dziennik w bazie danych .......................................................................................48216.2. Dziennik w zwykłym pliku ....................................................................................48516.3. Zmiana wiersza żądania .........................................................................................48816.4. Zapisywanie niestandardowych informacji............................................................48916.5. Rejestrowanie warunkowe .....................................................................................49016.6. Przechwytywanie błędów.......................................................................................491

Rozdział 17. PerlChildInitHandler, PerlChildExitHandler, PerlRestartHandler

i PerlDispatchHandler.............................................................................................................................499Wprowadzenie.................................................................................................................49917.1. Konfiguracja kodu poza obsługą żądania...............................................................50117.2. Uruchamianie kodu podczas restartu serwera........................................................50317.3. Jednokrotne ładowanie konfiguracji ......................................................................50417.4. Przeładowywanie skryptów Registry w procesie nadrzędnym..............................50617.5. Identyfikacja procesów potomnych .......................................................................50717.6. Wczesne łączenie ze źródłem danych ....................................................................50917.7. Śledzenie użycia modułów Perla............................................................................51117.8. Zastępowanie programów obsługi .........................................................................512

Dodatki.......................................................................................................................................517

Dodatek A Dostępne punkty zaczepienia i opcje kompilacji modułu mod_perl .....................................519Punkty zaczepienia modułu mod_perl ............................................................................519Opcje kompilacji modułu mod_perl................................................................................523

Dodatek B Dostępne stałe ..............................................................................................................................................531Wartości zwracane przez programy obsługi ...................................................................531Stałe określone przez protokół HTTP .............................................................................531Stałe używane przez programy obsługi dyrektyw...........................................................533Stałe sterujące zapisem w dzienniku...............................................................................536Stałe serwera ...................................................................................................................536

Dodatek C Zasoby związane z modułem mod_perl............................................................................................ 537Zasoby sieciowe ..............................................................................................................537Książki.............................................................................................................................540

Skorowidz ..................................................................................................................................................... 543

Page 8: mod_perl. Podręcznik programisty

Obsługa plików

WprowadzeniePodczas obsługi każdego żądania serwera Apache nasza aplikacji musi czytać i przetwarzaćzawartość plików na dysku. W Perlu można to zrealizować wieloma sposobami. Aplikacje WWWjednak, a w szczególności aplikacje modułu mod_perl, mają specjalne wymagania, które naj-lepiej wypełnia nowy interfejs obsługi plików. Zadania w tym rozdziale przedstawiają typoweproblemy i rozwiązania spotykane przy posługiwaniu się plikami.

Apache zawiera interfejs API obsługi plików zoptymalizowany pod kątem działania serweraWWW. Moduł mod_perl udostępnia elegancki, obiektowy interfejs do tych funkcji w klasie����������. Korzystając z tej klasy, nasza aplikacja zyska na jakości.

� Działa szybciej. Klasa ���������� używa skompilowanego kodu języka C,aby wykonać większość zadań.

� Jest bardziej stabilna. Pliki tymczasowe i zasoby tworzone dla żądania sąautomatycznie czyszczone.

� Pełniej wykorzystuje możliwości protokołu HTTP. Klasa ������ (a w konsekwencjitakże ����������) obsługuje zaawansowane możliwości protokołu HTTP/1.1,takie jak żądania fragmentów (byte range) plików czy nowe nagłówki.

Ten rozdział zawiera także recepty na typowe sytuacje.

� Konwersja dat modyfikacji plików (i dowolnych innych) na odpowiednie nagłówki HTTP.

� Opróżnienie bufora danych wyjściowych i wysłanie ich do klienta przedzakończeniem przetwarzania.

� Przekierowanie wyjścia istniejącego uchwytu pliku (jak �� ��� czy �� ���).

Page 9: mod_perl. Podręcznik programisty

170 Część II � Interfejs API modułu mod_perl

Omówienie klasy ���������� stanowi koniec naszego wprowadzenia do klas rdzeniowychmodułu mod_perl. Kolejne rozdziały pokażą, jak posługiwać się nimi w konkretnych aplikacjach.

6.1. Tworzenie uchwytów plikówChcemy utworzyć nowy uchwyt pliku do czytania lub pisania.

RozwiązanieUżyjemy metod ����� i ������ klasy ����������, która stanowi obiektowy interfejs douchwytów plików (filehandle).

Wydruk 6.1. Przykładowy program obsługi

����������� ��� ����������������������������������

�����������

����� ����!

��"#�$��%���&��

��'��������"#�() � #����*�����#�����#�*�� ��� �+#��,��"#�$&�%����������-. ���$�-.&��� �"���

������� ������������ �����$&�

��'�/�*��0���+�����+� ��,,,��$�-.�� ������� �����$�-.�� �& �$&��

��'�������+����+�"#*�1����#������*�2�3����� �+�"#*� #�����"��#�+ ��2��'�*�� #��#�� +��+�+���45���� ��+ �0��,������� ����6

KomentarzJest wiele sposobów obsługi wejścia-wyjścia plikowego w Perlu. Najczęściej używa się mo-dułów FileHandle.pm i ������ oraz funkcji ������ i ���������. Klasa ���������� stanowijeszcze jedno rozwiązanie, dostarczając obiektowy interfejs do uchwytów plików, podobny domodułów FileHandle.pm i ������. Stylistycznie klasa ���������� dobrze wkomponowujesię w moduł mod_perl, ponieważ większą część jego interfejsu API stanowią wywołania metod

Page 10: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 171

różnych klas, więc „obiektowy” dostęp do plików rozjaśnia kod. Dodatkowo klasa ���������� posiada zaletę w postaci większej wydajności, nie musimy się więc przejmować spowol-nieniem operacji na plikach, jak w przypadku modułu ������.

Konstruktor ����� zwraca nowy uchwyt pliku. Jeżeli parametrem jest nazwa pliku, jak w na-szym przykładzie (wydruk 6.1), wywołuje metodę ������������������ i zwraca otwartyuchwyt pliku. Domyślnie pliki są otwierane w trybie tylko do odczytu (znacznik ��� ����),ale możemy użyć tych samych parametrów w metodzie ������������������ co w perlowejfunkcji ������. Chodzi tu oczywiście o starszą wersję tej funkcji, nie tę z trzema parametrami,wprowadzoną w wersji 5.6 Perla.

"#�$&�%����������-. ���

'��������"#�����#���� �� ����#�� ��,$&-.��� �7..7,$�-.���8��������������8��7��5�9���������57������������ �:;<=;<�;<<�<�

Jedną z zalet używania konstruktora ����� w stosunku do metody ������ jest zwracanie war-tości �!�" w przypadku błędu, co pozwala stosować prosty mechanizm obsługi sytuacji wy-jątkowych.

Poniższa tabela przedstawia listę metod klasy ����������.

Tabela 6.1. Metody klasy Apache::File

Metoda Opis

���� Tworzy nowy uchwyt pliku, opcjonalnie otwierając wskazany plik.

��� �� Otwiera wskazany plik.

������� Zamyka uchwyt pliku.

�"�&����� Tworzy plik tymczasowy i zwraca jego nazwę i uchwyt w kontekście listowym

albo tylko uchwyt w kontekście skalarnym.

Chociaż klasa ���������� umożliwia wygodną obsługę uchwytów plików, jak również do-datkowe korzyści, które opisujemy w kolejnych zadaniach, posiada niestety pewne ogranicze-nia. Między innymi nie implementuje wszystkich metod, których moglibyśmy wymagać oduchwytu pliku. To utrudnienie wychodzi na jaw w zadaniu 6.6, kiedy klasa ����##�$� wy-maga wywołania metody %"������&��. Oczywiście uchwyt pliku, utworzony przez klasę �����������, jest normalnym, perlowym uchwytem pliku, więc zawsze możemy na nim wywo-łać perlową funkcję ���&�� w sposób „nieobiektowy”.

Innym utrudnieniem jest nakład czasu w trakcie wykonywania spowodowany przez interfejsobiektowy. Jeżeli zdecydujemy się pozostać przy perlowej funkcji ������, możemy skorzystaćz automatycznego tworzenia anonimowych referencji (autovivification), wprowadzonegow wersji 5.6 Perla, co pozwala opuścić wywołanie metody ��'(���$����'��. Jeżeli jednak uży-wamy starszej wersji Perla i chcemy użyć funkcji ������, moduł mod_perl udostępnia metodę��������$����'��, byśmy nie musieli dołączać modułu ��'(� do naszego programu obsługi.

"#�$&�%������-.5� �#"���� �$&2�>��#�� �,�"�>��

Page 11: mod_perl. Podręcznik programisty

172 Część II � Interfejs API modułu mod_perl

6.2. Tworzenie plików tymczasowychChcemy utworzyć plik tymczasowy, który istnieje tylko podczas przetwarzania żądania.

RozwiązanieUżyjemy metody )'�"��� z klasy ����������.

Wydruk 6.2. Moduł Rules.pm

���*�5�����*���*<�����

����������� ��� ��������������?���������

�����������

����� ����!

��"#�$��%���&��

��"#��$&��� �"�2�$&��%����������-.�"�&����

��"#�$� &�%�?��������-. ���&��� �"��%.�$&��� �"���

��"#�$��5��%�$� &-. �����5��

��$��5�-.���� 5�$� &-.&� �2�@A2�B2�CCA2�>"� ������3����&�3 #D>��

��$� &-.������

��'��������"#���*�E �*����*�� �����+)�*�,�����*�$&2�A2�A�

��$�-.������ �� ���� 5��-��$&��� �"���

��$�-.�� ������� ���7���������� 9� &7��

��'�F#�G�"#����*,��$�-.�� �& �$&��

��'�?��*�$&��� �"��3��������� #����+�*�H�+� ���() � ��,������� ����6B�

Page 12: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 173

KomentarzCzasem potrzebujemy pliku tymczasowego, na przykład kiedy tworzymy duży dokument i niechcemy przechowywać go w pamięci przed wysłaniem do klienta. W takiej sytuacji (i w po-dobnych) metoda )'�"��� stanowi wygodny sposób tworzenia plików tymczasowych, któresą usuwane po zakończeniu przetwarzania żądania.

Metoda )'�"��� może zostać wywołana na dwa sposoby: w kontekście listowym zwracanazwę nowego pliku i otwarty uchwyt, a w kontekście skalarnym — tylko uchwyt. W obuprzypadkach plik otwierany jest przy użyciu znaczników ��� *�+��,����+���-,�, czyli w try-bie do odczytu i zapisu.

Pliki tymczasowe utworzone w ten sposób różnią od plików tworzonych przez metodę ������������)'�"��� pod dwoma względami: mamy dostęp do nazwy pliku, a sam plik nie jestusuwany, kiedy jego uchwyt wychodzi z zasięgu widoczności. Są to wymarzone cechy dla pro-gramistów modułu mod_perl, pozwalające łatwo użyć tego samego pliku tymczasowegow różnych fazach przetwarzania żądania. Możemy na przykład skorzystać z metody ���)����,opisanej w zadaniu 8.11, do przekazania nazwy lub uchwytu do pliku tymczasowego w łańcuchuprogramów obsługi.

'�I���"�4��3�"#� �+�4����*���#"�+�����5��> ���JE ��3>,$�-.� ������;K?�LM;�%.�$&��� �"���

Warto też zauważyć, że wywołanie funkcji ���&�� nie jest niezbędne w naszym przykładzie(wydruk 6.2), gdyż moduł . ���,/��)� nie korzysta bezpośrednio z uchwytu pliku utworzo-nego za pomocą metody )'�"���. W ogólnym przypadku jednak jeżeli chcemy pisać do wy-generowanego pliku tymczasowego (albo jakiegokolwiek innego), a później wypisać jego za-wartość przy użyciu tego samego uchwytu pliku, musimy użyć perlowej funkcji ���&��, abyustawić wskaźnik pliku z powrotem na jego początku, jak w poniższym przykładzie (wydruk 6.3).

Wydruk 6.3. Użycie funkcji seek()

"#�$&�%����������-.�"�&����

��� ��$&�7KJ��"��L�"���,7�

'�?�+�������"#���*�E �*����*�� �����+)��*,���*�$&2�A2�A�

'�F#�#G�"#����*� ��*��� ��,$�-.�� �& �$&��

6.3. Wysyłanie całego plikuChcemy wysłać cały plik do klienta.

Page 13: mod_perl. Podręcznik programisty

174 Część II � Interfejs API modułu mod_perl

RozwiązanieUżyjemy metody �����������!�"!��.

Wydruk 6.4. Przykładowy skrypt

"#�$&�%����������-. ���7� ���� �,�"�7��

�&��"#�$�� 5��%�$�-.����"�7�� 5�7���!��'�F#�#G�"#��+401����*�,,,��$�-.�� �& �$&2�$�� 5���6�����!��'�,,,�������G#,��$�-.�� �& �$&�6

KomentarzWszystkie dotychczasowe przykłady w tym rozdziale używały metody %/�����!�"!��, abyprzesłać plik bezpośrednio do klienta. Zazwyczaj można się spotkać z użyciem funkcji�/�)�� do wypisania zawartości pliku, jak na przykład:

��� �������N$&.�

Ponieważ jednak wysyłanie pliku do klienta jest często potrzebne w aplikacjach WWW, me-toda ���!�"!�� pozwala na wykonanie tej czynności łatwo i efektywnie. Jej parametrem jestotwarty uchwyt pliku; używa ona interfejsu API języka C serwera Apache, aby wysłać za-wartość pliku do przeglądarki klienta możliwie wydajnie. Zwraca długość w bajtach przesła-nych danych na wypadek, gdybyśmy chcieli znać różnicę między liczbą wszystkich wysła-nych bajtów a pochodzących z pliku. Drugim opcjonalnym parametrem może być liczbabajtów do wysłania, używa się go rzadko, ale w pewnych warunkach jest użyteczny, co możnazobaczyć w zadaniu 6.7.

Rozważmy na przykład sytuację, w której chcielibyśmy uruchomić usługę, umożliwiającą(zaufanemu) klientowi zażądanie zawartości pliku konfiguracyjnego serwera. Moglibyśmyzrealizować to za pomocą następującego programu obsługi (wydruk 6.5).

Wydruk 6.5. Moduł ViewConf.pm

���*�5�����*���*=����� &�

����������� ��� ���������:;<=;<�;<<�<��������������������������

�����������

����� ����!

��"#�$��%���&��

Page 14: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 175

��'�?������"#� �+�4�() � �5�����*�,��"#�$&����%�$�-.&��� �"��

��'����� ��"#���42�(����� ��3�,��� ������-&�$�-.&� &���!����$�-.��5�������>?��*�$&���� ������ ��3�,>����������� �������������6

��'��������"#����#�����*�,��"#�$&�%����������-. ���$&�����

��� ������$&��!����$�-.��5�������>����"�( �������+#1����*��$&����$D>����������� �:;<=;<�;<<�<���6

��$�-.�� ������� ���7��O�9���� 7��

��'�?������"#���+"�������*�����#�#G�"#�5�,��"#�$��+��%�-������"#�$�� ��%�$�-.�� �& �$&��

��$�-.��� ��NN>;��>��

----------------------------------------------------<�+"�������*��$��+�F#�G� ����3�J��$�� �----------------------------------------------------

;��

������� ����6B�

Aby uruchomić moduł ,��&(��&��0��,��", należy użyć następujących dyrektyw w plikuhttpd.conf:

?���K� �������*���*=����� &

������9�� &�9���9�����9�����9�� &NM������ �9�� &.��:��P� ��������-��������?���P� �������*���*=����� &��'�����4���#�*��+�+��&� #��E�J �G,���� ����� #2��������� #�&��"������������&��"���������N9M������ .

W ten sposób klient może otrzymać tekstową wersję pliku konfiguracyjnego serwera, przykła-dowo httpd.conf, żądając adresu URI http://localhost/conf/httpd.conf. Pod zawartością pliku ra-portowany jest jeszcze rozmiar pliku na dysku serwera i liczba wysłanych bajtów. Te dwieliczby mogą się różnić, na przykład w systemie Win32, z powodu użycia różnych sekwencjinowego wiersza.

Page 15: mod_perl. Podręcznik programisty

176 Część II � Interfejs API modułu mod_perl

6.4. Wczytywanie zawartości plików do zmiennychChcemy przechowywać zawartość całego pliku w zmiennej, aby móc na niej operować.

RozwiązanieUżyjemy perlowego idiomu ���1%2, aby „wessać” (slurp) cały plik, ale należy przy tym za-chować ostrożność!

"#�$&�%����������-. ���$&��� �"���

"#�$&����%� ��!������$9��N$&.6

KomentarzLokalizacja specjalnej zmiennej %2 jest to perlowy idiom, służący do wczytywania całej za-wartości pliku do zmiennej tekstowej. Aby być wydajnym programistą Perla, należy znać tenidiom i podobne. W przypadku modułu mod_perl trzeba jednak głębiej zastanowić się nad je-go znaczeniem.

Jak już pisaliśmy w rozdziale 2., moduł mod_perl jest tak użyteczny między innymi dlatego,że interpreter Perla jest wbudowany w serwer Apache. Ma to wiele zalet, jak na przykład zmniej-szenie nakładu czasowego za każdym uruchomieniem skryptu środowiska ����������$�)/�.Jedną z największych wad takiego rozwiązania jest jednak fakt, że pamięć, której używa in-terpreter Perla, nie jest zwracana do systemu operacyjnego, dopóki nie zakończy się działanieodpowiedniego procesu potomnego httpd. Oznacza to, że jeżeli jakiś beztroski program obsługipostanowi wczytać 10-megabajtowy plik do zmiennej, to pamięć, której zmuszony będzieużyć interpreter Perla, nie zostanie zwolniona dopóki nie zostanie zakończony proces potom-ny serwera Apache.

Generalnie należy więc unikać operowania na zawartości całych plików jako zmiennych i sta-rać się zrealizować pożądaną funkcjonalność inaczej. Zdarzają się jednak sytuacje, kiedy nieistnieje inna możliwość, jak w przypadku pobierania całych plików z bazy danych (jak w za-daniu 3.11) albo gdy używamy klasy ���������)�/ (która zapisuje wygenerowaną zawar-tość w zmiennej). Jeżeli koniecznie potrzebujemy takiej funkcjonalności w naszej aplikacji,powinniśmy upewnić się, że stosujemy odpowiedni mechanizm utrzymywania rozmiarówprocesów potomnych w ryzach, na przykład ���������3��').

6.5. Pobieranie informacji o żądanym plikuChcemy użyć funkcji ������ na żądanym pliku albo przeprowadzić testy.

Page 16: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 177

RozwiązanieUżyjemy metody %/��"�"���, aby przeprowadzić testy i zastąpić wywołania funkcji �)�)��bezpośrednio funkcją %/��"���'���.

Wydruk 6.6. Moduł XBitHack.pm

���*�5�����*���*QR��P��*�

����������� ��� ����������;�ML�;���?��L��M��;:����������������

������ ������:�LQ�:<�:�LQS<?��

�����������

����� ����!��'�L"���"� ��3�"#� #��*�#�4�>QR��P��*�&���>������5��"���?�����O��P� ���,

��"#�$��%���&��

������� ��;�ML�;��� ���������-&�$�-.&� &���������������������TT����'����*���� ��3������$�-.�� �� ���#������7��O�9�"�7�TT����'���3���� �*�"� ��"�P�KM�����$�-.����������� ��T��?��L��M��;:������'���������� �����34�UL ��� ��

��'�:���� +�"#2��+#����*�3�����#*� #��� #� ����G�0����������3�5��5���#,��"#�$"� ��%���������V@W�

��'�F#*� #��� �01� ����G�0��������"���"#������ +�1����� �,������� ��;�ML�;��� ������$"� ��T�:�LQ�:<��

��'��������"#� �5GJ��*�M���-K� �&�� 2�3�(�������*�3�����#*� #��� #� ���5���#,��$�-.���������"� �&�� ���������VXW���&��$"� ��T�:�LQS<?��

��'����� ��"#���42�(��"� �G�"� �� ��� ��+�3"�����4�() � ��",��$�-.� ����7���8��-����� 7��

������� ����6B�

KomentarzJak już wiemy, metoda %/��"���'��� zwraca nazwę fizycznego pliku dla żądania, którejmożna użyć w rozmaitych operacjach testowych na pliku czy w funkcji �)�)��. Jednak metoda%/��"�"��� stanowi efektywniejszy sposób uzyskiwania tej samej informacji i oszczędza czasprzy wielu wywołaniach funkcji �)�)��, która zużywa dużo zasobów systemu. Użycie jej do-wodzi przy okazji, że posiedliśmy biegłość w posługiwaniu się zaawansowanymi elementamimodułu mod_perl.

Page 17: mod_perl. Podręcznik programisty

178 Część II � Interfejs API modułu mod_perl

Kiedy serwer Apache zmapuje żądany adres URI na plik fizyczny, wywołuje funkcję �)�)��dla własnych potrzeb i gromadzi informację w polu "�"� rekordu żądania. Kiedy wywoływa-na jest metoda %/��"�"���, moduł mod_perl wydobywa tę informację z rekordu żądania,wewnętrznie wypełnia specjalny perlowy uchwyt pliku � i zwraca go. Ponieważ uchwyt �używany jest do buforowania informacji dla przyszłych wywołań funkcji �)�)��, programiścimodułu mod_perl mogą uniknąć straty czasu, jaka zazwyczaj towarzyszy sprawdzaniu, czyplik istnieje, pobieraniu czasu ostatniej modyfikacji i tym podobnym.

Program obsługi ,��&(��&��-4)5��& (wydruk 6.6) stanowi implementację dyrektywy -4�)5��& z modułu mod_include. Standardowo dyrektywa ta pozwala administratorowi serweraApache wskazać, które pliki są przetwarzane przez mechanizm SSI (Server Side Include engine

— serwerowy mechanizm włączania plików) w oparciu o uprawnienia dostępu do pliku i dy-rektywę ��)���. Aby zaimplementować całą funkcjonalność dyrektywy -4)5��&1" przyminimum wysiłku, czynimy użytek z „dróg na skróty”, które zapewnia moduł mod_perl i tympodobnych sztuczek.

Pierwszym z wywołań funkcji opartych o �)�)�� jest operator testu pliku �", który sprawdza,czy plik istnieje i jest zwykłym plikiem. Ponieważ parametrem tego operatora jest %/��"�"���, „obchodzimy” w ten sposób wywołanie systemowej funkcji �)�)��, używając in-formacji przygotowanej przez serwer Apache. Pozostałe wywołania �)�)�� używają uchwytu �,świeżo zainicjalizowanego przez %/��"�"���, dzięki czemu korzystamy z wewnętrznego bu-fora interpretera Perla i oszczędzamy na wywołaniach metody %/��"�"���.

Ponieważ oryginalna dyrektywa -4)5��& rozróżnia uprawnienia dla właściciela i grupy, ope-rator testu �6 nie przyda się nam, jeżeli chcemy zachować z nią zgodność. Porównujemy więcuprawnienia do pliku, zwrócone przez funkcję �)�)��, z odpowiednimi stałymi, zaimportowanymiz pakietu ���), aby wyizolować uprawnienie do wykonywania pliku przez właściciela i grupę.

W naszym programie obsługi pozostaje już tylko sprawdzić wartość dyrektywy ��)���,ustawić nagłówek ���)�#�!"�! i upewnić się, że moduł mod_include zajmie się fazą gene-rowania zawartości. Aby sprawdzić ustawienie dyrektywy ��)���, używamy operatora ko-niunkcji bitowej 7 na wartości zwróconej przez metodę %/���������)����� i jeszcze jednejstałej z modułu ��������,���)��)�. Metody tej używa się bardzo rzadko w programach mo-dułu mod_perl, ale przydaje się w sytuacjach, takich jak ta, kiedy chcemy wymusić ustawieniapliku .htaccess. Użycie metody ��)���)�'�!"�!�� jest dokładniej opisane w następnym za-daniu, a użycie %/�����!�/�� — w podrozdziale 14.1.

Moduł ,��&(��&��-4)5��&, użyty jako program obsługi typu .�/�6 �5��!�/, ma identycznąfunkcjonalność, jak moduł mod_include, z jednym istotnym wyjątkiem. W systemach Win32nie istnieje rozróżnienie między uprawnieniami do pliku dla właściciela i grupy, więc modułmod_include stosuje specjalną obsługę dla tej platformy (i kilku innych). Sprawdza wtedy poprostu tylko, czy użytkownik może wykonywać dany plik i zawsze ustawia nagłówek ���)�#�!"�!. Chociaż wydaje się to rozsądnym rozwiązaniem, nie rozwiązuje jeszcze problemuużytkowników Windows, gdyż system ten uważa za pliki wykonywalne tylko te, które mająodpowiednie rozszerzenie, jak .exe czy .bat. Tak więc, chyba że używamy SSI do przetwarza-nia dokumentów o nazwie typu index.exe, dyrektywa -4)5��& staje się bezużyteczna na plat-formie Win32 mimo „najlepszych intencji” modułu mod_include.

Page 18: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 179

Poniżej (wydruk 6.7) prezentujemy alternatywę dla implementacji dyrektywy -4)5��& z mo-dułu mod_include w wersji dostosowanej do specyfiki systemu Win32.

Wydruk 6.7. Moduł WinBitHack.pm

���*�5�����*���*F� R��P��*�

����������� ��� ����������;�ML�;���?��L��M��;:����������������

����F� Y@��������<;����MZ��<�PL=;��

�����������

����� ����!��'�L"���"� ��3�"#� #��*�#�4�>QR��P��*�&���>������5��"���?�����O��P� ���2��'�����3�� ����#���"��F� Y@,

��"#�$��%���&��

������� ��;�ML�;��� �����������-&�$�-.&� &���������������������TT����'����*���� ��3������$�-.�� �� ���#������7��O�9�"�7�TT����'���3���� �*�"� ��"�P�KM�����$�-.����������� ��T��?��L��M��;:������'���������� �����34�UL ��� ��

��'�?������"#����#���#����*�,��"#�$�������F� Y@����S�������������$�-.&��� �"�2�$������

��'�I�����"#����G)��;�ML�;�2�3�(�������*�"��������� #����#�����<�PL=;,������� ��;�ML�;���&�$�����T��<�PL=;�

��'��������"#� �5GJ��*�M���-K� �&�� 2�3�(���� ���3����������� #����#����<;����MZ,��$�-.���������"� �&�� ���������VXW��� �����$�����T�<;����MZ�

��'����� ��"#���42�(��"� �G�"� �� ��� ��+�3"�����4�() � ��",��$�-.� ����7���8��-����� 7��

������� ����6B�

Zamiast użyć uprawnień do pliku, moduł ,��&(��&��*�4)5��& sprawdza atrybuty ��,5�0�(gotowy do archiwizacji) i ��� ���� (tylko do odczytu) przy użyciu pakietu *�89����, do-stępnego w dystrybucji libwin32 w archiwum CPAN. Jeżeli atrybut ��,5�0� nie jest ustawiony,nasz program obsługi przekazuje go modułowi mod_include do przetworzenia. Ponieważ atry-but ��,5�0� trzeba usunąć z utworzonego pliku celowo, schemat działania dyrektywy -4)5��&pozostaje bez zmian. Nasza nowa implementacja ustawia także nagłówek ���)�#�!"�!, aletylko, gdy nie jest ustawiony atrybut ��� ���� — jeżeli plik nie może być zmodyfikowany, niekłopoczemy się ustawianiem nagłówka.

W zależności od wersji systemu operacyjnego może być wiele sposobów przełączania atry-butów pliku, ale najbardziej uniwersalne jest użycie programu �����4 z wiersza poleceń:

�[�����[� ���.�������������� �������

Page 19: mod_perl. Podręcznik programisty

180 Część II � Interfejs API modułu mod_perl

6.6. Nagłówki warunkoweChcemy właściwie posługiwać się nagłówkami warunkowymi, na przykład wysyłać w odpo-

wiedzi nagłówek ��������� , czy sprawdzać nagłówek żądania ������� ����� .

RozwiązanieUżyjemy metod dodanych do klasy ������ przez klasę ����������, jak ��)���)�'�!"�!��czy '��)�����!)���� (spełnia warunek).

Wydruk 6.8. Moduł SendSmart.pm

���*�5�����*���*:� :"����

����������� ��� ������������������������������������

��������KK�5�������L������

�����������

����� ����!��'�F#�#G�"#����*�����#�+ #�+�� ����� �"�� �5GJ�*�"���#�*�2�*�� #��'�*��� ������� ������)�����34,

��"#�$��%���&��

��'��������������-. ������� ����(�����KK�5�������+���3��$&-.���*��,��"#�$&�%�L�����-. ���$�-.&��� �"���

������� ������������ �����$&�

��'�>K�5��+ ��>��������"#��#��KLK;,��$�-.�� �� ���#�������KK�5��-. ��-.���*�#���&���� ���$&���

��'��������"#� �5GJ��*�M���-K� �&�� � ���� ��������+����"� #&�*��3�����*�,,,��$�-.���������"� �&�� �������$�-.&� &��VXW��

��'�,,,���+� �5GJ�*��;��5����� �� �-M� 5�,��$�-.�������5���$�-.������ �� ���� 5��

��'�/�(������+#��*������� *��+� �5GJ�*J��L&-\��)����G �� �2��#�#G�"#� �5GJ�*�,��'�F���+���� #"���+���+�����"#�������� ���������������,���&���"#�$�������%�$�-."������� ���� ���%%�����!����$�-.�� ������� �����6�������!��������� �$���������6

Page 20: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 181

���'��������"#���*�E �*����*�� �����+)��*����#�#G�"#�+������01,�����*�$&2�A2�A���$�-.�� �& �$&��

������� �����6B�

KomentarzW zadaniu 3.10 pokazaliśmy, jak, używając metody ����������, ograniczyć „nadgorliwość”przeglądarki klienta w buforowaniu oglądanych dokumentów, teraz zobaczymy, jak „przekonać”przeglądarkę do użycia lokalnej kopii dokumentu, kiedy tylko to możliwe. W tym celu bę-dziemy sprawdzać i ustawiać zestaw odpowiednich nagłówków.

Częścią specyfikacji protokołu HTTP/1.1 jest pojęcie warunkowego żądania GET (conditional

GET request), czyli żądania przy użyciu metody :�� opartego na dodatkowej informacji, za-wartej w nagłówkach żądania i odpowiedzi. Nowoczesne przeglądarki zapamiętują odpowiedziserwera, jak również dodatkowe informacje o żądaniu, w pamięci podręcznej. Informacje te sąwysyłane z następnymi żądaniami w celu ograniczenia przesyłu danych.

Obsługa żądań, które mogą wygenerować odpowiedź, jest skomplikowana: samo przeczytanieopisu nagłówków z rodziny �"�; w dokumencie RFC 2616 może przyprawić o ból głowy. Naszczęście interfejs API serwera Apache dostarcza kilku metod, które zajmują się analiząi ustawianiem nagłówków warunkowych. Kod tych metod, jak również wyjaśnienia, pomocnew „rozszyfrowaniu” specyfikacji HTTP/1.1, znajdują się w pliku http_protocol.c w dystrybu-cji kodu źródłowego serwera Apache. Jak zwykle, możemy dostać się do tych metod dziękimodułowi mod_perl, w tym przypadku za pośrednictwem klasy ����������.

Tabela 6.2 przedstawia metody dostępne przez obiekt żądania. Inaczej niż do pozostałych meto-dy klasy ������, dostęp do tych jest możliwy dopiero po użyciu instrukcji ��1����������.

Dla dokumentów statycznych odpowiednimi nagłówkami warunkowymi żądania i odpowiedzizajmuje się domyślny program obsługi serwera Apache. Przetwarzanie ich przez aplikacje ge-nerujące dynamiczną zawartość wymaga trochę więcej wysiłku niż po prostu wywoływaniewyżej wymienionych metod. Należy najpierw zadecydować, co ma wpływ na zawartość, którągenerujemy: dane źródłowe, ich zmiany czy też inne czynniki, które mogą być subtelne, aleważne.

Moduł ,��&(��&�����!�'�/) (wydruk 6.8) pokazuje, jak w prostym programie obsługi zawarto-ści użyć metod obsługujących nagłówki warunkowe. Po pobraniu danych z żądanego zasobustatycznego przy użyciu metody %/��"���'��� ustawiamy odpowiednie nagłówki odpowie-dzi i obiektu. Wywołanie metody '��)�����!)����� powoduje użycie interfejsu API serweraApache, aby zdecydować, czy „świeża” zawartość powinna zostać wygenerowana na podstawienagłówków �)�$, �"�#�)��, �"���'�!"�!�����, �"������#�)��, �"�#�!"�!����� i ���$�

Page 21: mod_perl. Podręcznik programisty

182 Część II � Interfejs API modułu mod_perl

Tabela 6.2. Metody dodane do klasy Apache przez klasę Apache::File

Metoda Opis

����� ����������� #�� Usuwa ciało komunikatu z nadchodzącego żądania.

�����#���� 5��� Zwraca pozycje początkowe i długości każdego fragmentuwyspecyfikowanego w żądaniu.

"������� ���� ��� Sprawdza, czy spełnione są warunki z nagłówków L&-\. Jeżeli zwróci ��,zawartość powinna zostać wysłana do klienta.

"��"��� Umożliwia dostęp do czasu ostatniej modyfikacji żądanego zasobu,przechowywanego w rekordzie żądania serwera Apache.

�����#���� 5��� Zwraca wartość „prawda”, jeżeli żądanie dotyczy fragmentów pliku.

������ �� ���� 5��� Ustawia nagłówek �� �� �-M� 5� na wskazaną wartość albo na długośćżądanego pliku (jeżeli jest dostępna).

�������5�� Generuje i ustawia nagłówek ;��5.

���������"� �&�� �� Ustawia nagłówek M���-K� �&�� na czas ostatniej modyfikacji żądanegopliku, opcjonalnie wywołując metodę �� ����"��"���z podaną wartością.

�� ������"��� Ustawia czas ostatniej modyfikacji żądanego pliku w rekordzie żądaniatylko, kiedy nowo ustawiany czas jest późniejszy od dotychczasowego.

żądania. Metoda '��)�����!)����� zwraca wartość �<, jeżeli z analizy nagłówków i innychinformacji, które dostarczyliśmy na temat zasobu, jak na przykład czas ostatniej modyfikacji,wynika, że należy wysłać klientowi aktualną wersję zawartości. Jeżeli zwrócona wartość jestróżna od �<, powinna zostać przekazana do serwera Apache, aby mógł podjąć odpowiedniąreakcję, na przykład wysłać odpowiedź 8=>1��)1#�!"�! (zasób niezmieniony).

Można by pomyśleć, że ustawianie nagłówków odpowiedzi przed wywołaniem metody '���)�����!)����� to strata czasu. Jednak metoda ta używa nagłówka ���)�#�!"�! w swoichporównaniach, a ponadto niektóre nagłówki można zwracać także z odpowiedzią 8=>1��)1#��!"�!, na przykład �)�$, ���)�#�!"�!, <�����?� i inne.

Chociaż większość metod w tabeli 6.2 może być używana przy wysyłaniu zarówno dynamicz-nej, jak i statycznej zawartości, metody ��)��)�$�� powinno się używać tylko przy wysyłaniuniezmienionych, statycznych plików, ponieważ obliczenie nagłówka �)�$ jest bardzo kosztow-ne, gdyż musi być zagwarantowana jego unikalność dla danego zasobu w danym stanie; niejest dopuszczalne, aby jakiekolwiek dwie wersje zasobu mogły mieć ten sam nagłówek �)�$.

Warto również omówić osobno metodę �!�)��')'���. Wpływa ona bezpośrednio na czasostatniej modyfikacji, który zostanie wysłany w nagłówku ���)�#�!"�! odpowiedzi, jeżeliużyjemy metody ��)���)�'�!"�!��. Metodę �!�)��')'��� możemy wywoływać dowolnąilość razy — nagłówek ���)�#�!"�! będzie miał w rezultacie wartość najpóźniejszą z tych,które będziemy próbowali ustawić, co ułatwia wyrażanie skomplikowanych warunków logicz-nych dotyczących dat w naszym kodzie. Dobrą ilustrację tej cechy stanowią zadania 6.7 i 8.2.

Poniższy wynik działania metody %/������)/�$�� pokazuje komunikację między klientema serwerem dla wcześniejszego przykładu (wydruk 6.8). Pierwszy zestaw nagłówków repre-zentuje żądanie zasobu, którego przeglądarka klienta jeszcze nie posiada w pamięci podręcz-nej, a drugi — powtórne żądanie tego samego zasobu.

Page 22: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 183

����������������������������

���� �!����"��"�#$����"�����%���� $����"��& �"$����"�� & �"$����"�� "$�'�'

���� ��(���)��!��)*�++,-��$'$��#�+

���� ����*�"!�".�

���� ��/�"��"�!��$ #

(*����*!�0�� ����1�

�*)�!� ����� ����*�

2)����"��!�3*.�����4�56��78�* )�9��,��:�2;

P��?9B,A�@AA���M���-K� �&�� ���2�BC�K�#�@AAB�B]BC^_�SK�;��5�>_�]@�-B]�-Y�A^B`��>�� �� �-M� 5��YX^�� ����� �������� �� �-�#�����O�9�"�

����������������������������

���� �!����"��"�#$����"�����%���� $����"��& �"$����"�� & �"$����"�� "$�'�'

���� ��(���)��!��)*�++,-��$'$��#�+

���� ����*�"!�".�

���� ��/�"��"�!��$ #

(*����*!�0�� ����1�

�*)�!� ����� ����*�

�#�3*�#�������!����$��5�3���<�����+!�5!4=��3�:���"��>6-4

2)����"��!�3*.�����4�56��78�* )�9��,��:�2;

P��?9B,A�YA^�����K� �&�� M���-K� �&�� ���2�BC�K�#�@AAB�B]BC^_�SK�;��5�>_�]@�-B]�-Y�A^B`��>�� �� �-M� 5��YX^�� ����� ������

6.7. Żądania fragmentów plikówChcemy obsługiwać żądania fragmentów plików, wymaganych na przykład przez moduły roz-

szerzające przeglądarki do obsługi dokumentów w formacie PDF.

RozwiązanieUżyjemy metod ����������)�(�)�/��$��� i �������������(�)�/��$���, dodanych przez klasę����������.

Wydruk 6.9. Moduł SendAnyDoc.pm

���*�5�����*���*:� � #����

����������� ��� ����������������������������������

Page 23: mod_perl. Podręcznik programisty

184 Część II � Interfejs API modułu mod_perl

�����RL������R������������KLK;�#��������#���&&�O��������"�?�����

�����������

����� ����!

��"#�$��%���&��

��"#�$������%�$�-. ����� &�5�7�R�:;<7����"#�$������%�$�-. ����� &�5�7�R?�::7����"#�$ �����%�$�-. ����� &�5�7�R�:;7��

��'�����+#"#�����*����"�?����� ���JE ��3,��"#�$��"��%��������"��

��"#�$ ��%��RL-.�� ����$ ����2�$����2�$����2���!<����;�����%.�B2�������""���%.�B2�?�� �;�����%.�B6��aa� ���$�RL�������

��'�I �3 �3�"#� �+�4�������#������*���� � ��*���3�� &��"��3����0���(��,��'�?�+#*G� ��#�� �����<L����99��������9:� � #���9 ���9&���,� &��"#��$�����2�$&��� �"���%�$�-.����� &��%b�"D9�,\�9�,\�D�

��'�����+#"#�+��#�� ��2�*�J���+������+������01����*�����+�������� ��3�"� #&�*��3���'�����*� ���� ����+)�*�����*�2������+5�4 �"��*���� �3�����&#��+�����3��'��� ��+�3� �(���������&� *�3����"����,��"#�$���%���������������� ���"� �2�������������"� �&�� �-���� ����7ABABBXCA727��KKZZZZ7���\�]_^AA�����&��"�$��������������� �"��%�c����

��'�:���3�� ��������� ��� ����J��RM�R,��$ �-.!M� 5<�� M� 6�%�BA�\�BA@^�\�BA@^���'�BAK

��"#�$���%�$ �-.��������$�����

��$��-.�O������$&��� �"���

��"#��$&���2�$�����"� �&�� ��%�$��-.&�����������#�

��$��-.&� ���

������� ������������ �����$&����

��'�L &��"�3�"#���+�5�) ��*42�(���*�����3�"#�() � ���&��5"� �J�����*�,��$�-.�� �������-.����7������-<� 5��7�%.�7�#���7��

��'��������"#��#��KLK;� ���� ���������+�+��+� ��� �+�#����*�,��$�-.�� �� ���#����#���&&�O�$&��� �"��-.VAW��

��'������������+ ��# �3�2�*�J�#��+���3���� �3�JE ��3�+#��'���B,��+�������� #�+���+#� � #���'���@,��+���"� #&�*��3�����*��E�J G���5��"� �G�,

Page 24: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 185

��'�F���+#�� *���+����+���+#� � #������ ��"#���42�+��3������SK�,���"#�$���*�5��%���?����S;����%b��DD9D5���$�-.�� ����"��"��$�����"� �&�� �-�$��"�-.�+�&&�������$�-.�� ����"��"��������$L��!>$���*�5�,�">6�VXW����$�-.���������"� �&�� �

��'�:���� +�"#2��+#�3�������() � ���&��5"� �J�������������� ��"��� �� �-M� 5���'��������+� ���#�G� ��"� �5GJ�*J�2�5 #(�&� *�3����������#���� 5��"� #&�*�3��3�,��'�?�"�4��3"#2�(��������� ����� �� �-M� 5��3�����*� ���+ ��,��$�-.������ �� ���� 5���� 5��$&������

��"#�$�� 5����������%�$�-.�����#���� 5��

��'���*������ ��,���&���"#�$�������%�$�-."������� ���� ���%%�����!����$�-.�� ������� �����6�������!��������� �$���������6

��'������#�#G�"#�+������0��2�3�(������ �)� �������+� �,������� �����&�$�-.�� ���� �#�

��'�����+�+�3"��"#���4�&��5"� ��"�����*�2�����+#�� *�� �,� �*�"� ���?��,���&��$�� 5�����������!����������"#�$�&&���2�$�� 5���%�$�-.�����#���� 5���!��������� ���������$&���2�$�&&���2�$�� 5�������6��6�������!������� ��$&������6

������� �����6B�

KomentarzChociaż powinniśmy pozwolić serwerowi Apache obsługiwać wszystkie możliwe dokumentystatyczne, kiedy plik jest przechowywany w bazie danych, możemy nie mieć innego wyjścia,jak tylko obsłużyć żądanie „własnoręcznie”. W takim przypadku dodatkowy wysiłek, włożonyw zapewnienie właściwej obsługi różnych nagłówków protokołu HTTP/1.1, pozwoli znacznieobniżyć obciążenie naszego łącza.

Nasz przykładowy program obsługi (wydruk 6.9) stanowi bardzo zmodyfikowaną wersję pro-gramu ,��&(��&�����!*�/! �� z zadania 3.11. W nowej wersji dodaliśmy kilka usprawnień napodstawie dotychczasowych rozwiązań, w tym użycie dodatkowej informacji w adresie URI,aby określić nazwę tabeli w bazie danych i pliku, który chcemy z niej uzyskać. Dodaliśmy teżmożliwość inteligentnej obsługi żądań warunkowych w oparciu o czas modyfikacji zarówno

Page 25: mod_perl. Podręcznik programisty

186 Część II � Interfejs API modułu mod_perl

pliku w bazie danych, jak i naszego modułu — oba są używane do określenia, czy zawartośćjest „świeża”. I, aby spełnić obietnicę zawartą w tytule podrozdziału, dodaliśmy możliwość prze-syłania fragmentów pliku.

Możliwość żądania jedynie wskazanych fragmentów pliku została dodana przez wprowadze-nie odpowiedniego zestawu nagłówków w specyfikacji protokołu HTTP/1.1. Pełna imple-mentacja tych nagłówków przez klienta i serwer redukuje transfery dużych plików, kiedyużytkownik mógłby być zainteresowany jedynie niektórymi fragmentami. Chociaż taka kon-cepcja stanowi fascynujące rozwiązanie problemu „zapchania” przepustowości sieci, a serwerApache implementuje ją w pełni we wbudowanym, domyślnym programie obsługi zawartościstatycznej, przeglądarki klientów rzadko ją wykorzystują, z wyjątkiem żądań plików PDF1.

Mechanizm pobierania fragmentów pliku, używany aktualnie przez moduły rozszerzająceprzeglądarkę o obsługę dokumentów PDF, może się wydać nieco dziwny na pierwszy rzutoka, gdyż wywoływanych jest kilka żądań, z których pierwsze jest przerywane, aby wywołaćnastępne, dotyczące fragmentów. Chociaż może się to wydawać niezgodne z intuicją w przy-padku projektu mającego redukować przesyłanie danych, jednak po zidentyfikowaniu zasobujako dokumentu PDF, pochodzącego z serwera obsługującego żądania fragmentów, przeglą-darka natychmiast przerywa aktualne żądanie, aby wywołać jedno lub kilka następnych z od-powiednimi nagłówkami dotyczącymi fragmentów pliku.

Jak opisaliśmy w zadaniu 4.9, zerwanie połączenia jest natychmiast rozpoznawane przez ser-wer Apache, który z kolei zamienia wszystkie operacje pisania na operacje puste w celu za-oszczędzenia cykli procesora. Żądania fragmentów pliku mają zmniejszać obciążenie sieci,niekoniecznie zaś obciążenie naszego serwera.

Jeżeli to wszystko brzmi skomplikowanie, to dlatego, że jest skomplikowane. Przykładowydialog żądanie-odpowiedź dla programu z wydruku 6.9 mógłby wyglądać następująco:

���������?*��*�)�#���� #���������

���� �!����"��"�#$����"�����%���� $����"��& �"$����"�� & �"$����"�� "��'�'

���� ��(���)��!��)*�++,-��$'$��#�+

���� ����*�"!�".�

���� ��/�"��"�!��$ #

(*����*!�0�� ����1�

�*)�!� ����� ����*�

2)����"��!�3*.�����4�56��78�* )�9��,��:�2;

P��?9B,A�@AA����� �� �-M� 5��BYXC`X_������-<� 5����#���M���-K� �&�� ����2�@X�/� �@AAB�B_A]`X�SK��� ����� �������� �� �-�#������������� 9� &

���������?*��*�)�#���� #���������

���� �!����"��"�#$����"�����%���� $����"��& �"$����"�� & �"$����"�� "��'�'

1

Możliwość tę wykorzystują również coraz popularniejsze programy, zwane menedżerami pobierania

(download manager). W przypadku zerwania połączenia podczas pobierania dużego pliku, program

próbuje, przy ponownej inicjacji połączenia, rozpocząć pobieranie od miejsca, w którym zostało

przerwane — przyp. tłum.

Page 26: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 187

���� ��(���)��!��)*�++,-��$'$��#�+

���� ����*�"!�".�

���� ��/�"��"�!��$ #

(*����*!�0�� ����1�

�*)�!� ����� ����*�

��"�!�%���)>�6-=,5<��6-5,-,$�6+-4�4��6-=,5�$�@��).����)��A�����B

��C��)����"�!�%���)>�6-=,5<��6-5,-,$�6+-4�4��6-=,5�$�@��).����)��A�����B

2)����"��!�3*.�����4�56��78�* )�9��,��:�2;

P��?9B,A�@A_�?��������� �� ��� �� �-M� 5��BYX@A]A������-<� 5����#���M���-K� �&�� ����2�@X�/� �@AAB�B_A]`X�SK��� ����� �������� �� �-�#���"��������9O-�#���� 5������� ��#%Y�Y�����^YX

Metody ��)�(�)�/��$��� i �����(�)�/��$��� stanowią klucz do dynamicznego wysyłania do-kumentów PDF. Obie zostają dodane do klasy ������ po zaimportowaniu (przy użyciu instrukcji ��) klasy ����������. Pierwsza analizuje nagłówki żądania, a następnie ustawia odpowied-nio nagłówki ,��)��)����� i ,��)��)����$� w razie potrzeby. Ponieważ wartość nagłówka,��)��)����$� zależy od wielkości zawartości, musimy wywołać metodę ��)����)��)�

��$)��� przed wywołaniem metody ��)�(�)�/��$���, która z kolei musi zostać wywołanaprzed metodą ���!��))�����!�/�� — kolejność jest tu bardzo istotna. Kiedy zostanie jużstwierdzone, że żądano fragmentów pliku, wywołanie metody �����(�)�/��$��� zwraca listępar, zawierających początek i długość każdego fragmentu żądanego przez klienta. Możemyużyć tej listy, aby pobrać odpowiednie fragmenty pliku i przesłać je klientowi.

W naszym przykładzie pobieraliśmy plik z bazy danych, ale jeżeli obsługujemy dynamicznieżądania fragmentów plików statycznych na dysku, lepszym rozwiązaniem będzie użyć dwuar-gumentowej wersji metody ���!�"!��, omówionej w zadaniu 6.3, niż wczytywać cały plik dopamięci i dzielić na fragmenty za pomocą funkcji � (�)/��. Na przykład w pętli przetwarzają-cej listę zwróconą przez metodę �����(�)�/��$��� w naszym programie obsługi moglibyśmywprowadzić następujące zmiany, aby przetwarzać pliki statyczne:

�&��$�� 5�����������!��������"#�$�&&���2�$�� 5���%�$�-.�����#���� 5���!�������*�$&2�$�&&���2�A�����$�-.�� �& �$&2�$�� 5�����66�����!��$�-.�� �& �$&��6

6.8. Nagłówki związane z datamiChcemy bezpośrednio odczytywać i zmieniać wartość nagłówków związanych z datami.

Page 27: mod_perl. Podręcznik programisty

188 Część II � Interfejs API modułu mod_perl

RozwiązanieUżyjemy funkcji �)�)'��� i ��/��!�)���, dostarczonych przez klasę ���������).

$�-.��5-.� &��>��5GJ��*�M���-K� �&�� �������� #� ��>2����������������������������"��$�-."��"����

KomentarzPonieważ omawiamy teraz nagłówki związane z datami, jest to dobre miejsce, aby szerzejomówić dwie metody z klasy ���������), o których wspomnieliśmy tylko w rozdziale 5.Funkcje �)�)'��� i ��/��!�)��� zapewniają wygodny sposób konwersji dat między forma-tem protokołu HTTP a liczbą sekund od początku epoki, którą zwraca wiele funkcji perlo-wych. Funkcja ��/��!�)��� przelicza datę z formatu HTTP na odpowiednią liczbę sekund odpoczątku epoki. Funkcja �)�)'��� zamienia sekundy na datę w formacie HTTP, która zawszejest wyrażana w czasie GMT.

Chociaż te metody są wygodne, nie zawsze mogą wykonać za nas całą pracę. Na przykład je-żeli obliczamy liczbę sekund w innej strefie czasowej niż GMT (jak na wydruku 6.9), będzie-my musieli wykonać konwersję samodzielnie, używając modułu, takiego jak �'���.���.

6.9. Opróżnianie buforów wyjściowychChcemy opróżnić wewnętrzne bufory wyjściowe serwera Apache.

RozwiązanieUżyjemy metody ��������/" ����.

������N$&.��!��'�F#����3�"#�*�( #������+����*�����#�#G�"#�5��� ���+�� ��*��� ��,��'�R�� +��+G#���"#�G�����4*�+�0����#�� *J�,����� ����$�-.�&����6

KomentarzSerwer Apache w normalnych warunkach buforuje dane wypisywane przez program obsługi,wysyłając je do klienta dopiero, kiedy bufor jest pełny albo program obsługi zakończy działanie.Mogą się jednak zdarzyć sytuacje, kiedy trzeba wysłać dane do klienta natychmiast, na przykład

Page 28: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 189

gdy nasz program jest w trakcie jakiegoś relatywnie długiego procesu i chcielibyśmy, abyw tym czasie pojawiło się coś w przeglądarce klienta. W takim przypadku możemy użyć me-tody %/��/" ����, aby opróżnić bufor. Należy jednak używać jej z umiarem, gdyż obniżaznacznie wydajność serwera.

Jako przykład a także przypomnienie kilku metod, które poznaliśmy dotychczas, rozważmynastępujący program obsługi, który wybiera losowy obraz z katalogu ServerRoot/icons i wy-syła go klientowi.

Wydruk 6.10. Moduł SendIcon.pm

���*�5�����*���*:� L�� �

����������� ��� ���������:;<=;<�;<<�<����������������

�������P� ���

�����������

����� ����!

��"#�$��%���&��

��'�?������"#���G�(� ����� *�����5����� �9��+5�4 �"�:��8��<���,��"#�$��� ��%�$�-.���8��������������8��7��� �7����"#�$ �%����P� ��-. ���$��� ������ ������$ ��!����$�-.��5�������>����"�( �������+#1�*�����5��$��� ��$D>����������� �:;<=;<�;<<�<���6

��'�?������"#�+������01�*�����5���� � �3�"#� ������#�d��� ����+#��*���+ ���+�� ���'����*���#���SL�,��"#�d��� ��

��&������"#�$��� ��$ -.��� ��!����"#�$����%�$�-.���*�������>9��� �9$��� >������ �O��� �����$���-.�� �� ���#������7�"�5�95�&7���������d��� �2�$���-.&��� �"����6

��'�F#�����"#������#�����+,��"#�$�"�5��%�$��� �V�� �d��� �W�

��'��������"#��#��� #����*�����+�����#�#G�"#�5��*��� ����,��"#�$&�%����������-. ���$�"�5������ ������$&��!����$�-.��5�������>����"�( �������+#1����*��$�"�5��$D>����������� �:;<=;<�;<<�<���6

���� "� ��$&���'��#"�5� �� ����#���"J��F� Y@

��$�-.�� ������� ���7�"�5�95�&7��

Page 29: mod_perl. Podręcznik programisty

190 Część II � Interfejs API modułu mod_perl

��$�-.�� �& �$&��

��'����J( ��"#���&��2���#�����+�+����G��#�G� #� ��#�"����,��$�-.�&����

��'�:#"���3�"#�3�*�0� G�5�����G#�������,,,��������`��

������� ����6B�

Bez wywołania metody %/��/" ���� klient nie ujrzałby obrazu, zanim nie skończyłby siędługotrwały proces (w naszym przykładzie symulowany wywołaniem funkcji ������). Jed-nakże, podkreślamy po raz kolejny, metoda %/��/" ���� może znacznie obniżyć wydajnośćserwera, więc powinna być używana tylko w razie potrzeby.

6.10. Przekierowanie uchwytówplików wyjściowychChcemy zmienić domyślne przypisanie strumieni wyjściowych ������ i ������.

RozwiązanieUżyjemy interfejsu ���5�� ��, pochodzącego z klasy ������ lub innej, aby zmienić zachowa-nie uchwytów plików.

Wydruk 6.11. Przykładowy program obsługi

����������� ��� ���������:;<=;<�;<<�<�����������?�

�����������

����� ����!

��"#�$��%���&��

������� �:;<=;<�;<<�<�� ������ ���>9�"�>�

��$�-.�� ������� ���7��O�9���� 7��

��'�?�+�*������3�"#�����"��H�:��;<<� ����+�5�) ��*��*��� ��,��'�F��� �����J���*�(��"����4���G��*�"� �*��3��+��������"���?,������\:��;<<2�7�����7�

Page 30: mod_perl. Podręcznik programisty

Rozdział 6. � Obsługa plików 191

��"#�$&���%������?-. ���>&��,��� ,��5>2�����5�%.�`����$&��-.��5� �>� � #"���>����$&��-.�� ��#���$&��-.�� �>���9�?��9"� ����9�#-"� ���9�����9>����$&��-.5���>"� �����-B,@_,���,5+>����$&��-.�����

��'�:���"��H�:��;<<��� �� ����*������ #� �� +�� �*���G4 J�,��� ����\:��;<<�

������� ����6

KomentarzMechanizm )��� to „zdradzieckie” narzędzie, które może zostać użyte do zmiany zachowaniawielu perlowych typów danych. W zadaniu 2.17 widzieliśmy, jak można dowiązać (tie) mapędo klasy ���� 65���, aby zachować kolejność wstawiania elementów i umożliwić powtarza-nie się kluczy — normalnie mapa nie dopuszcza takiej funkcjonalności. Tak samo łatwo mo-żemy za pomocą instrukcji )��� zmusić uchwyty plików �� ��� i �� ��� do wykonania na-szych „diabelskich sztuczek”.

Moduł mod_perl podłącza strumienie �� ��� i �� �� do przeglądarki klienta, używając inter-fejsu ���5�� �� z klasy ������, natomiast �� ��� jest kierowany do pliku wskazanego przezwartość �//�/��$ w rekordzie serwera. Chociaż nie ma dużego sensu przekierowywaniestrumienia �� ��, to samo w przypadku strumieni wyjściowych może przynieść nieoczekiwa-ne korzyści w rękach cudotwórców, magików, guru i tym podobnych. Możemy poczuć sma-czek tej „magii”, kiedy używamy klasy ���������)�/ do łączenia wyniku działania kilkuperlowych programów obsługi — w serwerze Apache 1.3 filtrowanie danych wyjściowychjest po prostu niemożliwe przy użyciu istniejącego interfejsu API języka C. Programy obsługimodułu mod_perl mogą ominąć to ograniczenie, używając przekierowanych uchwytów pli-ków i paru innych, bardzo pomysłowych rozwiązań, aby osiągnąć imponujące rezultaty.W zadaniu 15.4 mamy przykład, jak używać klasy ���������)�/.

Jeżeli interesuje nas przekierowanie strumienia �� ��� zamiast �� ���, możemy go dowiązaćdo klasy, takiej jak �����)/�$, ��������/ (z dystrybucji ����)/�$�) lub naszego własnegointerfejsu ���5�� ��. Należy tylko pamiętać, aby „zwrócić” strumień �� ��� do serwera Apache,kiedy skończymy. Oto bardzo prosty przykład.

Wydruk 6.12. Przekierowanie strumienia STDOUT

����������� ��� ��������������L�:������

�����������

����� ����!

��"#�$��%���&��

Page 31: mod_perl. Podręcznik programisty

192 Część II � Interfejs API modułu mod_perl

��"#�$���� 5�

��$�-.�� ������� ���7��O�9���� 7��

����� ��>/��+�+�� �� ���)+� #,,,[ >�

������\:�����2�7Le:�����72�[$���� 5�

����� ��>?��+�"#� ��+"�� �3�[$���� 5>�

������\:�����2�7�����7�

����� ��>?� �� ��� ���)+� #�$���� 5[ >�

������� ����6

Aby nasz program zachowywał się grzecznie i przewidywalnie, nie powinniśmy zakładać, żestrumień �� ��� jest dowiązany do klasy ������. Właściwe rozwiązanie polega na zapamiętaniuklasy, do której strumień był dowiązany i odtworzenie go, kiedy skończymy już nasze „czary”.

"#�$�� �%���&���� �\:�������

'�����-���-*� ����,,,

����\:�����2�$�� �