Jak działa metoda HTTP GET w stosunku do protokołu DNS?

18

Próbuję zrozumieć protokoły warstwy aplikacji w stosie TCP / IP. Wiem, że zarówno protokół HTTP, jak i DNS pozostają na górnej warstwie (Warstwa aplikacji). Tak więc, gdy przeglądarka chce uzyskać dostęp do zasobu, musi wysłać żądanie do serwera HTTP, na przykład:

GET www.pippo.it/hello.htm HTTP/1.1

Wysyłając to żądanie zgodnie z regułami protokołu HTTP, używa adresu URL strony, a nie adresu IP.

Wiem, że żądanie DNS jest konieczne do konwersji adresu URL na adres IP. Moje pytanie brzmi: czy HTTP wywołuje protokół DNS? Wydaje mi się to niemożliwe, ponieważ oba są protokołami najwyższej warstwy (więc DNS nie może zapewnić usługi HTTP). W ten sam sposób nawet TCP (który pozostaje na niższym poziomie) nie może poprosić o usługę na protokole wyższego poziomu, takim jak DNS.

Kiedy więc pojawia się żądanie DNS? A kto wykonuje takie żądanie?

Giancarlo Perlo
źródło
1
Czy możesz zaakceptować jedną z odpowiedzi, aby wyjaśnić, która z tych odpowiedzi stanowi pytanie?
030

Odpowiedzi:

38

Żądanie HTTP, o którym mowa, jest w rzeczywistości nieprawidłowe, chyba że przeglądarka rozmawia z pośrednikiem (proxy).

Twój przykład wyglądałby bardziej jak poniżej, gdyby przeglądarka bezpośrednio komunikowała się z serwerem sieciowym:

GET /hello.htm HTTP/1.1
Host: www.pippo.it

Teraz, aby spojrzeć na to z perspektywy, rozważ model OSI:

Model OSI

W akcji mamy 3 systemy:

  • Klient uruchamiając przeglądarkę
  • Serwer WWW obsługujących witrynę
  • Serwer DNS znając adres IP strony

Stosowane protokoły są od dołu do góry (minimalny odpowiedni zestaw do PO):

  • IP
  • TCP, UDP
  • HTTP, DNS

Komunikacja HTTP odbywa się za pośrednictwem protokołu TCP (TCP znajduje się nad protokołem IP), podczas gdy komunikacja DNS w tym przypadku odbywa się za pośrednictwem protokołu UDP (UDP jest również nad protokołem IP).

Oto sekwencja komunikacji w skrócie:

  1. Klienta , uruchamiając przeglądarkę, zwraca się do serwera DNS za Arekord www.pippo.it, przy użyciu protokołu UDP.

    1.1 Na kliencie jest to system operacyjny, który wykonuje część rozstrzygającą i odsyła do przeglądarki --- przeglądarka nigdy nie komunikuje się bezpośrednio z serwerem DNS, raczej poprzez system operacyjny, wywołując gethostbyname () lub nowszą getaddrinfo () . W systemie Windows, kolejność, w jakiej OS rozwiązuje adresy prawdopodobne jest zdefiniowany przez coś takiego jak ten , podczas gdy w systemie Linux pierwszeństwo rozwiązywaniu jest zdefiniowana przez/etc/nsswitch.conf

  2. Serwer DNS , korzystając z protokołu UDP, odpowiada klientowi za pomocą rekordu / adresu IP, jeśli istnieje

  3. Klient otwiera połączenie TCP na porcie 80 na serwerze WWW i zapisuje się następujący tekst:

    Żądanie HTTP:

    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    Możesz naśladować to samo, robiąc coś takiego w konsoli lub wierszu polecenia:

    > telnet www.pippo.it 80
    Trying 195.128.235.49...
    Connected to www.pippo.it.
    Escape character is '^]'.
    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    a następnie dwie puste linie. Jeśli żądana treść istnieje, serwer internetowy wydrukuje ją na ekranie. Jeśli po drugiej stronie znajduje się przeglądarka, tekst odpowiedzi jest analizowany przez przeglądarkę, a wszystkie tagi, łącza, skrypty i obrazy są renderowane na tak zwanej stronie internetowej.

W rzeczywistości istnieje kilka dodatkowych szczegółów, np. Przeglądarki mogą buforować adresy IP, jeśli już odwiedziłeś jakąś domenę, więc rozpoznawanie DNS staje się zbędne. Ponadto nowoczesne przeglądarki mogą próbować rozwiązać problem, zanim rzeczywiście go potrzebujesz ( pobieranie DNS ), aby przyspieszyć przeglądanie.

Ponadto komputer może zawierać statyczne rekordy w hostspliku. Jeśli rekord pasuje do żądania, lokalny wpis statyczny jest wykorzystywany jako pierwszy i nigdy nie kontaktuje się z żadnym serwerem DNS. Jest to konfigurowalne i niekoniecznie prawdziwe, ale jest domyślne w systemach operacyjnych, które znam.

Hrvoje Špoljar
źródło
4
@trikly: do tego właśnie służy nagłówek „Host”. Bez niego możesz mieć tylko jedną stronę internetową na adres IP. Jest to kluczowa różnica między HTTP / 1.0 a HTTP / 1.1. Na szczęście przeglądarki HTTP / 1.0 są teraz rzadkie - ale jeśli chcesz się nimi zająć, potrzebujesz innego adresu IP dla każdej witryny (nadal mogą być hostowane na tym samym serwerze).
AE
1
@AE Dzięki. Myślę, że moje pytanie było niejasne i dlatego Hrvoje nie rozumiał, co mówię. (Powinienem był powiedzieć domenę zamiast adresu URL). Cieszę się, że wciąż rozumiesz.
trlkly,
1
Mówisz „ To nie jest poprawne żądanie HTTP ” i jest to w większości prawda, ale jest bliżej niż sugerujesz: „ Aby umożliwić przejście na wartości bezwzględne we wszystkich żądaniach w przyszłych wersjach HTTP, wszystkie serwery HTTP / 1.1 MUSZĄ zaakceptować formularz bezwzględny w żądania ”. (RFC 2616 §5.1.2) GET http://www.pippo.it/hello.htm HTTP/1.1Byłoby to zatem ważne, jeśli nietypowe, żądanie. Byłoby to również prawidłowe i zwykłe żądanie do serwera proxy HTTP.
wfaulk
1
gethostbyname()jest nieco przestarzały. Lepiej byłoby użyć getaddrinfo()...
glglgl
1
@Utku niestety nie, ponieważ SSH zakłada, że ​​drugi koniec mówi protokołem SSH, podczas gdy telnet jest protokołem zwykłego tekstu i może być używany do komunikowania się z dowolnym innym zwykłym protokołem, takim jak np. POP3, IMAP, o ile nie używają protokołu SSL / TLS. będzie musiał zakończyć sesję telnet pomocnikiem, takim jak sslwrap lub coś podobnego.
Hrvoje Špoljar
12

HTTP jest przesyłany przez TCP, który jest protokołem IP. Aby złożyć żądanie HTTP, przeglądarka musi otworzyć połączenie TCP, a do tego potrzebuje docelowego adresu IP (tj. Adresu IP serwera). Aby rozwiązać nazwę hosta serwera, musi on zatem wysłać żądanie DNS (zazwyczaj samo żądanie DNS jest wysyłane przez system operacyjny, gdy program wywołuje funkcje rozpoznawania nazw; jednak nic nie stoi na przeszkodzie, aby program sam wysyłał żądania DNS do DNS serwer). Po ustanowieniu połączenia może wysłać żądanie HTTP, które zawiera ścieżkę do żądanego zasobu oraz pole Host z nazwą hosta serwera (np Host: www.pippo.it.). Nazwa hosta ma nie iść na linii żądania (to faktycznie byćGET /hello.htm HTTP/1.1), z wyjątkiem sytuacji, gdy żądanie jest wysyłane do serwera proxy HTTP (w tym przypadku obecny jest pełny adres URL, w tym część protokołu, np. GET http://www.pippo.it/hello.htm HTTP/1.1),

Ale
źródło
Dzięki, teraz jest wyraźniej, ale nie do końca. Piszesz, że przeglądarka musi wysłać żądanie DNS. Ok, ale po otrzymaniu adresu IP z serwera DNS, jak go wykorzystuje? Mam na myśli, że taki adres IP nie pojawia się w żądaniu HTTP. Zakładam więc, że przed wydaniem żądania HTTP jest jeszcze jeden krok i myślę, że jest to otwarcie połączenia. Ten punkt nie jest dla mnie zbyt jasny ... Jeszcze raz dziękuję!
Giancarlo Perlo,
5
Rzeczywiście, adres IP jest potrzebny do otwarcia połączenia TCP, w którym przesyłane jest żądanie HTTP. W rzeczywistości adres IP klienta i serwera jest wysyłany wraz ze WSZYSTKIMI pakietami połączenia. Najlepszym sposobem, aby dowiedzieć się, jak to działa, jest prawdopodobnie zainstalowanie narzędzia do przechwytywania pakietów (Wireshark to doskonałe narzędzie wieloplatformowe i typu open source), przechwytywanie prostego żądania HTTP, odfiltrowywanie go od reszty aktywności sieciowej i sprawdzanie, w jaki sposób wszystkie pakiety zostały wysłane przewodem. Powinieneś być w stanie zobaczyć również żądanie DNS przed połączeniem TCP.
Ale
1
Żądania proxy powinny używać nagłówka Host, a nie umieszczać pełnego adresu URL w wierszu GET.
OrangeDog,
1
@OrangeDog: Nie, wręcz przeciwnie. RFC 7230 (sekcja 5.3.2) wyraźnie stwierdza, że ​​klient wysyłający żądanie do proxy MUSI użyć bezwzględnego identyfikatora URI w wierszu żądania. (Nie musi nadal być nagłówka Host powielanie informacji od linii żądanie; sekcja 5.4).
hmakholm opuścił Monikę
8

Procedura wygląda następująco:

  1. Użytkownik (ty) podaje przeglądarce adres URL, taki jak http://www.pippo.it/hello.htm
  2. Przeglądarka dzieli to na trzy części:

    • Protokół http
    • Nazwa hosta www.pippo.it
    • Ścieżka URL /hello.htm

    (bardziej skomplikowany adres URL może również zawierać inne części, na razie zignoruję tę możliwość)

  3. Przeglądarka wie, że aby utworzyć połączenie IP, potrzebuje adresu IP. Aby uzyskać adres IP, musi używać DNS (chyba że ma buforowany adres).

    1. Przeglądarka pyta system operacyjny o adres IP serwera DNS; załóżmy, że tak 8.8.8.8.
    2. Przeglądarka tworzy następujące połączenie wielowarstwowe:

      • Warstwa IP: połącz się z 8.8.8.8
      • Warstwa UDP: ustaw pakiet dla docelowego portu 53
      • Warstwa DNS: utwórz żądanie DNS dotyczące Arekordu dla nazwy hostawww.pippo.it

      Oczywiście pomijam wiele szczegółów na temat np. Dokładnego formatu zaangażowanych pakietów.

    3. Przeglądarka otrzymuje odpowiedź DNS (nałożoną na UDP nałożoną na IP itp.), Która podaje adres IP www.pippo.it, powiedzmy, że to10.11.12.13
  4. Przeglądarka wie, że do utworzenia połączenia TCP potrzebny jest numer portu. Aby uzyskać numer portu, sprawdza protokół httpw swojej wewnętrznej tabeli i dowiaduje się, że powinien używać portu 80.
  5. Przeglądarka tworzy następujące połączenie wielowarstwowe:

    • Warstwa IP: połącz się z 10.11.12.13
    • Warstwa TCP: ustaw pakiety na docelowy port 80
    • Warstwa HTTP: utwórz żądanie HTTP dotyczące adresu URL /hello.htmna hoście www.pippo.it(ponieważ komputer 10.11.12.13może być hostem dla wielu domen, więc musi wiedzieć, która jest pożądana)

      GET /hello.htm HTTP/1.1
      Host: www.pippo.it
      ...
      

    Oczywiście pomijam wszystkie szczegóły uzgadniania TCP i tym podobne.

  6. Przeglądarka odbiera odpowiedź HTTP (warstwowa na TCP warstwowa na IP itp.) Zawierająca zawartość hello.htm

Na wszelki wypadek wspomnę, że przeglądarka analizuje teraz treść tej odpowiedzi i identyfikuje wszelkie dodatkowe potrzebne zasoby: obrazy, CSS, JavaScript itp. Następnie powtarza ten cały proces dla każdego takiego zasobu.

David Z
źródło
4
Krok 3 naprawdę nie jest czymś, co robi sama aplikacja. Aplikacja po prostu używa czegoś podobnego getaddrinfolub gethostbynameprosi system operacyjny o rozpoznanie adresu. Ponadto system operacyjny zwykle używa wielu mechanizmów do wyszukiwania nazw, nie tylko DNS. (Zazwyczaj przynajmniej plik hosta oprócz DNS.)
Håkan Lindqvist
Dzięki! To naprawdę imponująca i szczegółowa odpowiedź, a także bardzo przydatna!
Giancarlo Perlo,
To najlepsza odpowiedź.
Xin