はじめに
この記事では、ブラウザとWebサーバーがどんなやり取りをしているのかを見ていこうと思います。
やり取りに関して大きく2つを取り上げようと思います。
- HTTPリクエスト・メッセージの作成
- DNSサーバーへの問い合わせと動作
1. HTTPリクエスト・メッセージの作成
ブラウザの最初の仕事はURLの解読
ブラウザは、Webサーバーに送るメッセージを作成するために、入力されたURLの解読から始まります。URLを分解し、要素を調べることで、URLの意味がわかるのです。
プロトコル + // + Webサーバー名 + / + ファイルパス
具体的なURLの例に置き換えると...
https: + // + qiita.com + / + trend
このURLは、「qiita.com」というWebサーバーの、「/trend」という名のファイルパスにアクセスするという意味を持ちます。
HTTPの基本的な考え方
URLを解読すれば、どこにアクセスすべきかがわかりました。その次に、ブラウザはHTTPプロトコルを使ってWebサービスにアクセスしますが...
HTTPプロトコルとは?
クライアントとサーバーがやり取りする際のルールみたいなものです。
まず、クライアントからサーバーに向けて2つの要素(「何を」「どうして」)をメッセージに組み込みます。
- URI(「何を」):ファイル名(だけではない)
- メソッド(「どうして」):GET / POST / PUT / DELETEなど
リクエストメッセージがWebサーバーに届くと、Webサーバーは中身を確認し、「何をどうして欲しいか」を判断し動作します。
動作した結果生じたデータを、レスポンス・メッセージに格納します。その先頭部分には、実行結果が正常に終了したか、異常が起こったかを表すステータスコードがあります。
404 Not Foundのような表示です。
クライアントにレスポンス・メッセージが届くと、ブラウザがメッセージからデータを取り出し画面に表示します。これでHTTPの動作は終わりです。
リクエストメッセージの作成
HTTPの基本的な考え方を確認できたので、実際のリクエスト・メッセージの作成についてみていきましょう。
リクエストメッセージにはフォーマットが決められています。
まず、1行目のリクエスト・ラインを書きます。
// リクエスト・ラインのフォーマット
<メソッド> <URI> <HTTPバージョン>
先頭部分のメソッドがポイントで、何種類もあるメソッドの中から、Webサーバーにどうして欲しいのかを伝えます。
2行目からは、メッセージ・ヘッダーと呼ばれる行が続きます。
リクエストの付加的な細かい情報を書き留めておく役割を持っています(日付、言語、圧縮形式など)。
メッセージ・ヘッダーを書いたら、その後に空白行を1行挿入し、メッセージ・ボディを書きます。メッセージの本体になる部分ですが、GETメソッドの場合は、メソッドとURIのみの情報で何をすべきか判断できるのでメッセージ・ボディに書く送信データは何もありません。POSTメソッドの場合などに、フォームに記入したデータなどが入ります。
これでリクエストメッセージの作成動作は完了です。
レスポンスが返ってくる
リクエストを送ると、レスポンスが返ってきます。
レスポンス・メッセージのフォーマットは、基本的にリクエストと同じですが、1行目が異なり、以下の内容になっています。
- ステータスコード:プログラムに実行結果を知らせるのが目的
- レスポンスフレーズ:人間に実行結果を知らせるのが目的
2. DNSサーバーへの問い合わせと動作
DNSとは、ドメイン名とIPアドレスを紐づけて管理するシステムを指す名称。
なぜDNSサーバーへ問い合わせるのか
HTTPメッセージを作成したら、次はアクセス先のWebサーバーに向けて送信しよウトします。しかし、ブラウザはURLの解読やHTTPメッセージを作成する機能は持っていますが、そのメッセージをネットワークに送り出す機能は持っていません。
なので、ブラウザはOSに依頼してアクセス先のWebサーバーに送信してもらいます。
そして、OSに依頼する時は、送信先をドメイン名ではなくIPアドレスで指定しないといけないのです。これが、DNSサーバーへと問い合わせる理由です。
なぜIPアドレスとドメイン名を分けるのか
OSに依頼する際はIPアドレスを指定しないといけないことがわかりました。それなら、URLにもドメイン名ではなく、IPアドレスを記述すればいいのいではないかと思いますよね。
実際、URLにIPアドレスを直接記述しても正しく動きます。しかし、数字を羅列したIPアドレスは覚えるのが大変なので、ドメイン名が書かれています。
では、IPアドレスをやめてドメイン名で相手を指定して通信できるようにすればいいのではないかと思いますよね。
ですが、これは実行効率という観点から見てベストとは言えないのです。IPアドレスが4バイトなのに対して、ドメイン名は数十~255バイトもあります。ルーターの負荷が増えると、結果的にネットワークの速度が遅くなってしまいます。
そこで、人間はドメイン名を使い、ルーターはIPアドレスを使うという方法が考案され定着しています。
DNSサーバーの基本動作
DNSサーバーの基本動作は、クライアントからメッセージを受け取り、回答をすることです。クライアントからのメッセージには、サーバやメール配送先の名前・クラス・タイプの3つの情報が含まれます。
例えば、qiita.comという名前のサーバーのIPアドレスを調べるとき、クライアントがDNSサーバーへ送るメッセージは以下のようになります。
- 名前:
qiita.com - タイプ:IN
- クラス:A
DNSサーバーは、送られたメッセージをもとに、登録されている情報を探します。もし、3つの項目全てがメッセージと一致するIPアドレスがあれば、それをクライアントに返します。
DNSサーバーは、サーバー内に登録されたドメイン名をIPアドレスの対応表を調べてIPアドレスを回答する。
IPアドレスの探し方
最寄りのDNSサーバーに問い合わせることで、IPアドレスを探すことができます。
DNSサーバーに対してクライアントとして動作する場合、Socketライブラリの1つであるリゾルバを利用してDNSサーバーに対して問い合わせをします。
そして、応答メッセージの中にIPアドレスが格納されているので、リゾルバがそれを取り出して、ブラウザから指定されらメモリー領域の中に書き込みます。
Socketライブラリはネットワークの機能を呼び出すためのプログラム部品集
リゾルバ内部では、以下のような動きをしています。
- DNSの仕様に従ったリクエストメッセージをDNSサーバーに送信
- リゾルバ自信が実行するのではなく、OS内部に組み込まれたプロトコル・スタックに実行を依頼
- 返ってきた回答をリゾルバが解読し、IPアドレスを取り出す
- 取り出したIPアドレスをアプリケーションに渡す
終わりに
今回はブラウザとWebサーバーの基本的なやり取りについてまとめてみました。このやり取りの中にも、さらに深掘れる部分はたくさんあります。
IPアドレスの基本的な部分やドメインの階層、プロトコル・スタック内部の動きにも触れつつ、更に先の流れについても理解を深めていければと思います。