Politechnika Wrocławska Wydział Podstawowych Problemów Techniki Technologie sieciowe Sprawozdanie z labolatorium Lista 5 Autor: Piotr Kosytorz IIrokInf. indeks: 166174 Prowadzący: dr inż. Łukasz Krzywiecki Wrocław, czerwca 2009
1 Cel Celem zajęć labolatoryjnych jest przetestowanie działania oraz przebudowa prostego serwera protokołu HTTP napisanego w języku Perl. 2 Realizacja Przedmiotem badania jest skrypt serwera HTTP, który został przedstawiony na listingu 1. 4 my $d = HTTP::Daemon->new( 5 LocalAddr => localhost, 6 LocalPort => 421, 7 ) die; 8 9 print "Please contact me at: <URL:", $d->url, ">\n"; 11 12 while (my $c = $d->accept) { 1 while (my $r = $c->get_request) { 14 if ($r->method eq GET ) { 15 16 $file_s = "./ index. html"; # index. html - jakis istniejacy plik 17 $c-> send_file_response( $file_s); 18 19 } 20 else { 21 $c-> send_error( RC_FORBIDDEN) 2 24 } 25 $c->close; 26 undef( $c); 27 } Listing 1: Program server.pl. 2.1 Opisprogramu Działanie programu server.pl opiera się o mechanizm udostępniany przez bibliotekę libwww-perl. Na początku tworzona jest nowa instancja obiektu typu HTTP::Daemon. Obiekt ten jest serwerem HTTP/1.1, który nasłuchuje na gnieździe nadchodzące żądania. W linii 12 rozpoczyna się pierwsza pętla programu. Konstrukcja my $c = $d-> accept zapisuje w zmiennej $c wskaźnik do obiektu HTTP::Daemon::ClientConn. Wykonanie instrukcji my $r = $c-> get request na tym obiekcie (linia 1) powoduje zapisanie w zmiennej $r wskaźnika do obiektu HTTP::Request. W linii 14 następuje sprawdzenie, czy żądanie zostało wykonane metodą GET. Jeśli nie, to do klienta zostaje przesłana infrmacja o błędzie(linia 21). W przypadku gdy zapytanie było prawidłowe, klient otrzyma treść pliku index.html, który zapisany jest bieżącym katalogu. Działanie skryptu server.pl zostało przetestowane przy pomocy programu telnet. Po uruchomieniu skryptu, nawiązano połączenie programem telnet przez port 421. Następnie przesłano znak x i potwierdzono kombinacją znaków CR LF. Odpowiedź serwera HTTP przedstawia listing 2. 1 HTTP/1.1 400 Bad Request 2 Date: Tue, 02 Jun 2009 15:44:17 GMT Server: libwww- perl- daemon/5.826 4 Content- Type: text/ html 5 Content- Length: 57 6 7 <title>400 Bad Request</title> 8 <h1>400 Bad Request</h1> Listing 2: Odpowiedź serwera HTTP. Listing 2 przedstawia nagłówek HTTP/1.1 wraz ze stroną o treści Bad Request. Uzyskano taką odpowiedź, ponieważ skrypt server.pl traktuje wszystkie zapytania typu innego niż GET za 1
nieprawidłowe. Przeprowadzono kolejny eksperyment. Nawiązano połączenie, takie samo jak przy poprzedniej próbie, jednak wysłano treść GET/ i potwierdzono ją kombinacją znaków CR LF. Odpowiedź serwera przestawia listing 5. 1 Hello World! Listing : Odpowiedź serwera HTTP. Treść Hello World! jest zawartością pliku index.html, który umieszczono w tym samym katalogu co skrypt server.pl. Odpowiedź jest zatem prawidłowa. Przesłana została prawidłowa zawartość. Oznacza to, że skrypt działa poprawnie. 2.2 Modyfikacjaprogramu Celem kolejnego kroku była modyfikacja serwera HTTP w taki sposób, aby niezależnie od żądania, zwracał jego nagłówek. Listing 4 przedstawia skrypt po modyfikacji. 4 my $d = HTTP::Daemon->new( 5 LocalAddr => localhost, 6 LocalPort => 421, 7 ) die; 8 9 print "Please contact me at: <URL:", $d->url, ">\n"; 11 12 while (my $c = $d->accept) { 1 while (my $r = $c->get_request) { 14 15 $response = HTTP::Response->new(200, OK ); 16 $response-> content($r-> as_string); 17 $c-> send_response( $response); 18 19 } 20 $c->close; 21 undef( $c); Listing 4: Skrypt zwracający nagłówki. Skrypt różni się jedynie zawartością drugiej pętli. Zrezygnowano tutaj ze sprawdzania, czy metoda zapytania jest typu GET. W celu wysłania odpowiedzi, należy ją najpierw przygotować, co następuje w linii 15. Treść zapytania w formie tekstowej($r->as string) zostaje dołączona do obiektu $response. W linii 17 następuje przesłanie przygotowanej odpowiedzi. Działanie tak skonstruowanego skryptu przetestowano przy użyciu programu Mozilla Firefox w wersji.0. W pasku adresu programu Firefox wpisano adres serwera http://localhost:421/. Program wyświetlił informacje, które przedstawia listing 5. 1 GET / HTTP/1.1 2 Connection: keep- alive Accept: text/ html, application/ xhtml+xml, application/ xml;q=0.9,*/*; q=0.8 4 Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7 5 Accept-Encoding: gzip,deflate 6 Accept-Language: pl,en-us;q=0.7,en;q=0. 7 Host: localhost:421 8 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.0.) 9 Gecko/200904216 Firefox/.0. (. NET CLR.5.0729) FirePHP/0.2.4 Keep- Alive: 00 Listing 5: Odpowiedź zmodyfikowanego serwera HTTP. Serwer zwrócił nagłówek żądania. W pierwszej linii widoczne jest, że program Firefox wysłał żądanie typu GET. Ponieważ w przesyłanym adresie nie podano nazwy żadnego konkretnego pliku, to program wybiera domyślny katalog, czyli/. Druga linia zawiera informacje o rodzaju nawiązanego połączenia. W tym wypadku jest to keep-alive. Linia zawiera akceptowane przez przeglądarkę treści, linia 4- informacje na temat akceptowanego kodowania znaków, linia 5- informacje na temat 2
kodowania danych a linia 6 akceptowane języki. W linii 7 znajduje się pełny adres serwera HTTP. Linia 8, oznaczona tagiem User-Agent, zawiera informacje o programie przy pomocy którego dokonano zapytania. Ostatnia linia zawiera wartość Keep-Alive, czyli czas w jakim kolejne zapytania do serwera będą wykonywane przy pomocy tego samego połączenia. Zmodyfikowany skrypt działa poprawnie i spełnia założenia zadania, t.j. zwraca nagłówki żądań wysyłane przez progamy klienckie. 2. Rozszerzenie funkcjonalności serwera Kolejnym zadaniem było zwiększenie funkcjonalności serwera w taki sposób, aby możliwe było uruchomienie przy jego pomocy prostego serwisu www. Po raz kolejny wykorzystano program server.pl. Dokonano niewielkich zmian, które umożliwiają przesłanie dowolnego żądanego pliku znajdującego się w wyznaczonym katalogu. Listing 6 przedstawia zmodyfikowany kod skryptu. 4 $WEBDIR = / home/ kossa/www ; # domyślny folder z plikami 5 6 my $d = HTTP::Daemon->new( 7 LocalAddr => localhost, 8 LocalPort => 421, 9 ) die; 11 print "Please contact me at: <URL:", $d->url, ">\n"; 12 1 14 while (my $c = $d->accept) { 15 while (my $r = $c->get_request) { 16 if ($r->method eq GET ) { 17 18 $file_s = $r->uri; # bezpośredni adres pliku w katalogu 19 20 if ($file_s eq "/") { 21 $file_s = "/ index. html"; # index. html - domyślnie otwierany plik 2 24 $c-> send_file_response( $WEBDIR. $file_s); # przesyłanie pliku 25 26 } 27 else { 28 $c-> send_error( RC_FORBIDDEN) 29 } 0 1 } 2 $c->close; undef( $c); 4 } Listing 6: Zmodyfikowany skrypt serwera HTTP. Skrypt po modyfikacji zawiera w linii 4 zmienną $WEBDIR, która przechowuje ścieżkę do katalogu na dysku, w którym znajdują się pliki HTML. W pętli rozpoczynającej się od linii 15 sprawdzany jest warunek, czy zapytanie wykonane zostało metodą GET. Jeśli tak, to w zmiennej $file s zapisany zostaje adres pliku podany w zapytaniu. Jeśli nie podano żadnego konkretnego pliku, to $file s zawiera jedynie znak /. W takim wypadku należy wyświetlić domyślną stronę, czyli index.html (linie 20-22). W lini 24 następuje wysłanie zawartości pliku o nazwie podanej w żądaniu klienta i znajdującym się w katalogu/home/kossa/www. W katalogu/home/kossa/www umieszczono trzy pliki html ze wzajemnymi odnośnikami do siebie. Po otwarciu strony głównej w przeglądarce internetowej możliwe było przechodzenie pomiędzy poszczególnymi podstronami poprzez umieszczone na nich odnośniki. Zmodyfikowany skrypt serwera działa dobrze i wykonuje prawidłowo swoje zadania.
2.4 Podgląd komunikatów przesyłanych pomiędzy klientem a serwerem HTTP Ostatnim punktem zadania jest sprawdzenie treści komunikatów przesyłanych do i z serwera HTTP. W tym celu użytko programu podsłuchującego Wireshark. Przechwytywane ramki zawierały części komunikatów protokołu HTTP. Informacje przesyłane do serwera miały treść podobną do tej przedstawionej na listingu 5. Dane przesyłane w drugą stronę, to dane wyświetlane w przeglądarce opakowane dodatkowo w znaczniki protokołu HTTP. 1 HTTP/1.1 200 OK 2 Date: Tue, 02 Jun 2009 19:1:08 GMT 4 Server: libwww- perl- daemon/1.9 5 Content- Type: text/ html 6 Content- Length: 1 7 Last-Modified: Tue, 02 Jun 2009 1:20:09 GMT 8 Hello Wordl! Listing 7: Treść komunikatu przesyłanego przez serwer HTTP. Listing 7 przedstawia przechwycony komunikat z serwera HTTP do przeglądarki internetowej. Jego treśćjestcałkowiciezgodnazespecyfikacjąprotokołuhttpprzedstawionąwdokumencierfc2616 1. Wnioski Podstawa działania serwera protokołu HTTP jest bardzo prosta. Usługa tego rodzaju daje olbrzymie możliwości, które stały się podstawą dzisiejszego Internetu. Protokół HTTP ma prostą, tekstową budowę, dzięki czemu jego implementacja jest prosta i jednoznaczna. 1 http://www.w.org/protocols/rfc2616/rfc2616.html 4