🀄

HTTPについて

に公開

HTTP

WebブラウザとWebサーバーの間で、 HTMLなどのハイパーメディア文書を転送するためのアプリケーション層のプロトコルです。HTTPではクライアントが出したリクエストをサーバーが処理をして、レスポンスを返します。このようなプロトコルをリクエスト/レスポンス型のプロトコルと呼びます。
HTTPのリクエスト/レスポンス型の原則として、サーバーで処理に時間がかかる場合でも、クライアントはサーバーからのレスポンスがあるまで基本的に待機します。(同期的に動作をします)

HTTPの特徴

HTTPはステートレス(stateless)なプロトコルです。
これは、「通信が1回ごとに独立しており、それ以前・以後の通信とは関係を持たない」という意味です。たとえば、あるWebサイトでログインしたあとに別のページへ移動したとします。このとき、サーバーが「このユーザーはログイン済みです」と認識してくれないと、毎回ログインし直す必要が出てしまいます。しかし、HTTP自体には「このリクエストは誰が送ったか」「どんな操作をしたあとか」といった情報を記憶する仕組みがありません。
このような、状態を持たない(ステートレス)という性質は、通信のしくみをシンプルに保ち、サーバーの負担を軽減するというメリットがあります。サーバー側でクライアントの状態を保持する必要がないため、リクエストのごとに独立した処理ができるような設計になっています。
しかし、ログイン状態の保持や、ショッピングカートの中身の管理などでは、ステートレスが障壁になることもあります。そこで登場するのが、HTTP Cookieやセッションといった仕組みです。これらは、ステートレスなHTTPの上に「状態を持たせる」ための補助的な手段として使われています。

Cookieとは、クライアント(Webブラウザ)側に情報を一時的に保存しておく仕組みです。
サーバーはレスポンスにCookie情報を含めることで、ユーザーの識別情報やセッション情報をブラウザに保存させます。保存されたCookieは、次回以降のリクエスト時に自動的にサーバーへ送信されるため、サーバーは このリクエストは以前も来たあのユーザーだ と認識できるようになります。
例えば、ログイン後にサーバーが次のようなレスポンスヘッダーを返したとします。

Set-Cookie: session_id=abc123; Path=/; Max-Age=3600;

この場合、ブラウザは session_id=abc123 というデータをCookieとして保持し、次回のリクエスト時に次のような形で送信します。

Cookie: session_id=abc123

サーバーはこの session_id に紐づいたユーザー情報をもとに、ログイン状態を維持したり、個人に合わせたレスポンスを返すことができます。このように、CookieはステートレスなHTTPに「状態(ステート)」を持たせるための役割を担っています。

CookieとSessionの違い

  • Cookie: クライアント側に保存される情報
  • Session: サーバー側に一時的な状態を保存しておく仕組み

以下の連携のイメージです。この流れが、Sessionです。

  1. ユーザーがログインフォームでログイン情報を送信
  2. サーバーがログイン認証を行い、セッションIDを発行
  3. そのセッションIDを Cookieに含めてクライアントに返す
  4. 次回以降のリクエストで、ブラウザはCookieに含まれたセッションIDを送信
  5. サーバーはセッションIDから、対応するユーザーの情報を参照する

HTTPとトランスポート層(TCP)の関係

HTTPはアプリケーション層のプロトコルです。実際にデータを送受信するときには、下の層にあるトランスポート層のTCP(Transmission Control Protocol)を使って通信を行っています。
HTTPは、自分自身でパケットの送受信や順序の管理ができないため、TCPを使ってリクエストレスポンスのやり取りを行います。
TCPは次のような機能を提供します

  • パケットの順序保証(順番通りに届く)
  • パケットの再送(途中で失われても再送)
  • 誤り検出と訂正
  • コネクションの確立と終了(いわゆる「3ウェイハンドシェイク」など)

このように、HTTPはTCPコネクションでデータのやり取りを行います。
以前TCP/IPに関しては、以前こちらで記事を書いたので参照してみてください。

https://zenn.dev/kishida000/articles/6b9008c8dc12a8

HTTPメソッド

HTTPメソッドは、クライアント(主にWebブラウザ)がサーバーに対してどんな操作をしたいのかを伝える命令のようなものです。HTTP1.1では、8つのメソッドしか定義されていません。

https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Methods

また、設計を実装をする際に大切になる、「安全性」と「冪等性(べきとうせい)」という概念があります。

安全性とは

「リクエストを実行しても、サーバー側の状態に変化を与えない」ことを意味します。
たとえば、GETメソッドは「ページを見る」「画像を取得する」といった読み取り操作なので、データの変更は発生せず安全なメソッドとされます。反対に、POSTはサーバーにデータを送信して保存するため、サーバー側の状態が変化する=安全ではないと判断されます。

メソッド 安全性
GET 安全
POST 安全ではない
PUT 安全ではない
DELETE 安全ではない

冪等性とは?

冪等性とは、「同じリクエストを何度繰り返しても、サーバーの結果が変わらない」という性質です。
たとえば、PUTで「ユーザー名をHogeに更新」と送った場合、1回でも10回でも結果は「Hoge」です。これは冪等な操作です。一方、POSTで「コメントを追加」すると、1回ごとに新しいコメントが追加されるため、冪等ではありません。

メソッド 冪等性
GET 冪等
POST 冪等ではない
PUT 冪等
DELETE 冪等

参考文献

https://developer.mozilla.org/ja/docs/Web/HTTP

https://gihyo.jp/book/2010/978-4-7741-4204-3

Discussion