HTTPプロトコルを理解しよう
今回は意外と知識の浅さを感じたhttpについて、基本的なとこから勉強してみました。
http(Hypertext Transfer Protocol)とは
http(Hypertext Transfer Protocol)はインターネット上のクライアントが、サーバの提供するリソースへアクセスするためのプロトコルです。
普段使用しているgoogle chromeやMicrosoft Edgeのようなwebブラウザは、このhttpの仕組みを利用して動作しています。
httpとOSI参照モデル
httpはOSI参照モデルでいうところの最上位層である7層、アプリケーション層に位置します。
また、TCPによって確立されたコネクション内でのhttp使用が定められています。
(ただし、HTTP/3ではQUICと呼ばれる新しいトランスポート層のプロトコルを使用。)
ハイパーテキスト(hypertext)とは
http(Hypertext Transfer Protocol)は直訳でハイパーテキスト転送プロトコルとなるわけですが、そもそもハイパーテキストとは何でしょうか?
別になんかすごい文書という意味ではなく、任意の単語やフレーズから任意の文書(テキスト)をリンクさせる(紐づける)仕組みを指しています。
Hyperは、単純なテキストデータではなく、より高度な機能を持ったテキストという意味合いらしいです。
同様に、メディアをリンクさせる仕組みのことをHyperMediaと呼んだりします。
httpのversionとRFC対応
現在までにおけるhttpの各versionと、関連するRFCを整理してみました。
HTTP/1.1以降RFCの改定などがいろいろありややこしいのですが、以下で分かりやすく整理してくれています。
http通信フォーマット
以降はHTTP/1.1における基本的なhttpの通信フォーマットを確認していきます。
まず前提としてhttpはASCIIで表現される文字列を扱います。
wiresharkで確認すると、TCPのペイロード部分がASCIIの文字列で表現されていることが分かります。
httpでは、クライアントからサーバへの要求をリクエストと呼び、サーバからクライアントへの応答をレスポンスと呼びます。
リクエストもレスポンスも以下のようなフォーマットで通信を行います。
Start Line、HTTP headers、Empty Line、Bodyの4階層となっており、内容によってはbodyは省略されます。
Start Line
Start Lineはリクエストとレスポンスによってフォーマットが異なります。
リクエストのStart LineはRequest Lineとも言われ、HTTPメソッド、リクエスト対象、HTTPバージョンの3っつの要素が含まれます。
一方でレスポンスのStart LineはStatus Lineとも言われ、HTTPバージョン、ステータスコード、ステータス文字列の三つの要素が含まれます。
以下は各要素の概要です。
要素 | 契機 | 概要 |
---|---|---|
HTTPメソッド | リクエスト | リクエスト内容を表わす動詞。 |
リクエスト対象 | リクエスト | リクエストを適用するターゲットリソースを識別するための情報。 基本的にはURIが指定される。 |
HTTPバージョン | リクエスト / レスポンス | HTTPのバージョン番号。 |
ステータスコード | レスポンス | クライアントからの要求に対する、サーバーの受付結果を示す3桁の整数コード。 |
ステータス文字列 | レスポンス | ステータスコードを補足する文字列。 |
以下はHTTPメソッドの一覧です。
詳細についてはRFC9110等を確認して見てください。
HTTPメソッド | 意味 |
---|---|
GET | 指定したリソースの提供を要求する。 |
HEAD | GETと同じだが、Bodyは不要。 ページの有無だけを確認したい時などに使用。 |
POST | 指定したリソースの更新を要求する。 (リソースの新規作成、バッチ処理開始、データの削除など) |
PUT | 指定したリソースの更新を要求する。 (既存リソースの置き換え) |
DELETE | 指定したリソースの削除を要求する。 |
CONNECT | 指定したリソースを用いて双方向の通信を開始する。 |
OPTIONS | サーバが対応しているオプションの確認。 |
TRACE | クライアントがリクエストした内容に幾つかの情報を付加しそのままクライアントへ送り返す。 通信確認などの試験用のメソッド。 |
以下はステータスコードの概要です。
値の例についてはほかにも様々なステータスコードがあるため、気になる方はRFC9110等を確認して見てください。
値 | 意味 | 値の例 |
---|---|---|
1XX | 要求に対する進捗やステータスなどの暫定的な応答。 | 100:リクエストを受信中 101:プロトコルバージョンの切り替えを受け入れる |
2XX | 要求に対する正常応答。 | 200:リクエストの成功 201:リクエストにより新たなリソースが作成された 202:リクエストを受け付けたが処理は継続中 |
3XX | 要求に対し、クライアントへ要求を満たすためのアクションを依頼する。 | 300:リクエストに対して複数のレスポンスがある 301:リクエストのURL が変更された 302:リクエストのURL が一時的にに変更された |
4XX | 要求に対し、サーバーがクライアントの異常を通知する。 | 400:リクエストの構文不正 401:リクエストを受け入れるには認証が必要 404:リクエストされたリソースが見つからない |
5XX | 要求に対し、サーバー自身の異常を通知する。 | 500:サーバー側で予期せぬ異常が発生している 501:リクエスト内容にサーバーが対応していない 503:リクエストを処理することが出来ない (メンテナンス中や過負荷など) |
HTTP headers
HTTP headersはRFC5322を踏襲とされており、以下はその内容の抜粋です。
- ヘッダーフィールドは値ごとの行に分割される。
- ヘッダーフィールドの各行は、「フィールド名:フィールド本文」の後にCRLFで終わる構成となる。
- 各行はCRLFを除いて998文字以下である必要があり、78文字以下であることが推奨されている。
たくさんある各フィールドの詳細については、以下などを参考にしてください。
Body
HTTP通信におけるメッセージの本文を指します。
HTTP headersの内容に応じて、エンコードなどが行われたデータが送信されます。
普段のブラウザ利用においては、HTMLのデータを本Bodyから取得することによって画面の更新などが行われます。
最後に
大まかな仕組みが分かったとこで、次回はpythonを使用しPC内でhttpサーバとhttpクライアントを立てて通信なんかしてみようと思います。
ゆくゆくはTLSもやりたい。