HTTP GETメソッドは、DNSプロトコルに関連してどのように機能しますか?


17

TCP / IPスタックのアプリケーション層プロトコルを理解しようとしています。HTTPプロトコルとDNSプロトコルの両方が最上位層(アプリケーション層)にとどまることを知っています。そのため、ブラウザがリソースにアクセスする場合は、たとえば次のようにHTTPサーバーにリクエストを送信する必要があります。

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

HTTPプロトコルの規則に従ってこの要求を行うと、IPアドレスではなくページURLが使用されます。

URLをIPに変換するにはDNS要求が必要であることを知っています。私の質問は次のとおりです。HTTPはDNSプロトコルを呼び出しますか?どちらも最上位層のプロトコルであるため(DNSはHTTPにサービスを提供できません)、私には不可能のようです。同様に、TCP(より低いレベルにとどまる)でさえ、DNSのようなより高いレベルのプロトコルでサービスを要求することはできません。

では、DNS要求はいつ発生しますか?そして、誰がそのような要求を実行しますか?


1
これらの回答のどれが質問を明確にするために、回答の1つを受け入れてもらえますか?
030 14年

回答:


38

問題のHTTP要求は、ブラウザが仲介者(プロキシ)と通信していない限り、実際には無効です。

ブラウザーがWebサーバーと直接通信している場合、例は次のようになります。

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

次に、これを理解するために、OSIモデルを検討します。

OSIモデル

動作中のシステムは3つあります。

  • クライアントブラウザを実行しています
  • サイトを提供するWebサーバー
  • DNSサーバーサイトのIPアドレスを知ります

関連するプロトコルは、下から上(OPに関連する最小限のセット)です。

  • IP
  • TCP、UDP
  • HTTP、DNS

HTTP通信はTCPプロトコル(TCPはIPプロトコルの上)で行われますが、この場合、DNS通信はUDPプロトコル(UDPもIPプロトコルの上)で行われます。

短い通信シーケンスを次に示します。

  1. クライアントは、ブラウザを実行し、要求するDNSサーバーAのレコードをwww.pippo.itUDPプロトコルを使用して、。

    1.1。クライアントでは、解決部分を実行してブラウザに戻るオペレーティングシステムです。ブラウザは、gethostbyname()または新しいgetaddrinfo()を呼び出してOSを介してDNSサーバーと直接通信することはありません。Windowsでは、OSがアドレスを解決するためには、おそらくのようなものによって定義され、この Linux上で解決の優先順位がで定義されている間、/etc/nsswitch.conf

  2. DNSサーバーに、応答をUDPプロトコルを使用して、クライアントが存在する場合、記録/ IPアドレスで

  3. クライアントは、ポート80上のTCPコネクションオープンし、Webサーバを、次のテキストを書き込みます。

    HTTPリクエスト:

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

    コンソールまたはコマンドプロンプトで次のような操作を行うことで、同じことを模倣できます。

    > 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
    

    2行の空行が続きます。要求されたコンテンツが存在する場合、Webサーバーはそれを画面に印刷します。反対側にブラウザがある場合、応答テキストはブラウザによって解析され、すべてのタグ、リンク、スクリプト、および画像がWebページと呼ばれるものにレンダリングされます。

実際には、さらに詳細があります。たとえば、すでにドメインにアクセスしている場合、ブラウザはIPアドレスをキャッシュするため、DNS解決は不要になります。また、最新のブラウザは、実際に必要になる前に解決を試み(DNSプリフェッチ)、ブラウジングを高速化する場合があります。

さらに、コンピューターのhostsファイルに静的レコードがある場合があります。レコードが要求と一致する場合、ローカルの静的エントリが最初に使用され、DNSサーバーは一切接続されません。これは構成可能であり、必ずしも真実ではありませんが、私が使い慣れているオペレーティングシステムのデフォルトです。


4
@trikly:それが 'Host'ヘッダーの目的です。これがないと、IPアドレスごとに1つのWebサイトしか持てません。これは、HTTP / 1.0とHTTP / 1.1の重要な違いです。ありがたいことにHTTP / 1.0ブラウザーは今ではまれです-ただし、それらに対応したい場合は、各サイトに異なるIPアドレスが必要です(それらは同じサーバーでホストできます)。
AE 14年

1
@AEありがとう。私は自分の質問が不明瞭だったと思うので、フルボイエは私が言っていることを理解できなかったのです。(URLではなくドメインと言ったほうがいい)。まだ理解できてうれしいです。
trlkly 14年

1
あなたは「言うこれが正しいHTTPリクエストではありません」、そしてそれはほとんど本当だが、それは近いです、あなたが意味するものではありより:「HTTPの将来のバージョンですべての要求でabsoluteURIsへの移行を可能にするため、すべてのHTTP / 1.1サーバは、中absoluteURIでフォームを受け入れなければなりませんリクエスト」。(RFC 2616§5.1.2)そのGET http://www.pippo.it/hello.htm HTTP/1.1ため、異常な場合でも有効な要求になります。また、HTTPプロキシに対する有効で通常の要求にもなります。
wfaulk 14年

1
gethostbyname()やや時代遅れです。一つは、より良い使用することになりgetaddrinfo()...
glglgl

1
@Utku残念ながら、SSHは相手がSSHプロトコルを話すと仮定しているのに対し、telnetはプレーンテキストプロトコルであり、SSL / TLSを使用しない限り、POP3、IMAPなどの他のプレーンプロトコルと通信できます。 sslwrapなどのヘルパーでtelnetセッションをラップする必要があります。
フルボイェショポルヤル

12

HTTPは、IPプロトコルであるTCPを介して転送されます。HTTPリクエストを行うには、ブラウザはTCP接続を開く必要があり、そのためには、宛先IPアドレス(つまり、サーバーのIPアドレス)が必要です。したがって、サーバーのホスト名を解決するには、DNS要求を発行する必要があります(一般に、プログラムが名前解決関数を呼び出すと、DNS要求自体がオペレーティングシステムによって送信されますが、プログラムがDNS要求をDNSに送信することを妨げるものは何もありませんサーバ)。接続が確立されると、要求されたリソースへのパスを含むHTTP要求と、サーバーのホスト名を含むHostフィールド(などHost: www.pippo.it)を送信できます。ホスト名はリクエスト行にありませ(実際にはGET /hello.htm HTTP/1.1)、リクエストがHTTPプロキシに送信される場合を除きます(この場合、プロトコル部分を含む完全なURLが存在します(例:)GET http://www.pippo.it/hello.htm HTTP/1.1)。


おかげで、今では明確になっていますが、完全ではありません。ブラウザはDNSリクエストを発行する必要があると書いています。わかりましたが、DNSサーバーからIPを受信した後、どのように使用しますか?つまり、そのようなIPはHTTPリクエストには表示されません。したがって、HTTPリクエストを発行する前にもう1つのステップがあり、それが接続の開始だと思います。この点は私にはあまり明確ではありません...もう一度ありがとう!
ジャンカルロペルロ14

5
実際、TCP接続を開くにはIPが必要であり、その内部でHTTP要求が転送されます。実際には、クライアントとサーバーの両方のIPアドレスが、接続のすべてのパケットとともに送信されます。これがどのように機能するかを学ぶ最良の方法は、おそらくパケットキャプチャツールをインストールし(Wiresharkは優れたマルチプラットフォームおよびオープンソースのツールです)、単純なHTTPリクエストをキャプチャし、ネットワークアクティビティの残りからフィルタリングして、すべてのパケットが有線で送信されました。実際には、TCP接続の前にDNS要求を確認できるはずです。
エール

1
プロキシされたリクエストは、GET行に完全なURLを入れずに、Hostヘッダーを使用する必要があります。
停止ハーミングモニカ

1
@OrangeDog:いいえ、反対に。RFC 7230(セクション5.3.2)は、プロキシにリクエストを行うクライアントはリクエスト行で絶対URIを使用しなければならないと明示的に述べています。(要求行からの情報を複製するHostヘッダーがまだある必要があります;セクション5.4)。
ヘニングマクホルム14年

7

手順は次のようになります。

  1. ユーザー(あなた)はブラウザに次のようなURLを与えます http://www.pippo.it/hello.htm
  2. ブラウザはそれを3つの部分に分割します。

    • プロトコル http
    • ホスト名 www.pippo.it
    • URLパス /hello.htm

    (より複雑なURLには他の部分も含まれる可能性がありますが、今のところその可能性は無視します)

  3. ブラウザは、IP接続を作成するためにIPアドレスが必要であることを知っています。IPアドレスを取得するには、DNSを使用する必要があります(アドレスがキャッシュされていない場合)。

    1. ブラウザは、DNSサーバーのIPアドレスをオペレーティングシステムに要求します。それが取得すると仮定します8.8.8.8
    2. ブラウザは、次の多層接続を構築します。

      • IPレイヤー:接続先 8.8.8.8
      • UDPレイヤー:宛先ポート53のパケットを設定します
      • DNSレイヤー:Aホスト名のレコードのDNS要求を作成しますwww.pippo.it

      もちろん、関連するパケットの正確な形式など、多くの詳細を省略しています。

    3. ブラウザがためにIPアドレスを提供します(IPなどの上に重ねUDPの上に階層化)DNS応答を受信しwww.pippo.it、聞かせてのは、それはだと言います10.11.12.13
  4. ブラウザは、TCP接続を作成するためにポート番号が必要であることを知っています。ポート番号を取得するにhttpは、内部テーブルでプロトコルを検索し、ポート80を使用する必要があることを学習します。
  5. ブラウザは、次の多層接続を構築します。

    • IPレイヤー:接続先 10.11.12.13
    • TCPレイヤー:パケットを宛先ポート80に設定します
    • HTTPレイヤー:/hello.htmホスト上のURLに対するHTTPリクエストを作成しますwww.pippo.it(コンピューターは10.11.12.13複数のドメインをホストしている可能性があるため、どのドメインが望ましいかを知る必要があるため)

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

    もちろん、TCPハンドシェイクなどの詳細はすべて省略しています。

  6. ブラウザは、HTTP hello.htm

また、適切な手段として、ブラウザーがその応答のコンテンツを検査し、必要な追加リソース(画像、CSS、Javascriptなど)を識別するようになったことに言及します。その後、このようなリソースごとにこのプロセス全体を繰り返します。


4
ステップ3は、アプリケーション自体が実行するものではありません。アプリケーションは、getaddrinfoまたはのようなものを使用してgethostbyname、OSにアドレスの解決を依頼します。また、OSは通常、DNSだけでなく、複数のメカニズムを使用して名前を検索しようとします。(通常、少なくともDNSに加えてhostsファイル。)
HåkanLindqvist 14

ありがとう!それは本当に印象的で詳細な答えであり、非常に便利です!
ジャンカルロペルロ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.