HTTP

**HTTP**（**Hypertext Transfer Protocol**、ハイパーテキスト・トランスファー・プロトコル）は、ハイパーメディアを転送する通信プロトコルであり、主にインターネット上で利用される。World Wide Webのデータ通信の基盤を支える技術であり、インターネット・プロトコル・スイートの一つである。

## 概要
TCPやQUICはアプリケーション間のコネクション型通信を提供する。HTTPはこのコネクション上を、リソース要望と返答が、メッセージ単位で、1往復のクライアントリクエスト&サーバーレスポンスという形で通信される、と定めたステートレスのプロトコルである。

HTTPの発明により、インターネット上でのリソース公開とアクセスが容易になった。クライアントがサーバーとコネクションを確立し1つのHTTPメッセージを書いて送るだけで、サーバー上のリソースがHTTPメッセージとして帰ってくる。ゆえにHTTPで公開されるあらゆるリソースにHTTPという単一の手法でアクセスできるようになった。

HTTPを開発した理由でありかつ現在も広く利用される用途はWorld Wide Webである。WebサーバとWebブラウザはHTTPで主に通信しており、ブラウザからのHTTPメッセージに応答してサーバーがHTMLテキストやJavaScriptコードを送り返し、これをブラウザで表示することでウェブが成立している。

またHTTPはメッセージ形式を定める。基本的な考え方は単純で「何を」「どうして」欲しいのかを伝える。例えばリクエストメッセージ `GET /apple.jpg` は「apple.jpg 画像を、手に入れたい」を意味する。URLが「何を」に、メソッドが「どうして」に当たる。

World Wide WebにおけるWebページなどのリソースは、Uniform Resource Identifierによって指定される。HTTP を使用してリソースにアクセスするときは、http: が先頭についた URL を使用する。下にURL の例を挙げる。

 http://www.example.co.jp/~test/samples/index.html

最初の HTTP/0.9 ではURLを指定してコンテンツをダウンロードするのみの簡単なやりとりだったが、HTTP/1.0 で改良された。
*様々なリクエストメソッドが追加された。POSTを使って、アップロード（クライアントからサーバへのデータの転送）が可能になった。
*NNTPやSMTPのような各種ヘッダが定義され、HTTP cookieなどの利用が可能になった。
HTTP/1.1 では複数データを効率よく転送するための持続的接続や、プロキシの利用なども想定した仕様になった。さらに HTTP/2やHTTP/3が策定された。現在ではHTTPセマンティクスと各バージョンの手続きが分離して定義されている（#規格を参照）。

このほかの点を箇条書きで示す。

*TCPのポート番号80をデフォルトとして使用する（HTTP/0.9〜1.1とHTTP/2の場合）。
*TLSで暗号化され、セキュリティを確保したHTTPは、**[[HTTPS]]**と呼ばれる（httpsは実際にはURIスキームの1つであり、実際のプロトコルには**HTTP over SSL/TLS**またはHTTP/3が用いられる）。
*HTTP は基本的にサーバが状態を保持しない (stateless) プロトコルだが、データベースなどを使用するWebアプリケーションにおいては状態保持が必要だったため、いわゆる Cookie（クッキー）とよばれる機構が Netscape Communications Corporation によって導入された。Cookie を使用することによって状態を管理し、セッションを維持することが可能になる。
*行末文字はCRLFで、インターネット・プロトコル・スイートにおいてアプリケーション層に属する他の多くのプロトコルと同じである（HTTP/0.9〜1.1の場合）。

## 歴史
イギリスの物理学者ティム・バーナーズ＝リーは1990年末、ロバート・カイリューと共に初のWebブラウザとWebサーバを作成した。ブラウザには通信をするためのプロトコルが必要だったので、二人はHTTPの最初期のバージョンを設計した。

以来インターネットの大部分をHTTP通信が占めるようになり、1998年にはインターネット上の通信の75%がHTTPによるものになった。

最初期のHTTP/0.9の仕様書は紙に印刷すれば1枚で済むような非常に簡素なドキュメントだったが、2度のバージョンアップを経たHTTP/1.1の仕様書は実に176ページ近くの分量に膨れあがった。

### HTTP/0.9
1991年に最初にドキュメント化されたバージョン。メソッドは GET しかなかった。レスポンスは単純にドキュメントの内容を返してコネクションを切断するだけで、レスポンスコードの規定もない。下記は、HTTP/0.9 のリクエストの例。

 GET /index.html

### HTTP/1.0
1996年5月に  として発表された。仕様が RFC で扱われるようになった。メソッドに POST など GET 以外のものが増えた。レスポンスはヘッダーがつくようになり、ステータスコードを含めるようになった。HTTP/0.9 と区別するため、リクエストプロトコルにバージョンを含めることになった。

HTTP/1.0のリクエスト


```http
GET /index.html HTTP/1.0
```



### HTTP/1.1
1997年1月に  として初版が発表された。その後、3回改訂され、現在はセマンティクス・キャッシングを除く部分がで規定されている。

名前ベースバーチャルホストのため、Hostヘッダーフィールドの規定が追加された。

HTTP/1.1のリクエスト


```http
GET /index.html HTTP/1.1
Host: foo.example.com
```




### HTTP/2

HTTP/2の目標はHTTP/1.1のトランザクション・セマンティクスとの完全な後方互換性を維持したまま非同期な接続の多重化、ヘッダ圧縮、リクエストとレスポンスのパイプライン化を実現することである。Googleによって立ち上げられ、GoogleのブラウザーであるChromeだけではなく、他にも、Opera、Firefox、Amazon Silkなどが対応しているHTTP互換のプロトコルSPDYの人気が高まっていることに対応するために開発された。

### HTTP/3

HTTP-over-QUIC（hq）としてIETFが開発していた新たな通信プロトコルが、HTTP/3へと改名される。
IETFが策定を進めているQUICはトランスポート層におけるプロトコルの名称であり、アプリケーション層プロトコルであるHTTP-over-QUICとの区別を明確にするため、このような名称変更に至った。

HTTP/2と比べ、多重化するストリームの取り扱いが下位層のQUICへ移行したこと、を回避するためのヘッダ圧縮の変更（HTTP/3用にQPACKが開発されている）などの差異がある。

## 動作
### 通信の開始
他のプロトコル同様、クライアント側とサーバ側では役割が大きく異なる。HTTP通信を開始できるのはクライアント側のみである。

クライアント側がサーバにリクエストを送り、サーバがクライアントにレスポンスを返すのが最も典型的なHTTPのやりとりである。

### 接続
システム間でメッセージをやりとりするには接続を確立させる必要がある。HTTP/0.9～HTTP/1.1およびHTTP/2ではTCPを使用する。

HTTP/0.9ではクライアントのリクエストごとにTCP接続を確立させる必要があった。これは当時のWebサイトがシンプルなテキストベースであることが多かったためである。近年ではJavaScriptやアニメーション画像など、多数のオブジェクトが埋め込まれたWebサイトが一般的となってきており、これらのオブジェクトを取得するたびにTCP接続を確立するのはサーバやネットワークに大きな負担を強いるため、1回のTCP接続で、複数のHTTPリクエスト・レスポンスをやり取りする持続的接続がHTTP/1.0の拡張として導入された。その後、HTTP/1.1では、持続的接続がデフォルトとなった。すなわち、何も指定しなければ持続的接続となり、持続的接続を望まなければヘッダーフィールドにConnection: closeを追加する仕様となっている。

### パイプライン
クライアントは前のリクエストに対するサーバの応答を待たずに別のリクエストを発行できる。

## リクエストメソッド
HTTPでは8つのメソッドが定義されている。ただし、実際のHTTP通信ではGETとPOSTメソッドが大部分を占める。

;GET
:指定されたURIのリソースを取り出す。HTTPの最も基本的な動作で、HTTP/0.9では唯一のメソッド。
;POST
:
:GETとは反対にクライアントがサーバにデータを送信する。Webフォームや電子掲示板への投稿などで使用される。GETの場合と同じく、サーバはクライアントにデータを返すことができる。
;PUT
:指定したURIにリソースを保存する。URIが指し示すリソースが存在しない場合は、サーバはそのURIにリソースを作成する。画像のアップロードなどが代表的。
;DELETE
:指定したURIのリソースを削除する。
;OPTIONS
:サーバを調査する。例えば、サーバがサポートしているHTTPバージョンなどを知ることができる。
;HEAD
:GETと似ているが、サーバはHTTPヘッダのみ返す。クライアントはWebページを取得せずともそのWebページが存在するかどうかを知ることができる。例えばWebページのリンク先が生きているか、データを全て取得することなく検証することができる。
;TRACE
:サーバまでのネットワーク経路をチェックする。サーバは受け取ったメッセージのそれ自体をレスポンスのデータにコピーして応答する。WindowsのTracertやUNIXのTracerouteとよく似た動作。
;CONNECT
:TCPトンネルを接続する。暗号化したメッセージをプロキシサーバを経由して転送する際に用いる。当初、ネットスケープコミュニケーションズによって考案されたものがIETFドラフトTunneling TCP based protocols through Web proxy serversとして公開され、 に取り込まれた。その後、 で定義が更新されている。

HTTPの仕様以外で定義しているメソッドは、IANAのHypertext Transfer Protocol (HTTP) Method Registryで管理されている。WebDavで使用するものや、  のなどがある。

## サーバの連携
### バーチャルホスト
1つのサーバーで複数のホスト名に対するHTTPリクエストを受け付ける機能である。

インターネット人気に伴い多くの企業がWebサイトを持ち始めたが、当時はまだまだ企業が自前のWebサーバを運用するのは人員、効率の問題で難しく、ISPのサーバでホスティングをしていた。また、1社ごとに専用サーバを用意するほどのことでもないため、1台のサーバで複数のWebサイトを運用していた。

しかし、IPアドレスのみで相手を特定するHTTP/1.0はこれに対応できなかった。例えば、ある1台のサーバに foo.example.com と bar.example.com という2つの仮想Webサーバがあり、クライアントは  にアクセスしたいとする。この場合はDNSサーバに foo.example.com のIPアドレスを問い合わせ、次にそのIPアドレスを使って該当サーバにアクセスし、GET index.html を要求することになる。しかし同じサーバ上にある bar.example.comもIPアドレスは同じであり、もし両方の仮想サーバに index.html というファイルが存在すれば、クライアントがどちらにアクセスしようとしているのか、判別できない。

対策としてはそれぞれにIPアドレスを付与する方法もあるが、IPv4の資源を無駄にすることになる。この問題を解決するため、HTTP/1.1でHostヘッダーフィールドが追加され、名前ベースバーチャルホストが用いられるようになった。

名前ベースバーチャルホストのため、以下のようにHTTPリクエストでホスト名を指定する。

* HTTP/1.1: Hostヘッダーフィールドでホスト名を指定する。
* HTTP/2およびHTTP/3: :authority疑似ヘッダーフィールドでホスト名を指定する。

### リダイレクト

別のURIに対して再度のメソッド実行を要求する機能である。301 Movedや303 See Otherなどのリダイレクトを指示するステータスコードとURIを受け取り、クライアントはこのURIに再度メソッドを実行する。

### クッキー

## HTTPメッセージ
リクエストとレスポンスでやり取りされるデータは、HTTPメッセージと呼ばれる。クライアントからリクエストHTTPメッセージを送り、サーバーからレスポンスHTTPメッセージを返す。

HTTPメッセージは以下で構成される。
* コントロールデータ
* ヘッダー
* コンテント
* トレイラー

なおHTTP/1.1では、コントロールデータをリクエスト行・ステータス行として表現し、コンテントを格納する部分をメッセージボディまたは単にボディと呼ぶ。

ヘッダー・コンテント・トレイラーは空となる場合もある。

下にもっとも単純なクライアントとサーバ(www.google.co.jp:80)とのやり取りの例を挙げる。

**クライアントのリクエスト**:

```http
GET / HTTP/1.1
Host: www.google.co.jp
```


この例では、リクエスト行とヘッダーにフィールドが1項目あるのみで、ボディは空でトレーラーも無い。
リクエスト行はメソッド、リクエストターゲット、HTTPバージョンの3つの要素から構成され、それぞれスペースで区切られる。
メソッドは`GET`、リクエストターゲットは「/」、HTTPバージョンは1.1である。

`GET`はリソースを取得するためのメソッドであり、リクエストターゲットの「/」はURIのパス部分であってルートリソースを対象にしたリクエストであることを示している。

**サーバのレスポンス**:

```http
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Set-Cookie: PREF=ID=72c1ca72230dea65:LD=ja:TM=1113132863:LM=1113132863:S=nNO7MIp
W2o7Cqeu_; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.co.jp
Server: GWS/2.1
Date: Sun, 10 Apr 2005 11:34:23 GMT
Connection: Close

<html><head><meta http-equiv="content-type" content="text/html; charset=Shift_JI
 S"><title>Google</title><style>
```


先頭のステータス行はHTTPバージョン、ステータスコード、ステータスメッセージから構成される。
ステータスコードの「200」は処理の成功を表し、これを補足するメッセージが「OK」である。

2行目以降にヘッダフィールドが続く。
さらに空行を挟んで、レスポンスボディとなる。
このレスポンスにもトレーラーは無い。

## HTTPヘッダフィールド
ヘッダの各要素は
```
フィールド名: 内容
```
のペアで構成される。
ブラウザの情報を表す`User-Agent`、使用候補言語を表す`Accept-Language`、他ページへのリンクを辿った場合にそのリンク元ページのURLを表す`Referer`などが代表的なフィールドである。

なお、リクエスト時の`Host`ヘッダはHTTP/1.1では必須であるが、HTTP/1.0ではなくてもよい。
ただし、サーバがバーチャルホストを利用している場合は、`Host`ヘッダがないとリソース取得に失敗するので、たとえHTTP/1.0を使用していても`Host`ヘッダを付加しなければならない。

### HTTPヘッダフィールドの一覧

;Accept
:サーバのレスポンスに含まれるメッセージボディで受け入れることが出来るコンテンツタイプと各コンテンツタイプの相対的な優先度を指定するリクエストヘッダ。指定できるコンテンツタイプはIANAによって定義されている。

```http
Accept: text/plain; q=0.5, text/html,
	text/x-dvi; q=0.8, text/x-c
```


:上記のようにAcceptヘッダには行をわけて複数のコンテンツタイプを指定できる。上記の例はいずれの4のコンテンツタイプのいずれも受け入れ可能であることを示す。0.5や0.8といった数字は品質係数で0〜1の範囲の数値である。数値の指定がなければ1.0となる。
:*text/plain; q=0.5
:*text/html
:*text/x-dvi; q=0.8
:*text/x-c

;Accept-Charset
:レスポンスで返されるメッセージボディの文字コードを指定するリクエストヘッダ。Acceptと同じく複数指定でき品質係数も設定できる。定義済み文字セットはIANAが管理している。


```
Accept-Charset: UTF-8, *; q=0.8
```

:この例だとクライアントはUTF-8を優先的に希望しているが他の文字セットとの相対優先度0.8で受け入れている。ただしサーバからのレスポンスのHTTPヘッダそのものの文字コードは常にISO-8859-1である。

;Accept-Encoding
:クライアントが受信できるメッセージボディのエンコーディングを指定する。


```
Accept-Encoding: gzip, deflate
```

:この例ではクライアントはgzip、またはzlibフォーマットに対応している。ただし必ずしもここで指定されたエンコーディングでメッセージボディが返ってくるとは限らない。
:Accept-Encodingで指定可能なエンコーディングは、IANAがHTTP Content Coding Registryとして管理されている。

;Accept-Language
:レスポンスの言語（人間の言語）に対する優先度を指定する。言語の指定にはIETF言語タグを用いる。書き方は他のAccept-群と変わらず。


```
Accept-Language: en-gb, en; q=0.8
```

:上記の例はまずイギリス英語を要求し、利用できない場合はその他の英語を要求する。

;Accept-Ranges
:Acceptで始まる他のヘッダフィールドと違いレスポンスヘッダである。現在の仕様では2つの指定方法しかない。

;Age
:リソースの推定経過時間を表示するレスポンスヘッダ。キャッシュサーバーはAgeヘッダの値からキャッシュしたリソースが有効かどうかを判定する。

;Allow
:

;Authentication-info
:ユーザ認証のやりとりの最後で用いられる、成功したレスポンスのサーバが含めることの出来るレスポンスヘッダ。

;Authorization
:サーバに対するクライアント自身の認証を行うことが出来る。

;Cache-Control
:キャッシングの動作を指定するためのマスターヘッダ。

;Connection
:接続に対するオプションを指定する。その値には以下が使用される。
:;keep-alive
::持続的接続を行う。
:;close
::持続的接続を行わない。
:;upgrade
::他のプロトコルへのアップグレードを希望する。

;Content-Encoding
:

;Content-Language
:リソースの表現に用いられる言語の明示に使われる。言語の指定はAccept-Languageヘッダと同じ。

;Content-Length
:

;Content-Location
:

;Content-MD5
:メッセージボディが変更されず宛先に届いたことの保証に用いる。MD5によるハッシュ値をヘッダー値に記載する。ただし悪意の改ざんに対しては当然MD5も改ざんされるのであまり機能はしない。どちらかといえば偶発的な変化が生じていないことの保証をしている。で廃止された。

;Content-Range
:ダウンロードの再開に用いられる。

;Content-Type

:メッセージボディに含まれるオブジェクトタイプを示す。次の例はリソースがテキストファイル、文字セットはISO-8859-4を使用していることを示している。

```
Content-Type: text/plain; Charset=ISO-8859-4
```


;Cookie
:
:クライアントがHTTP状態管理を望む場合にサーバから受け取ったクッキーを以後のリクエストに次の例のようなヘッダを付加する。

```
Cookie: $Version="1"; NAME="VALUE";
        $Path="/shopping"; $domain="www.shop.com"+
        $Port="80"
```

:$VersionはHTTPのバージョン、NAMEはクッキーの名前である。$から始まるクッキー名は使用が禁止されている。

;Cookie2
:基本的にCookieヘッダとCookie2ヘッダは別物である。

;Date
:サーバがメッセージを生成した日時を示す。リソースの更新日時を示すLast-Modifiedヘッダとは別である。

:HTTP/1.1では次のような形式を用いる。これはの7.1.1.1. Date/Time Formatsで定義されている。HTTP/1.1の以前の版であるでは、日時の形式の定義にを参照していた（内容は同等である）。


```
Date: Sun, 06, Nov 1994 08:49:37 GMT
```


:HTTP仕様ではレスポンスに`Date`ヘッダを含めることを求めている。ただしレスポンスのステータスがサーバエラーの場合には`Date`ヘッダは返らない。

;ETag
:主にキャッシングのパフォーマンスを向上する目的で使われる。

;Expect
:サーバに対して特定の動作の期待を知らせる。用途としてはクライアントがサーバに対して*100 Continue*ステータスを返すことを期待する場合に使われる。

```
Expect: 100-continue
```

:サーバが期待に応じられない場合は*417 Expectation Failed*を返す。クライアントがいくつかのプロキシ経由で通信している場合、各プロキシサーバはExpectヘッダの一切の修正を許されない。

;Expires
:オブジェクトの有効期限を示す。このヘッダで指定された日時までキャッシュはレスポンスのコピーを保持し、リクエストに対するレスポンスとして返すことができる。サーバがオブジェクトのキャッシュを望まない場合には`Expires`ヘッダに過去の日時を設定することが多い。仕様では1年以上先の日時は設定できない。

```
Expires: Thu, 28 Aug 2010 16:00:00 GMT
```

:`Cache-Control`ヘッダの`max-age`ディレクティブは`Expires`ヘッダより優先されるため注意が必要である。

;From
:リクエストを発行したユーザを特定することが出来る。1990年代では電子メールアドレスを設定することが多かったが、迷惑メールの問題もあり現在では殆ど使われていない。

```
From: user@example.com
```


;Host
:主にレンタルサーバのサポートを目的としてHTTP/1.1で導入された。現在ではHostヘッダを利用できない場合、レンタルサーバのWebサイトとまともな通信ができないと言ってよい（詳細はHTTP#歴史を参照）。

;If-Match
:ETagが一致した場合のみ、メソッドを実行するようにサーバに要求する。例えばウィキペディアを編集する際、記事のソースを取得し、書き換える際の間に別のユーザが既に編集していないかを判断するときなどに用いられる。

#利用者：AがHTTPの記事を取得。`ETag`は1234。
#利用者：BがHTTPの記事を取得。`ETag`は1234。
#利用者：AがHTTPの`ETag`を再度取得。先ほど取得した`ETag: 1234`と現在の`ETag: 1234`が一致。
#利用者：AがHTTPの記事を編集。`ETag`は1256になる。
#利用者：BがHTTPのETagを再度取得。先ほど取得した`ETag`と現在のETagはマッチせず。
#サーバは利用者：Bの書き込みを拒否。

;If-Modified-Since
:指定日時以降にオブジェクトが変更されている場合のみ、メソッドを実行するようにサーバに要求する。通信量の削減に効果がある。

;If-None-Match
:`If-Match`の逆で、ETagが一致しない場合のみの実行を要求する。

;If-Range
:クライアントがキャッシュにオブジェクトの一部分を持っている場合にパフォーマンスを向上できる。

;If-Unmodified-Since
:`If-Modified-Since`の逆で、指定時刻以降に変更がない場合のみの実行を要求する。

;Last-Modified
:レスポンスでオブジェクトの最終更新日時を示す。リクエスト時の`If-Modified-Since`ヘッダと組み合わせることで、効率的な通信が可能になる。

;Location
:サーバがクライアントにリダイレクト先URLを知らせる際に用いられる。一般的にステータスコードが3xx代のレスポンスと共に使われるが*201 Created*のレスポンスでも使うことができる。`Content-Location`ヘッダと名前が似ているが全く関係のない別のヘッダであるため注意。

;Max-Forwards
:プロキシサーバなどを経由する際の最大ホップ数を指定する。二重ループなどでサーバから応答が得られない場合の問題解決の際、`OPTION`メソッドや`TRACE`メソッドと共に用いられる。

## HTTPステータスコード
ステータスコードはサーバからのレスポンスで、リクエストの結果を通知する。3桁の数字から成り、おおまかな分類として、1xxは「情報」、2xxは「成功」、3xxは「リダイレクト」、4xxは「クライアントエラー」、5xxは「サーバエラー」を示す。

## セキュリティ技術
いくつかの観点でセキュリティに関する追加機能が存在する。

### HTTPS

セキュアな通信路でHTTP通信を行うことを通常HTTPSと言う。

### HTTP認証

HTTPの中で認証を行う仕組みが用意されている。

#### Basic認証
HTTP/1.1で定義されている最も単純なセキュリティ技術である。「基本認証を用いるくらいならなにも使わない方がまし」と主張する人もいる。平文で認証情報を送信する仕組みであるため、TLS (HTTPS)など安全を確保した通信路での利用が望ましい。通常サーバはステータスコード401で応答する。

#### Digest認証

## 規格
HTTPはIETFを始めとした標準化団体により規格化されている。以下はその一部である。

歴史的には各バージョンが独立して規格化されてきた。しかし現行の3バージョン（v1.1, v2, v3）が共通のセマンティクスを維持していたことから、これを独立した規格とする活動が推進され現在の形になっている。

## 派生・拡張プロトコル
HTTPSのほか、以下のようなHTTPのセマンティクスを利用するプロトコル、HTTPの構文を元とするプロトコルなどが存在する。以下はその一例である。

*WebDAV: HTTP上でファイル転送を実現するプロトコル。
*WebSocket: 双方向通信プロトコル。
*Internet Printing Protocol (IPP): プリンタの制御と印刷データの伝送を行うプロトコル。
*UPnPでは、HTTPをUDP上で使用するHTTPUや、マルチキャストで使用する**HTTPMU**が規定された。
*Hyper Text Coffee Pot Control Protocol (HTCPCP): エイプリルフールのジョーク。コーヒーポットの制御機能を有するプロトコル。

なお、このようなHTTPの利用に関する文書として  Building Protocols with HTTP (BCP 56)が存在する。

## 脚注

## 関連項目

* HTTP/2
* HTTPステータスコード
* FTP
* WebDAV
* Webサーバ
* ウェブブラウザ
* アプリケーションサーバ
* Representational State Transfer (REST)
* HTTPヘッダ・インジェクション
* Hyper Text Coffee Pot Control Protocol
* バーチャルホスト

## 外部リンク
* 
*