Moduł HTTP::Daemon
Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowaSpis treści
Co to jest?
Prosta klasa serwera http.
Instancjami klasy HTTP::Daemon są serwery HTTP/1.1 które nasłuchują na gnieździe nadchodzące żądania. HTTP::Daemon jest podklasą klasy IO::Socket::INET, więc możesz wykonywać operacje na gniazdach również bezpośrednio na nim.
Moduł ten w prosty i szybki sposób pozwoli man ustawić prosty serwer http. Może okazać się to przydatne np. w lokalnych sieciach gdzie istnieją problemy w połączeniu pomiędzy dwoma hostami. Dzięki temu że moduł ten jest czysto perlowy będziemy mogli zrobić to z poziomu naszego programu perlowego. Więc jeśli stworzyliśmy progam który generuje stronę HTML dzięki temu modułowi jesteśmy w stanie z poziomu tego samego programu odrazu ją udostępnić nie zagłębiając się w programy ani ustawienia systemowe. Może to okazać się bardzo przydatne.
Metoda accept() zwróci obiekt HTTP::Daemon::ClientConn z podklasą IO::Socket::INET kiedy połączenie z klientem jest możliwe.IO::Socket::INET jest obiektowym interfejsem umożliwiającym tworzenie oraz używanie gniazd AF_INET (gniazd używających protokołu TCP/IP) więcej informacji tutaj. Wywołując metode get_request() na tym obiekcie będzie czytało dane od klienta i zwróci obiekt HTTP::Request. Obiekt ClientConn również zapewnia metody aby wysłać odpowiednie odpowiedzi.
Ten demon HTTP nie wykonuje fork(2) za ciebie. Twoja aplikacja, dla przykładu użytkownik HTTP::Daemon jest odpowiedzialny z forkowanie jeśli jest to potrzebne. Zauważ również, że to użytkownik jest odpowiedzialny za generowanie odpowiedzi potwierdzających dla protokółu HTTP/1.1.
Metody
- $d = HTTP::Daemon->new
- $d = HTTP::Daemon->new( %opts )
Konstruktor tych metod pobiera takie samie argumenty jak konstruktor IO::Socket::INET, w przeciwieństwie do klasy bazowej może być również wywołana bez argumentów. Demon ustawi w takim przypadku nasłuchującą kolejkę 5 połączeń alokując losowe numery portów.
Serwer który chce podłączyć do jakiegoś określonego adresu o standardzie portu HTTP może zostać skonstruowany w taki sposób:
$d = HTTP::Daemon->new( LocalAddr => 'www.thisplace.com', LocalPort => 80, );
Zobacz IO::Socket::INET aby zobaczyć opis innych argumentów które mogą zostać użyte do konfiguracji demona w trakcie konstrukcji.
- $c = $d->accept
- $c = $d->accept( $pkg )
- ($c, $peer_addr) = $d->accept
Ta metoda działa jak dostarczona w klasie bazowej, ale zwraca domyślnie wskaźnik do HTTP::Daemon::ClientConn. Jeśli nazwa pakietu jest dostarczona jako argument, zwrócony obiekt będzie przetworzony w daną klasę. To jest prawdopodobnie dobry pomysł aby zrobić tą klasę podklasą HTTP::Daemon::ClientConn.
Metoda accept zwróci undef jeśli ustalony został czas na połączenie a w trakcie tego czasu ono nie nastąpiło. Metoda timeout() jest opisana w IO::Socket.
W kontekście listowym zarówno obiekt klienta jak i adres będzie zwrócony; zobacz IO::Socket po detale.
- $d->url
- Zwraca URL w postaci napisu który może zostać wykorzystane do serwera.
- $d->product_tokens
Zwraca nazwę dzięki której serwer będzie identyfikował siebie. Jest to napis wysyłany w nagłówku przy odpowiedzi serwera. Główny powód aby mieć tą metode jest taki, że podklasy mogą przesłonic ja jeśli chcą używać nazwy innego produktu.
Domyślnie ten napis to "libwww-perl-daemon/#.##" gdzie "#.##" jest zastąpione numerem wersji modułu.
- $c->get_request
- $c->get_request( $headers_only )
Ta metoda czyta dane od klienta i przetwarza je na obiekt HTTP::Request który jest zwracany. Zwraca undef jeśli czytanie nie powiedzie się. Jeśli się nie powiedzie, wtedy obiekt HTTP::Daemon::ClientConn ($c) powinien zostać zniszczony, i nie powinieneś próbować wywoływać tej metody jeszcze raz na nim. Metoda $c->reason może dać ci pewne informacje na temat czemu $c->get_request zawiodło.
Metoda get_request() normalnie nie zwróci niczego dopóki całe żądanie od klienta nie zostanie otrzymane. To nie koniecznie musi być to czego chcesz jeśli żądane jest ściąganie dużego pliku. Jeśli przekażemy wartość "prawda"(TRUE) jako argument $headers_only, wtedy get_request() zwróci od razu po parsowaniu nagłówka żądania i ty będziesz odpowiedzialny za czytanie reszty zawartości żądania. Jeśli wywołasz jeszcze raz $c->get_request na tym samym połączeniu lepiej przeczytaj odpowiednią ilość bitów.
- $c->read_buffer
- $c->read_buffer( $new_value )
Bajty przeczytane przez $c->get_request, ale nie użyte są umieszczane w buforze odczytu. Następnym razem kiedy $c->get_request zostanie wywołana pochłonie najpierw bajty z bufora odczytu zanim będzie czytac więcej danych z siecowego połącznia. Bufor odczytu nie jest ważny jeśli $c->get_request zawiodło.
Jeśli sam zajmiesz się czytaniem zawartości żądania musisz opróżnić ten bufor zanim przeczytasz więcej musisz również umieścić nieprzetworzone bajty tutaj. Będziesz potrzebował również tego buforu jeśli implementujesz usługi jak 101 protokoły "Switching".
Ta metoda zawsze zwraca zawartość starego bufora może również opcjonalnie zamienić zawartość bufora jeśli przekażesz argument.
- $c->reason
Kiedy $c->get_request zwraca undef możesz uzyskać krótki napis opisujący czemu tak się stało wywołując $c->reason.
- $c->proto_ge( $proto )
Zwraca prawda(TRUE) jeśli klient ogłosił protokół którego wersja jest większa bądź równa danemu argumentowi. Argument $proto może być napisem w stylu "HTTP/1.1" bądź "1.1".
- $c->antique_client
Zwraca prawdę (TRUE) jeśli klient rozmawia protokołem HTTP/0.9. Nie powinny być zwracane kody statusu ani nagłówki. Powinno być to samo co !$c->proto_ge("HTTP/1.0").
- $c->force_last_request
Upewnij sie ze $c->get_request nie będzie próbował czytac żądań z tego połączenia. Jeśli generujesz odpowiedz która nie jest samoograniczona, wtedy powinieneś zasygnalizować ten fakt do metody wywołującej.
Ten atrybut jest jest włączany automatycznie jeśli klient ogłosił protokół HTTP/1.0 albo gorszy nie dołączył nagłówku Connection: Keep-Alive. Jest również włączany automatycznie kiedy HTTP/1.1 albo nowszy klient wysyła nagłówek Connection: close.
- $c->send_status_line
- $c->send_status_line( $code )
- $c->send_status_line( $code, $mess )
- $c->send_status_line( $code, $mess, $proto )
Wysyła linie statusu z powrotem do klienta. Jeśli $code jest pominięte, zakładane jest 200. Jeśli $mess jest pominięte, wtedy wiadomość odpowiadająca $code jest podawana. Jeśli $proto jest pominięte zawartość wartości $HTTP::Daemon::PROTO jest użyta.
- $c->send_crlf
Wysyła sekwencję CRLF do klienta
- $c->send_basic_header
- $c->send_basic_header( $code )
- $c->send_basic_header( $code, $mess )
- $c->send_basic_header( $code, $mess, $proto )
Wysyła linie status oraz nagłówki Date: i Server z powrotem do klienta. Zakładamy że nagłówki te są ciągłe oraz nie zawierają pustej linii CRLF.
Zobacz opis send_status_line() dla opisu akceptowanych argumentów.
- $c->send_response( $res )
Pisze obiekt HTTP::Response do klienta jako odpowiedź. Staramy się mocna aby upewnić sią że odpowiedź jest samo ograniczona dzięki czemu połączenie może zostać podtrzymane dla dalszej wymiany żądań/odpowiedzi.
Zawartość atrybutu obiektu HTTP::Response może być normalnym napisem bądź wskaźnikiem do funkcji. Jeśli jest funkcją, wtedy cokolwiek ta zwrotna funkcja zwraca jest zapisywana z powrotem do klienta jako zawartość odpowiedzi. Funkcja będzie wywoływana dopóki zwróci niezdefiniowana bądź pustą wartość. Jeśli klient jest HTTP/1.1 zważ, że będziemy używać podzielonego na części przesyłu jako odpowiedzi.
- $c->send_redirect( $loc )
- $c->send_redirect( $loc, $code )
- $c->send_redirect( $loc, $code, $entity_body )
Wysyła przekierowaną odpowiedź z powrotem do klienta. Lokacją $loc może być absolutny URL. $code musi być jednym z przekierowanych statusy kodów, domyślnie 301 Moved Permanently.
- $c->send_error
- $c->send_error( $code )
- $c->send_error( $code, $error_message )
Wysyła błędną odpowiedz z powrotem do klienta. Jeśli brakuje $code błąd "Bad Request" jest raportowany. Napis $error_message który jest dołączany do zawartości treści HTML.
- $c->send_file_response( $filename )
Wysyła zwrotną odpowiedz z określonym plikiem $filename jaką zawartością. Jeśli jest to folder staramy się wygenerować indeks HTML'owy z niego.
- $c->send_file( $filename )
- $c->send_file( $fd )
Kopiuje plik do klienta. Plik może być napisem (który będzie interpretowany jako nazwa pliku) albo wskaźnikiem do IO::Handle.
- $c->daemon
Zwraca wskaźnik do odpowiadającego mu obiektu HTTP::Daemon.
Następujące metody HTTP::Daemon są nowe (poprawione) w stosunku do klasy IO::Socket::INET:
HTTP::Daemon::ClientConn jest podklasą klasy IO::Socket::INET. Instancje tych klas są zwracane poprzez accept() metodę z HTTP::Daemon. Następujące metody są dostarczone:
Dodatkowe informacje.
- Przykładowe uruchomienie
Moduł pozwala na postawienie małego serwera http. Już tak krótki kod jak znajduje się poniżej pozwala na wyświetlanie stron http.
use HTTP::Daemon; use HTTP::Status; my $d = HTTP::Daemon->new || die; print "Please contact me at: <URL:", $d->url, ">\n"; while (my $c = $d->accept) { while (my $r = $c->get_request) { if ($r->url->path eq "/test") { $c->send_file_response("./test.html"); } else { $c->send_error(RC_FORBIDDEN); } } $c->close; undef($c); }
W przeglądarce wystarczy teraz podać adres naszego komputera (u mnie "laptop") oraz adres jaki wybraliśmy (u mnie /test) i nasz mini serwer http wyświetli stronę którą wskazaliśmy (u mnie ./test.html). Jak widać na załączonym obrazku daemon.gif wszystko działa dość sprawnie i bezproblemowo.
- Przydatne linki
-
Dokumentacja tego modułu w cpan'ie
Jeszcze więcej dokumentacji
Kontakt i informacje o autorze opracowania
Autor modułu:
Gisle Aas
Autor przekładu: MD
Numer GG: 2194164