Co z tym HTTP? Zrozum podstawy komunikacji internetowej

przez Mateusz Hoffman
Mateusz w sklepie z gry Skyrim żądający o zasoby poprzez HTTP

Otwierasz przeglądarkę, wpisujesz adres swojego ulubionego portalu i… jest! Czasem szybciej, czasem wolniej ale nareszcie Twoim oczom ukazuje się treść okraszona warstwą wizualną niczym te zostawiane na talerzykach w ekskluzywnych kawiarniach płatki kwiatków, listki i zastanawiający Cię sos (a przecież chciałeś tylko zjeść sernik jak człowiek).

Czy zastanawiałeś się czasem jak przebiega ten proces wymiany danych w sieci? A może jesteś programistą i „masz wrażenie, że kumasz jak to działa ale właściwie po co Ci to jak płacą Ci za 5 lat znajomości Reacta a nie jakieś tam teorie”? Poświęcając te kilka minut Twojego cennego czasu na przeczytanie tego artykułu obiecuję, że raz na zawsze zrozumiesz i będziesz w stanie odpowiedzieć na fundamentalne pytanie: co z tym HTTP?

Zacznij od zrozumienia struktury komunikacji

Jak wymieniamy informacje w sieci komputerowej? Każdy z nas zadaje sobie to pytanie w poniedziałkowy poranek przy pachnącej jajecznicy (lub z racji, że nie zaniedbuje społeczności wegańskiej – tofucznicy). Otóż w latach 70-tych ubiegłego wieku, przemiła ekipa zwana Międzynarodową Organizacją Normalizacyjną (ISO) postanowiła podzielić ową strukturę bazując na zdefiniowaniu 7 warstw komunikacji i nazwała ją na cześć zwyciężczyni czwartej edycji Top Model czyli Model OSI (ang. ISO Open Systems Interconnection Reference Model).

Obrazek przedstawiający 7 warstw modelu OSI

Nie będziemy się jednak dziś zbytnio skupiać na szczegółach tego modelu referencyjnego – piszę o tym aby ułatwić Wam zrozumienie działania naszego głównego bohatera wieczoru czyli protokołu HTTP (widocznego w 7 warstwie czyli warstwie aplikacji). Drugim ważnym elementem będzie zaś warstwa czwarta zwana transportową a konkretnie protokoły TCP i UDP.

A samym HTTP słów kilka

Czyli wiemy już, że HTTP jest protokołem (szczególnie, że jego pełna nazwa to Hypertext Transfer Protocol). Jak to rozumieć? Czym jest protokół? Tutaj z pomocą przychodzi nam Wikipedia ze swoją definicją w ogólnym znaczeniu tego terminu:

W najbardziej ogólnym sensie: zestaw reguł umożliwiających porozumienie. Przykładem może być protokół dyplomatyczny, wypracowany w ciągu stuleci w celu zażegnania konfliktów występujących w trakcie oficjalnych wizyt przedstawicieli obcych państw u przedstawicieli władz. W tym sensie słowo to jest też używane zamiennie z etykietą.

W wypadku systemów komputerowych możemy to zrozumieć jako zestaw reguł i instrukcji umożliwiających wymianę informacji między dwoma urządzeniami/systemami.

W tym wypadku mówimy o modelu klient-serwer czyli wymianie danych pomiędzy naszą przeglądarką w serwerem przeglądanej przez nas strony. Protokół HTTP bowiem skupia się na tym co i w jakiej formie będziemy wymieniać, samą stabilność tego połączenia i transport pakietów zapewnia nam protokół z warstwy czwartej czyli TCP.

Klient nasz Pan? Ja żądam, Ty odpowiadasz!

Najłatwiejszą do zrozumienia analogią może być tu wizyta w sklepie spożywczym. Jako klient (przeglądarka), przychodzisz do sklepu w celu zakupu produktów na wieczorną imprezkę urodzinową (odwiedzasz konkretną witrynę). W ręku trzymasz listę zakupów, która jest konieczna do przygotowania poszczególnych dań na wieczór (tu odpowiednikiem jest lista assetów, które musimy pobrać z serwera aby strona mogła się uruchomić – mowa tu o pliku HTML, CSS, skryptach JS, obrazkach i wielu innych zasobach, które składają się na naszą stronę). Prościej? Prościej.

No i co teraz? Wypadało by poprosić ekspedienta (nasz serwer)

Obrazek ilustrujący przeglądarkę w sklepie

Żądania HTTP (request)

Prośbę taką nazywamy żądaniem i w wirtualnej formie wygląda ona mniej więcej tak jak na tym przykładzie:

Przykład requestu HTTP

Rozkładając przykład na czynniki pierwsze możemy tu doszukać się takich elementów jak:

  • Typ/metoda żądania (na przykładzie GET) – po co przyszedłeś? Chcesz coś kupić? Sprzedać? Wymienić? Bazując na obecnej wersji HTTP rozróżniamy takie typy jak GET, POST, PUT, DELETE, OPTIONS, CONNECT, HEAD, TRACE
  • Ścieżka do zasobu (na przykładzie / oznaczający bazową lokalizacje) – innymi przykładami mogą być „/login”, „/strona-2” czy „/memy-o-morsowaniu”
  • Wersja protokołu (na przykładzie HTTP/1.1) – najczęściej spotykaną wersją od ponad 20 lat pozostaje wersja 1.1 a czym się różnią i jaka jest ich historia rozwoju opowiemy sobie za chwilę
  • Inne nagłówki – umieszczane w żądaniu mają na celu przekazanie dodatkowych informacji serwerowi do ich prze-procesowania
  • Ciało żądania – o ile w przypadku zapytań GET ono nie występuje, o tyle w innych, bardziej manipulatywnych typach jak np. POST (SQL-owy odpowiednik INSERT’a) czy PUT (SQL-owy odpowiednik UPDATE), potrzeba nam dodatkowych danych, które przekazujemy serwerowi (dla przykładu nazwa produktu i jego cena aby dodać nowy produkt do sklepowych półek)
  • Linia końca – często spotykany błąd i element frustracji u osób próbujących wysłać żądanie. Obowiązkowa pusta linia na końcu informuje serwer, że nasze żądanie zostało zakończone.

O ile w prawdziwym sklepie taka forma pytania ekspedienta o produkty ze sklepowych półek była by nieco frustrująca, o tyle w świecie komunikacji sieciowej jest to świetny pomysł.

Odpowiedzi HTTP (response)

Piłeczka po Twojej stronie, Panie sklepowy! Po otrzymaniu i prze-procesowaniu żądania od przeglądarki, serwer wysyła nam odpowiedź w równie subtelnej formie.

Przykład odpowiedzi HTTP

Po raz kolejny umówmy sobie powyższy przykład i rozbijmy go na składowe.

Pierwsza linia składa się ze znanej nam z żądania wersji protokołu (w tym wypadku HTTP/1.1) oraz przede wszystkim kodu odpowiedzi. Kod odpowiedzi przekazuje nam informacje dt. powodzenia bądź też niepowodzenia naszego żądania – reprezentowane jest to przez kody o wartościach liczbowych, które możemy podzielić na kilka kategorii bazując na pierwszej cyfrze:

  • (100-199) : kody informacyjne – żądanie zostało dostarczone i kontynuujemy jego procesowanie
  • (200-299): kody powodzenia – żądanie pomyślnie dotarło do adresata i zostało przetworzone przez serwer.
  • (300-399): kody przekierowań – dalsze akcje muszą zostać wykonane aby zakończyć żądanie
  • (400-499): kody błędów klienta – wystąpił błąd z treścią wysyłanego żądania lub żądanie nie może zostać spełnione
  • (500-599): kody błędów serwera – żądanie zostało zaakceptowane aczkolwiek wystąpił błąd podczas jego procesowania

Polecam wczytanie się w poszczególne kody statusu a żeby uprzyjemnić Wam ten proces przedstawiam stronę HTTP Cats, która może zostać użyta w Waszej witrynie aby przedstawić konkretny status w formie śmiesznego obrazka z kotem.

Kod 401 w formie śmiesznego obrazka z kotem

Kolejne nagłówki przekazują nam dodatkowe informacje od naszego ekspedienta-serwera takie jak data i czas powiązana z żądaniem, informacje dotyczące serwera (na przykładzie widać, że operujemy tu na serwerze Apache w wersji 2.2), informacje dotyczące samej treści odpowiedzi (jaki jest jej typ, długość – w powyższym przykładzie wartością zwracaną jest plik HTML).

Ostatni nagłówek (tj. Connection: Closed) mówi nam o tym, że nasze połączenie TCP z serwerem zostało zamknięte wraz z otrzymaniem tejże odpowiedzi.

Czy może być inaczej? Czy połączenie jest zawsze zamykane? Jakie to niesie za sobą konsekwencje?

Historia HTTP i jej konsekwencja na dzień dzisiejszy

Powiedzieliśmy sobie trochę na temat samych żądań i odpowiedzi. Jednak w jaki sposób ta komunikacja jest utrzymywana? Tutaj przyda nam się powrót do roku 1995, kiedy to wydana została wersja HTTP/1.0.

Niezbyt szybko ale za to budżetowo, czyli HTTP/1.0

W czasach kiedy wielkość pamięci RAM sięgała 64 MB i usilnie szukano sposobów jak jej nie wykończyć poprzez optymalizacje operacji. Jedną z takich optymalizacji, która skutecznie oszczędzała dodatkowe megabajty było konsekwentne zamykanie połączenia TCP po każdym żądaniu. Znów odnieśmy się do przykładu ze sklepem:

Obrazek ilustrujący komunikacje HTTP w wersji 1.0

Na tamte czasy to był świetny pomysł – szczególnie na czasy prostych stron internetowych nie będących wizualnymi molochami. Ten pomysł miał jednak jeden minus – takie otwieranie i zamykanie połączeń było okropnie wolne jako, że chociażby inicjalizacja połączenia TCP i osiągnięcie docelowej przepustowości zabierało trochę czasu. Na poprawki nie trzeba było czekać zbyt długo a były one na tyle zjadliwe że przetrwały do dziś.

Szybka zmiana i prawie 20 lat tradycji, czyli HTTP/1.1

HTTP WG w niecały rok dostarczyło nam usprawnioną wersję HTTP, która towarzyszy nam w wielu przypadkach po dziś dzień. Co nowego? Sporo, między innymi takie rzeczy jak:

  • Nowe typy żądań bez których twórcy REST-owego API nie wyobrażają sobie życia czyli PUT oraz DELETE
  • Możliwość wysyłki (streamowania) plików w kawałkach – przykładem niech będzie tu klasyczny obrazek ładujący się „warstwami” od góry, który widzimy podczas ładowania strony internetowej
  • Cachowanie + eTagi (o których w przyszłości przygotuję osobny artykuł)
  • Wsparcie dla proxy (wymagany header Host)
  • Usprawniona kompresja
  • Ale przede wszystkim możliwość wymiany wielu żądań-odpowiedzi podczas jednego połączenia TCP (ogromna oszczędność czasu)

Jak by to wyglądało w naszym sklepowym przykładzie?

Obrazek ilustrujący komunikacje HTTP w wersji 1.1

Zmiana ta była na tyle istotna i satysfakcjonująca, że protokół HTTP w wersji 1.1 przetrwał po dziś dzień. Jednak czymże były człowiek bez swojej tendencji do usprawniania i wdrażania innowacji do wszystkiego co nas otacza? W roku 2015 bowiem, świat ujrzał wersję nazwaną HTTP/2.0.

Czy można szybciej ale jednocześnie bezpieczniej? Powitajcie HTTP/2.0

XXI wiek obfitował w ogromny rozwój światowego internetu. Ilość witryn wzrastała w niewyobrażalnym tempie a ich przeznaczenie coraz częściej wykraczało poza cel czysto informacyjny. Takie zmiany skutkowały zwiększonej liczbie obserwacji i poszukiwaniu zmian, które lepiej odnalazły by się w dobie bieżących potrzeb. Co zatem nowego?

  • Zaawansowana kompresja nagłówków – metoda HPACK redukuje ilość zbędnych informacji w nagłówkach przez co jest zwięźlej i szybciej
  • Server push – umożliwia serwerowi „wypchnięcie” zasobów o które nie został poproszony. Powoduje to, że nowoczesne aplikacje zawierające mnóstwo elementów nie muszą żądać każdego z nich z osobna i serwer jest w stanie wyjść tu z pomocą dłonią i sam wysłać nam zbiorczo resztę elementów (informując wcześniej o liście zasobów, które ma zamiar wysłać)
  • Praca na danych binarnych zamiast tekstowych – zmniejszona błędogenność oraz zwiększona szybkość transmisji
  • Oraz znów na końcu jako największy smaczek został mechanizm zwany multiplexing – możliwość niejako połączenia wielu zapytań i wysłania ich jednocześnie. Tutaj posilę się obrazkiem znalezionym w sieci jako, że najlepiej oddaje tę zmianę.
    Obrazek ilustrujący zjawisko multiplexingu

    Źródło: https://factoryhr.medium.com/http-2-the-difference-between-http-1-1-benefits-and-how-to-use-it-38094fa0e95b

Co nas czeka w przyszłości? HTTP/3.0

Na początku roku 2020 nastąpiło wdrożenie nowej wersji protokołu zwanej wcześniej HTTP/2.0 with QUIC a przemianowanej później na HTTP/3.0.

Bazuje on na zmianie protokołu na warstwie transportowej z TCP (w duecie z TLS) na UDP, który jest zdecydowanie szybszy lecz przez długi okres czasu odrzucany był przez fakt, że jest on zbudowany w myśli „strzelania” pakietami z dużą stratnością oraz brakiem potwierdzenia czy takie zapytanie doszło do skutku. Ten brak stabilności oraz kontroli spowodował, że na wiele lat zdecydowaliśmy się trzymać TCP jako naszego „transportera”.

Jak robi to HTTP/3.0? Otóż używa on nowego protokołu sieciowego zwanego QUIC, który wymyślony został przez firmę Google w roku 2012 i tak jak wspominałem w akapicie powyżej, bazuje on na protokole UDP i implementuje szereg poprawek powodujących, że mistyczne szybko i dobrze staje się możliwe.

Większość przeglądarek implementuje już HTTP w wersji 3.0 jednak pozostaje on domyślnie zablokowany i można go aktywować przy użyciu eksperymentalnych flag. Wyjątkiem jest tutaj Safari, które w wersji 14 wydanej we wrześniu roku 2020 posiada tę funkcję dostępną i aktywowaną domyślnie.

 

Animacja pokazująca szybkość protokołu QUIC

Żródło: https://medium.com/devgorilla/what-is-http-3-94335c57823f

 


Słowem zakończenia

Mam nadzieje, że teraz rozumiesz już jak ważny dla rozwoju internetu jest protokół HTTP i jak drobne zmiany i obserwacja bieżących potrzeb generuje potrzebę na kolejne jego usprawnienia. Jeżeli tu dotarłeś to dziękuję za poświęcenie czasu na przeczytanie tego posta i mam nadzieje, że ta fundamentalna wiedza przyda Ci się w Twojej pracy lub też ogólnym zrozumieniu tego zjawiska.

Spokojnego tygodnia,

 

Darmowy ebook dla subkrybentów

You may also like