Technologia WWW i protokół HTTP
Aż do lat 90. internet był przede wszystkim wykorzystywany przez naukowców, pracowników akademickich i studentów, którzy logowali się na zdalnych hostach, przesyłali pliki z lokalnych do zdalnych hostów i odwrotnie, odczytywali i wysyłali artykuły grup dyskusyjnych oraz wiadomości poczty elektronicznej. Choć wymienione zastosowania były i nadal są niezwykle przydatne, w zasadzie internet poza środowiskiem akademickim i naukowym nie był znany. Dopiero z początkiem lat 90. na scenie pojawiło się nowe istotne zastosowanie, czyli technologia WWW (ang. World Wide Web) [Berners-Lee 1994]. To ta technologia internetowa jako pierwsza zwróciła na siebie uwagę szerszej opinii publicznej. W zdecydowany sposób wpłynęła na to, w jaki sposób ludzie komunikowali się w obrębie miejsca pracy i poza nim. Technologia WWW sprawiła, że internet przestał być tylko jedną z wielu sieci, a zamiast tego zaczął pełnić rolę w zasadzie jedynej sieci służącej do wymiany danych.
Prawdopodobnie większość użytkowników zauważyła, że technologia WWW oferuje swoje usługi na żądanie. Użytkownicy w odpowiednim dla nich czasie otrzymują to, czego potrzebują. Jest to przeciwieństwem radia i telewizji, w przypadku których użytkownicy zainteresowani określoną audycją lub programem są zmuszeni do dostosowania się do tego, o jakiej porze zostanie wyemitowany przez operatora. Poza udostępnianiem danych na żądanie technologia WWW posiada wiele innych wspaniałych funkcji, które ludzie uwielbiają. Dla dowolnej osoby wyjątkowo proste będzie udostępnienie informacji przy użyciu technologii WWW. Ponosząc wyjątkowo niewielkie koszty, każdy może stać się dostawcą danych. Hiperłącza i wyszukiwarki ułatwiają nam poruszanie się w oceanie witryn WWW. Grafika i filmy stymulują nasze zmysły. Formularze, kod w JavaScripcie, aplety Java i wiele innych rozwiązań umożliwia nam interakcję ze stronami i witrynami WWW. Ponadto sieć WWW i jej protokoły stanowią platformę dla serwisu YouTube, internetowych klientów poczty elektronicznej (takich jak Gmail) oraz większości mobilnych aplikacji internetowych, takich jak Instagram i Google Maps.
Omówienie protokołu HTTP
HTTP (ang. HyperText Transfer Protocol) jest protokołem warstwy aplikacji stanowiącym podstawowy składnik technologii WWW. Specyfikacja protokołu została zawarta w dokumentach [RFC 1945] i [RFC 2616]. Protokół HTTP jest wykorzystywany w dwóch typach aplikacji — aplikacji klienta i serwera. Aplikacje klienta i serwera uruchomione w różnych systemach końcowych komunikują się ze sobą, wymieniając komunikaty HTTP. Protokół HTTP definiuje strukturę tych komunikatów i sposób, w jaki są one wymieniane między klientem i serwerem. Zanim szczegółowo omówimy protokół HTTP, Czytelnicy powinni zapoznać się z terminologią obowiązującą w przypadku technologii WWW.
Strona WWW (nazywa się ją też dokumentem) składa się z obiektów. Obiekt jest po prostu plikiem, takim jak plik HTML, plik graficzny JPEG, plik apletu Java, plik klipu audio itp. Obiekt jest adresowany przy użyciu pojedynczego adresu URL. Większość stron WWW jest złożona z podstawowego pliku HTML i kilku obiektów, do których są zdefiniowane odwołania. Jeśli na przykład w skład strony WWW wchodzi dokument HTML i pięć obrazów JPEG, posiada ona 6 obiektów — podstawowy plik HTML i 5 plików graficznych. Plik HTML odwołuje się do innych obiektów (wyświetlanych na stronie internetowej) za pomocą ich adresów URL. Każdy adres URL posiada dwa składniki — nazwę hosta serwera przechowującego obiekt i ścieżkę identyfikującą jego lokalizację. Oto przykładowy adres URL:
http://www.uczelnia.edu/wydzial/obraz.gif
W adresie łańcuch www.uczelnia.edu jest nazwą hosta, natomiast /wydzial/obraz.gif ścieżką określającą położenie obiektu. Ponieważ przeglądarki internetowe (takie jak Internet Explorer lub Firefox) reprezentują stronę klienta protokołu HTTP, w kontekście sieci WWW zamiennie będziemy posługiwali się terminami przeglądarka i klient. Serwery WWW reprezentują stronę serwerową protokołu HTTP i przechowują obiekty strony WWW, z których każdy jest adresowany przez adres URL. Popularnymi serwerami WWW są serwery Apache i Microsoft Internet Information Server. Protokół HTTP definiuje, w jaki sposób klienty WWW (na przykład przeglądarki) żądają stron internetowych od serwerów WWW, a także jak serwery przesyłają strony klientom. Dalej szczegółowo omówimy interakcję między klientem i serwerem, natomiast na rysunku 2.6 przedstawiono ogólną ideę działania protokołu. Gdy użytkownik zażąda strony internetowej (na przykład klikając hiperłącze), przeglądarka wyśle do serwera komunikaty żądań HTTP dotyczących obiektów wchodzących w skład strony.
Po odebraniu żądań w ramach odpowiedzi serwer odeśle komunikaty HTTP zawierające obiekty. W roli protokołu transportowego protokół HTTP wykorzystuje protokół TCP (zamiast protokołu UDP). W pierwszej kolejności klient HTTP inicjuje z serwerem połączenie TCP. Gdy to nastąpi, procesy przeglądarki i serwera uzyskują dostęp do protokołu TCP przy użyciu swoich gniazd pełniących rolę interfejsów. Jak wspomniano w podrozdziale 2.1, po stronie klienta gniazdo jest drzwiami znajdującymi się między procesem klienta i połączeniem TCP. Po stronie serwera gniazdo jest drzwiami między procesem serwera i połączeniem TCP. Klient wysyła do swojego gniazda komunikaty żądań HTTP i z tego samego gniazda odbiera odpowiedzi HTTP na żądania. Podobnie jest w przypadku serwera HTTP, który za pomocą swojego gniazda odbiera komunikaty żądań i wysyła komunikaty odpowiedzi. Gdy klient umieści komunikat w swoim gnieździe, jest on przekazywany protokołowi TCP, który przejmuje nad nim nadzór. Protokół TCP zapewnia protokołowi HTTP usługę niezawodnego transferu danych. Oznacza to, że każdy komunikat żądania HTTP wysłany przez proces klienta ostatecznie w niezmienionej postaci trafi do serwera. Podobnie każdy komunikat odpowiedzi HTTP wygenerowany przez proces serwera w niezmodyfikowanej postaci w końcu zostanie odebrany przez klienta. W ten sposób przedstawiliśmy jedną z wielkich zalet architektury warstwowej, która sprawia, że protokół HTTP nie musi się „martwić” o utratę danych lub szczegóły tego, w jaki sposób protokół TCP odzyska utracone dane bądź zmieni kolejność danych przesyłanych w sieci. Tym zajmuje się protokół TCP oraz protokoły położone w niższych warstwach stosu protokołów.
Rysunek 2.6. Przesyłanie żądań i odpowiedzi w protokole HTTP
Godne uwagi jest to, że serwer wysyła klientom żądane pliki bez potrzeby przechowywania informacji na temat konfiguracji klienta. Jeśli w przeciągu kilku sekund określony klient dwukrotnie zażąda tego samego obiektu, serwer nie odpowie, informując klienta, że właśnie przekazał mu ten obiekt, tylko ponownie go prześle, tak jakby całkowicie nie pamiętał, jakie operacje wykonał wcześniej. Ponieważ serwer WWW nie przechowuje żadnych informacji na temat klientów, protokół HTTP jest nazywany protokołem bezstanowym. Należy też podkreślić, że technologia WWW wykorzystuje architekturę klient-serwer. Serwer WWW jest zawsze dostępny, posiada stały adres IP i obsługuje żądania przychodzące od milionów różnych przeglądarek.
Połączenia nietrwałe i trwałe
W wielu aplikacjach internetowych klient i serwer komunikują się przez długi okres. W tym czasie klient wysyła serię żądań, a serwer odpowiada na każde z nich. W zależności od programu i sposobu jego stosowania żądania mogą być zgłaszane bezpośrednio po sobie, w stałych odstępach czasu lub nieregularnie. Jeśli interakcja między klientem i serwerem odbywa się za pośrednictwem protokołu TCP, autor aplikacji musi podjąć ważną decyzję — czy przesyłać każdą parę żądanie-odpowiedź przez odrębne połączenie TCP, czy kierować wszystkie żądania i powiązane z nimi odpowiedzi jednym takim połączeniem? To pierwsze rozwiązanie to tak zwane połączenia nietrwałe, natomiast drugie to połączenia trwałe. Aby dobrze zrozumieć to zagadnienie projektowe, warto zastanowić się nad wadami i zaletami połączeń trwałych w kontekście specyficznego zastosowania — protokołu HTTP, w którym wykorzystywane są zarówno trwałe, jak i nietrwałe połączenia. Choć w domyślnym trybie protokół HTTP używa połączeń trwałych, klienty i serwery stosujące ten protokół można też tak skonfigurować, aby stosowały połączenia nietrwałe.
Połączenia nietrwałe w HTTP
Przeanalizujmy krok po kroku proces transferowania strony internetowej z serwera do klienta, gdy są używane połączenia nietrwałe. Załóżmy, że strona jest złożona z podstawowego pliku HTML i 10 obrazów formatu JPEG. W sumie na tym samym serwerze znajduje się 11 obiektów. Przyjmijmy, że adres URL identyfikujący podstawowy plik HTML jest następujący: http://www.uczelnia.edu/wydzial/home.index
Proces składa się z następujących kroków:
1. Klient HTTP inicjuje połączenie TCP z serwerem www.uczelnia.edu za pomocą portu o numerze 80, który jest domyślnie używany przez protokół HTTP. Port ten jest powiązany z połączeniem TCP i posłuży jako gniazdo po stronie klienta oraz serwera.
2. Klient HTTP wysyła komunikat żądania HTTP do serwera za pośrednictwem swojego gniazda. Komunikat żądania zawiera ścieżkę /wydzial/home.index (poniżej bardziej szczegółowo omówimy komunikaty HTTP).
3. Proces serwera HTTP odbiera komunikat żądania przy użyciu swojego gniazda powiązanego z połączeniem, a następnie z pamięci (RAM lub dysk) pobiera obiekt /wydzial/home.index, kapsułkuje go w komunikacie odpowiedzi HTTP, który odsyła klientowi, korzystając ze swojego gniazda.
4. Proces serwera HTTP nakazuje protokołowi TCP zakończenie połączenia TCP (jednak protokół nie wykonuje tej operacji do momentu, aż uzyska pewność, że klient otrzymał komunikat odpowiedzi w niezmienionej postaci).
5. Klient HTTP odbiera komunikat odpowiedzi. Połączenie TCP jest kończone. Komunikat wskazuje, że kapsułkowanym obiektem jest plik HTML. Klient wyodrębnia plik z komunikatu, a następnie sprawdza go i odnajduje odwołania do 10 obiektów będących obrazami formatu JPEG.
6. Dla każdego z obrazów są powtarzane pierwsze cztery kroki.
Po otrzymaniu strony internetowej przeglądarka wyświetla ją użytkownikowi. Dwie różne przeglądarki mogą w odmienny sposób interpretować (przedstawiać użytkownikowi) stronę internetową. Protokół HTTP nie ma nic wspólnego z tym, jak strona WWW będzie interpretowana przez klienta. Specyfikacje protokołu HTTP ([RFC 1945] i [RFC 2616]) definiują jedynie protokół komunikacyjny pośredniczący między aplikacją klienta i serwera HTTP.
Powyższe kroki prezentują zastosowanie połączeń nietrwałych, w przypadku których każde połączenie TCP jest kończone po przesłaniu przez serwer obiektu. Połączenie nie jest utrzymywane dla innych obiektów. Warto zauważyć, że każde połączenie TCP transportuje dokładnie jeden komunikat żądania i odpowiedzi. A zatem, gdy w przytoczonym przykładzie użytkownik zażąda strony internetowej, zostanie wygenerowanych 11 połączeń TCP.
W powyższych krokach celowo nie określiliśmy precyzyjnie, czy klient pobiera 10 obrazów JPEG za pośrednictwem 10 szeregowych połączeń TCP, czy część obrazów jest uzyskiwana przy użyciu równoległych połączeń TCP. Tak naprawdę użytkownicy mogą tak skonfigurować nowsze przeglądarki, aby mogli kontrolować stopień równoległości. Domyślnie większość przeglądarek nawiązuje od 5 do 10 równoległych połączeń TCP, z których każde obsługuje jedną transakcję żądanie-odpowiedź. Jeśli użytkownik woli, jako liczbę maksymalnych połączeń równoległych może ustawić wartość 1 (wtedy sekwencyjnie nawiązywanych jest 10 połączeń). Jak się okaże w kolejnym rozdziale, użycie równoległych połączeń skraca czas odpowiedzi.
Zanim przejdziemy dalej, wykonajmy obliczenie mające na celu oszacowanie czasu, jaki upłynie od wysłania przez klienta żądania podstawowego pliku HTML do chwili odebrania przez niego całego pliku. W związku z tym zdefiniujemy czas RTT (ang. Round-Trip Time), który identyfikuje czas potrzebny na przesłanie niewielkiego pakietu od klienta do serwera i z powrotem. Czas RTT uwzględnia opóźnienia związane z propagacją pakietu, jego kolejkowaniem w pośredniczących routerach i przełącznikach, a także z przetwarzaniem pakietu. Zastanówmy się teraz, co się stanie, gdy użytkownik kliknie hiperłącze. Jak widać na rysunku 2.7, operacja spowoduje zainicjowanie przez przeglądarkę połączenia TCP między nią i serwerem WWW. Z związku z tym jest realizowany proces negocjowania złożony z 3 etapów. W pierwszym etapie klient wysyła serwerowi niewielki segment TCP, w drugim etapie serwer generuje potwierdzenie i w odpowiedzi odsyła segment TCP, natomiast w trzecim klient przesyła potwierdzenie serwerowi. Czas realizacji pierwszych dwóch etapów jest równy czasowi RTT. Po zakończeniu tych etapów procesu negocjowania klient wysyła komunikat żądania HTTP w ramach trzeciego etapu (odsyłanie serwerowi potwierdzenia) negocjowania połączenia TCP.
Rysunek 2.7. Proste obliczanie czasu odpowiedzi serwera na żądanie pobrania pliku HTML
Gdy komunikat żądania pojawi się na serwerze, za pośrednictwem połączenia TCP serwer prześle plik HTML. Wykonanie tej operacji żądanie-odpowiedź zajmuje kolejny czas RTT. A zatem całkowity czas odpowiedzi w przybliżeniu jest równy dwukrotnemu czasowi RTT powiększonemu o czas transmisji pliku HTML przez serwer.
Połączenia trwałe w HTTP
Połączenia nietrwałe mają kilka wad. Po pierwsze, dla każdego żądanego obiektu musi być nawiązywane i utrzymywane zupełnie nowe połączenie. W przypadku każdego takiego połączenia muszą być przydzielane bufory protokołu TCP, natomiast jego zmienne muszą być przechowywane zarówno na serwerze, jak i kliencie. Może to spowodować poważne obciążenie serwera WWW, który może obsługiwać żądania generowane jednocześnie przez setki różnych klientów. Po drugie, jak już wspomnieliśmy, każdego obiektu dotyczy opóźnienie związane z jego dostarczaniem, które jest równe dwukrotnemu czasowi RTT (czas RTT potrzebny na nawiązanie połączenia TCP i czas RTT, jaki zajmuje zażądanie obiektu i jego otrzymanie).
W HTTP 1.1 w przypadku połączeń trwałych po wysłaniu odpowiedzi serwer pozostawia aktywne połączenie TCP. Kolejne żądania i odpowiedzi wymieniane między tym samym klientem i serwerem mogą być przesyłane przy użyciu tego połączenia. Tak więc cała strona internetowa (w powyższym przykładzie składa się z podstawowego pliku HTML i 10 obrazów) może zostać przekazana za pośrednictwem pojedynczego trwałego połączenia TCP. Co więcej, takim połączeniem może zostać przesłanych do tego samego klienta wiele stron internetowych znajdujących się na tym samym serwerze.
Żądania obiektów można generować jedno po drugim, bez konieczności oczekiwania na otrzymanie odpowiedzi na wcześniejsze żądania (ta technika to potokowanie). Zwykle serwer WWW kończy połączenie, gdy nie jest używane przez określony okres (konfigurowalny czas bezczynności). Gdy serwer odbiera takie żądania, również wysyła obiekty jeden po drugim. Domyślnie protokół HTTP korzysta z połączeń trwałych z potokowaniem. Nowszy protokół HTTP/2 [RFC 7540] jest oparty na HTTP 1.1 i umożliwia przeplatanie wielu żądań i odpowiedzi w tym samym połączeniu. Dostępny jest też mechanizm priorytetyzowania żądań i odpowiedzi HTTP w ramach takiego połączenia.
Opracowano na podstawie: