くま's Tech系Blog

基本的には技術で学んだことを書き留めようと思います。雑談もやるかもね!

Webサイトが表示されるまで

今回はWebサイトが表示されるまでに行われることやネットワークの基礎中の基礎をまとめたいと思います

URLについて

皆さんは、URLを入力してWebサイトに接続すると思います

URLにはアクセスしたいファイルやドメインの情報が含まれていてブラウザはURLを解析して目的のファイルを取得します

例えば、このブログのURLであるhttps://kumaskun.hatenablog.com/entry/2023/01/08/123900を例にみていきましょう!

プロトコル・スキーム

まずはhttps://の部分です。

httpsの部分はプロトコルと呼ばれています。 URLは通信をするときに使うので、「通信プロトコル」とも呼びます

プロトコルはインターネット上で通信をするとき、このルールに従いましょうという取り決めのことを指します。 中でも、通信プロトコルには、次のように目的に応じて様々な種類があります

  • http→ WebサーバーとWebブラウザ間でデータを送受信する
  • https→ httpにデータ暗号化機能を付与したもの
  • mailto→ メール送信先を指定する
  • ftp→ ファイルをダウンロードする

よく使うのはhttphttpsだと思います

httpとは、Hyper Text Transfer Protocolの略で、WebサーバーとWebブラウザがデータを送受信するときに使う通信上のルールのことです。 例えば、Google ChromeWebブラウザからhttpという通信プロトコルを使ってWebサーバーに要求を出すことで、そのページを表示させて利用できるようになります。

httpsHyper Text Transfer Protocol Secureの略で、httpにデータを暗号化する機能がついたものです。 Secure Socket Layer、transport layer securityはそれぞれSSLTLSと省略し、どちらもデータを暗号化して送受信する技術のことを指します。 SSLTLSの技術でデータを暗号化することにより、個人情報などの漏洩を防ぎます。 現在のURLの形式はhttpsがほとんど占めると思います

https://はまとめてスキームと呼ばれています。 前述したプロトコルというルールを規定するものだと理解しましょう。 上図の場合では、このURLはhttpsのルールを使って通信することを表しています

ドメイン

次はドメインについてです。ドメインkumaskun.hatenablog.comの部分です

ドメインは、ホスト名と同じく、IPアドレスを分かりやすくするために設定する文字列のことを指します。 インターネット上の住所となるので、同じドメインは1つしか存在しません。Webサイトを作成する際にはまず、ドメインの取得から行うことが多いと思います

ドメインには、更に細かくトップレベルドメインセカンドレベルドメインサードレベルドメインの3つに分けられます。

トップレベルドメインは、ドメインの一番最後にあるjpcomnetなどです。 特定の領域や分野ごとに割り当てられた分野別トップレベルドメイン(gTLD)と、国別のコードに割り当てられたトップレベルドメインccTLD)に大別されます。 例えば、日本のccTLDは上図の「jp」です。

セカンドレベルドメインは、ドメインの中で2番目に属しているドメインです。(今回はhatenablogの部分) この階層はあくまで順番を表しているため、トップレベルドメインの種類によって、どのようなドメインがセカンドレベルドメインになるかは変わります。

トップレベルドメインがjpの場合は、co(組織)or(非営利法人)など、組織の種類を表すドメインが入ります。

一方、トップレベルドメインが下図のようにcomやnetなどの場合は、サードレベルドメインがセカンドレベルドメインの位置に入るため、サードレベルドメインがないURLもあります

サードレベルドメインは、セカンドレベルドメイン以下に属しているドメインです。 上図の場合、このサードレベルドメインのkumaskunは、重複がない限り登録者が自由に設定できます

IPアドレスとは?

補足情報としてIPアドレスについて軽く触れておこうと思います

IPアドレスは、スマホやPCなど、ネットワーク上の機器に割り当てられるインターネット上の住所のようなものです。 インターネットでページを閲覧したり、メールの送受信を行うには、データの送信元や送信先を識別する必要があります。 そこで、この識別に使うための番号がIPアドレスです。 ネットワーク上でデータを送受信する際、通信相手を指定するために使われています

IPアドレスネットワーク番号ホスト番号から構成されています。 どのサブネット(ハブにコンピューターを接続したもの)に属しているかを示す番号をネットワーク番号、 サブネット内のどのコンピューターからを表す番号をホスト番号と呼びます

IPアドレス32bitのデータで8bitずつドットで区切り10進数で表記します。 例えば、100.12.11.100のようなイメージです

しかし、100.12.11.100だけだとどこまでがネットワーク番号でどこまでがホスト番号がわかりません。 そこで、100.12.11.100/16と書くことで最初の16bitがネットワーク番号になり、残りの16bitがホスト番号とわかるようになります

ホスト名

今回の例のURLにはないのですが、URLにはホスト名というものが存在します

例えば、wwwなどの文字を1度は見たことがあるのではないでしょうか?

ホスト名は、ネットワークに接続されたホスト(機器やサーバー)の名前を指します。 通信する際に、特定のホストを識別するために使います

ホスト名は、後述するドメインとほとんど同じ意味だと捉えて構いません。 人間が管理しやすいように、前述したIPアドレスを文字に置き換えているの文字列が「ホスト名」と「ドメイン」です。

ホスト名もドメインも、どちらも登録者の任意で自由に決めることができます。 ホスト名は、代表的な「www」にするか、自由に設定するか、必要がなければ省略することもできます

ディレクト

ディレクトリは、サーバー内のフォルダ名と位置を表しています。 ホームページの場合、複数のコンテンツを持っていることがほとんどです。 そのコンテンツを分類し、このURLがホームページ内のどの階層にあるページなのかを示しています。

ディレクトリが何層もある場合は、URLの中では一番左の、一番大きなディレクトリより後のものをサブディレクトリといい、「/」で区切ります。 今回の例の場合には2023ディレクトリにあたり、/01/08/はサブディレクトリに相当します

ファイル名

ファイル名は、URLの末尾に配置される一番小さなファイルを表します。 そのURLの中では一番最後の部分です。今回は123900の部分です。 今回の例では、ディレクトリの中の123900に分類されたファイルを開くようなURL構成になっています

リクエストメッセージ

ここまでで、HTTPプロトコルHTTPSプロトコルを使ってどのドメインやどのファイルにリクエストするかがURLを見ればわかるようになったと思います

次にブラウザはサーバーに対してデータをリクエストする旨を伝えるリクエストメッセージを作成します。 リクエストメッセージはHTTPプロトコルに準拠している必要があります

ここからはリクエストメッセージの構成に関して説明します。まずは下記にリクエストとレスポンスのイメージ画像を載せます

MDN Web Docsから抜粋

メソッド

メソッドはWebサーバーにどのような処理をして欲しいのかを記述します。今回の例ではPOSTが該当します。 他にはGETPUTなどがあります。 例えばGETはリソースを取り込むこと、POSTはデータをサーバーへ送信すること (リソースを作成または変更する、あるいは返送する一時的なドキュメントを生成する) ことを示します

HTTPバージョン

どのバージョンのHTTPプロトコルに準拠しているかを定義しています。今回の場合にはHTTP/1.1でバージョン指定を行っています

メッセージヘッダー

メッセージヘッダーはリクエストに対して付加情報を記述したい場合には追加します。上記の図ではHTTP Headersと命名されている箇所です

使用できるリクエストヘッダーは多数あり、いくつかのグループに分類されます

  • 一般ヘッダーは: Via など、メッセージ全体に適用される
  • リクエストヘッダー:User-Agent, Accept-Typeなど指定するとリクエストを変更するもの (Accept-Languageなど)、状況を示すもの (Refererなど)
  • エンティティヘッダー:Content-Lengthなど、リクエストの本文に適用されます。リクエスト内に本文がない場合はこれらのヘッダーが送信されません

メッセージボディー

リクエストの最後の部分が本文です。 本文が存在しないリクエストもあります。 リソースを取り込むリクエストであるGET, HEAD, DELETE, OPTIONSは通常、本文は不要です。 サーバー内のデータを更新するためにデータを送信するリクエストもあり、 POST リクエストでよくあります (HTML フォームのデータを持つ)

本文は、大きく 2 種類に分類されます。

  • 単一リソースの本文。1 個のファイルで構成され、Content-TypeとContent-Lengthの 2 つのヘッダーで定義される
  • 複数リソースの本文。マルチパートの本文で構成され、それぞれが異なる情報を持ちます。これは主に、 HTML フォームと関連付けられる

レスポンスメッセージ

レスポンスメッセージはHTTPリクエストに対するレスポンスです。 少し細かくいうと、ホームページを見るときに使うソフト(Webブラウザ)からホームページのファイルが置いてあるコンピュータ(Webサーバ)に対して出されるリクエストに対するWebサーバさんからの返事です

レスポンスメッセージはリクエストメッセージで表示させているイメージをベースに説明します

ステータスコード

ステータスコードHTTPリクエストが正常に処理されたかを示す数字です

大まかに5種類に分けられます

レスポンスメッセージ

レスポンスの最後の部分が本文です。 本文を持たないレスポンスもあります。

本文は、大きく 3 種類に分類されます。

  • 大きさが判明している 1 個のファイルで構成される、単一リソースの本文。 Content-Type と Content-Length の 2 つのヘッダーで定義される
  • 大きさが不明な 1 個のファイルで構成される、単一リソースの本文。Transfer-Encodingをchunkedに設定して、 chunked 形式でエンコードされる
  • 複数リソースの本文。マルチパートの本文で構成され、それぞれが異なる情報のセクションを持ちます。これは比較的まれ

DNS

ここまででサーバーにリクエストを行い、レスポンスが返却されるという流れは把握したと思います

リクエスト時にデータを送信するためには宛先のIPアドレスを知る必要があります

URLから得られる情報はドメイン名(IPアドレスを人間が理解しやすくしたもの)なので、IPアドレスに変換する必要があります。そこでDNSという仕組みがあります

DNSIPアドレスドメイン名を対応づけします。 例えば、https://kumaskun.hatenablog.com/IPアドレスを問い合わせるとDNSサーバーが100.100.100.100のようにIPアドレスを教えてくれます。 DNSサーバーを使用してIPアドレスを取得するのを名前解決と呼びます

DNSサーバーとresolver

ドメイン名の情報を管理し、外部からの問い合わせに応答するコンピュータやソフトウェアのことをDNS server、サーバへの問い合わせを行いDNS情報を参照・利用する側のコンピュータやソフトウェアをDNS clientあるいはDNS resolverという。 DNS resolverはIPアドレスを問い合わせる側のことです

resolverには以下3つの情報が含まれています。これらの情報をリソースレコードとも呼びます

  1. 名前:サーバーやメールの@以降の情報
  2. クラス:DNSがどのような目的で使用されているかがわかる
  3. タイプ:AタイプとMXタイプがある。Aタイプは名前とIPアドレスが対応づけされている場合でMXタイプは名前とメールサーバーが対応づけされている場合

DNSサーバーは複数存在しています。インターネット上には数枚台というDNSサーバーがありそれぞれ自分が担当するドメインを持っています

実際に問い合わせを行う場合には、ツリー構造でつながれているネットワーク上に配置されたほかのDNSサーバーに対して、問い合わせを受けたDNSサーバーが問い合わせをします。 この問い合わせをするプログラムのことをフルサービスリゾルバといいます。

フルサービスリゾルバは該当のデータが見つかるまでほかの権威DNSサーバーへ問い合わせを繰り返し、引き当たったIPアドレスをスタブリゾルバに返します。 それをスタブリゾルバが端末に返すことで、リクエストを送信した端末がアクセス先のIPアドレスが何であるかを把握し、Webページにアクセスできるという仕組みです。 イメージは下記です

フルサービスリゾルバのイメージ

サーバーからデータを受け取る

ここまでリクエストを送信することに特化して解説していました。 ここではリクエストを受け取った後のことを説明しようと思います

Webサイトが表示するためにはレスポンスを返却する必要があります

ブラウザにはメッセージを送信する機能がないため、OSに送信を依頼します。 OSがメッセージを送信するための通信プロトコル郡をプロトコルスタックと呼びます。 データの送信をしたいときは上のレイヤから下のレイヤへ送信を依頼することで、データ送信をしています

プロトコルスタックの一例(参照のリンク先のもの表示)

HTTPリクエストを送信したい場合は、Socketライブラリを使用してデータを送信します。 データ通信時には受信側/送信側の両方でソケットというデータの出入り口を作成して、それらを接続することで通信を行います。 クライアントがデータを受信するまでの流れは次の4ステップで行われます

  1. アプリケーションは直接ソケットを触ることができないため、Socketライブラリを通してソケットの作成を行います。 ソケットはSocket関数にサーバのIPアドレスを渡すことで作成でき、ソケットの作成が完了するとソケットの識別子であるディスクリプタが返ってきます。 1つのソケットにつき1つのサーバとしか通信が行えないです

  2. サーバのソケットに接続する。 クライアントはソケットを作成した後、サーバ側のソケットへ接続するようプロトコルスタックに依頼します。 サーバに接続する際はSocketライブラリのconnect関数にディスクリプタIPアドレス、ポート番号の3つを渡すことで接続を確立してくれます

  3. データの送受信 接続確立後はソケットにデータを入れるだけで、相手にデータを届けることができます。 データの送受信を行うためにはSocketライブラリのread/write関数を使用します。 ブラウザとOSがデータのやりとりをするために、受信バッファ/送信バッファというものを使用します。 ブラウザは送信したいデータを送信バッファに書き込むことで、OSにデータを渡すことができます。 同様に、OSは受信したデータを受信バッファに書き込むことで、ブラウザにデータを渡すことができます

  4. 接続を切断する データの送受信が終了した場合にはSocketライブラリのclose関数を使うことで、接続を切り、ソケットを抹消することができます

データを受信したら、受け取ったレスポンスメッセージをもとに、受信した内容をブラウザに表示します。 これによりホームページを表示することができます

参照

ferret-plus.com

developer.mozilla.org

www.rworks.jp

sites.google.com