読書要点「Webを支える技術」：第3部「HTTP」

# 第6章 HTTPの基本
### HTTPの重要性
HTTPはRFC2616で規定されている。
最新バージョンは1.1
HTTPはハイパーテキストの転送用プロトコルだが、コンピュータで扱えるデータなら何でも転送可能。
強みはプロトコルがシンプルな点。

### TCP/IPとは何か
TCP：Transmission Control Protocol
IP：Internet Protocol

インターネットは階層型プロトコルである。
層ごとの実装により、他の層の具体的な部分に縛られることのない実装が可能である。

- ネットワークインターフェース層
物理的なケーブルやネットワークアダプタに相当。

- インターネット層
ネットワークインターフェース層の上位に位置する。
パケット単位でデータのやり取りを行っており、IPが担当する。
データの送出は保証するが、相手に届くかは保証しない。

- トランスポート層
データ転送の保証が目的。
TCPが担当する。

- アプリケーション層
最上層に位置する、具体的なアプリケーション。
ソケット呼ばれるライブラリを用いて実装されるのが一般的で、ソケットは接続、送受信、切断などの基本的な機能を備える。
多くのプログラミング言語がHTTPを実装したライブラリを持つ。
アプリケーションの開発側はHTTPの細かな挙動にも配慮する必要がある。

### HTTPのバージョン

- 0.9
Webが当初使われ始めたときに用いていたプロトコル。

- 1.0
最終更新は1996年。
基本的な要素が詰め込まれていたが、競争のせいもあって相互運用性が確保されているとは言いがたかった。

- 1.1
殆どのHTTPクライアントライブラリやWebサーバがこのバージョンをサポート。
現在はこのバージョンをもとに、誤りの修正、参考文献の改定、曖昧さの排除、実装経験からのアドバイスの追加を予定したHTTP Bisという、アップデートを企画する活動がある。

### クライアントとサーバ

Webが採用するアーキテクチャスタイルにクライアント/サーバがある。
クライアントはサーバにリクエストを送り、サーバからレスポンスを受け取る。

**クライアントで行われること**

- リクエストメッセージの構築
- 送信
- 待機
- レスポンスメッセージの受信
- 解析
- クライアントの目的を達成するために必要な処理

サーバからのレスポンスによってはリクエストが複数回に渡ることもある。
最終的にクライアントで行われる処理は、ブラウザであればHTMLのレンダリングなどになる。

**サーバで行われること**

- リクエストの待機
- タイクエストメッセージの受信
- 解析
- 適切なアプリケーションプログラムへの処理の委譲
- アプリケーションプログラムから結果を取得
- レスポンスメッセージの構築
- 送信


### HTTPメッセージ
リクエストメッセージとレスポンスメッセージをまとめてHTTPメッセージという。

**HTTPメッセージの構成**

- スタートライン
- ヘッダ
- 空行
- ボディ

**リクエストメッセージ**

- リクエストライン

メソッド、リクエストURI、プロコトルバージョンからなる。
URIフラグメントはクライアント側での処理になるのでメッセージ中には含まれない。

- ヘッダ

2行目のHostヘッダは必須。

- ボディ

**レスポンスメッセージ**

- プロトコルバージョン、ステータスコード、テキストフレーズからなる。
- ヘッダ
- ボディ

### HTTPのステートレス性
ステートフルなやり取りは、サーバ側が情報を維持しているため、簡潔になる。
ステートレスなやり取りは、サーバ側が情報を維持しないため、冗長になる。

**ステートフル**

- メリット

サーバ側が情報を維持するためクライアント側の欲求が簡潔。

- デメリット

クライアントの数が増えすぎると、アプリケーション状態を保持する必要性から、処理が多くなってしまい運用性が担保されない。 

**ステートレス**

- メリット

サーバ側のシステムが単純になる。
クライアントの増加をサーバの増設で乗り切れる。

- デメリット

送信データ量が増え、認証などの回数が増えるため、全体から見るとパフォーマンスは低下してしまう。
アプリケーション状態を保持しないため、通信エラーが発生した際にデータのミスが発生しやすい。

# 第7章 HTTPメソッド

HTTPメソッドは8種類しかないが、HTTPを特徴づける重要な役割を持つ。
そのうち主に使われているのは5~6種類である。

**HTTPメソッドの一覧**

|**メソッド**  |**意味**  |
|:--|:--|
|GET   |リソースの取得   |
|POST   |子リソースの取得、リソースへのデータ追加、その他の処理   |
|PUT   |子リソースの更新、リソースの作成   |
|DELETE   |リソースの削除   |
|HEAD   |リソースのヘッダの取得   |
|OPTIONS   |リソースがサポートしているメソッドの取得   |
|TRACE   |自分宛てにリクエストメッセージを返す試験   |
|CONNECT   |プロキシ動作のトンネル接続への変更   |

GET、POST、PUT、DELETEはCRUDという性質（Create、Read、Update、Delete）を満たす代表的なメソッドである。
それぞれのメソッドはヘッダに条件を組み合わせることで**条件付きリクエスト**を行うことも可能。

### GET

GETでは、指定したURIのリソースの取得を行う。
最も使用頻度の高いメソッドである。

### POST

POSTでは、3種類の役割があり、GETに次いで使用頻度の高いメソッドである。
_methodパラメータやX-HTTP-Method-Overrideを用いてPUT、DELETEを代用することも可能。

- 子リソースの作成

ブログ記事の投稿などに使われる機能。
ボディにリソースの内容を含めることもできる。

- リソースへのデータ追加

既存の内容に対してはリソースに対してデータの追加を行うことが可能。

- その他の処理

リクエストボディに内容を含めることができるので、URIの実装上の問題でGETでは実現できないリクエストの実装が可能になる場合がある。

### PUT

PUTは2つの機能を持つ。

- リソースの更新

URIを指定し、ボディに更新内容を記述することでリソースの更新を行うことができる。

- リソースの作成

存在しないURIを指定した場合には、PUTはこちらの機能を利用して新しくリソースを作成する。
ボディに内容を記述することが可能。

ただ、クライアント側にサーバの内部実装の知識を要求するので、リソースの作成はPOSTで行い、URIをサーバで指定することが望ましい。

### DELETE

DELETEは指定されたURIのリソースを削除するメソッド。

### HEAD

GETと似ているが、ヘッダだけを取得するメソッドである。
このメソッドのレスポンスにはボディが含まれない。

### OPTIONS

そのリソースがサポートしているメソッドの一覧を返すためのメソッド。
多くのWebアプリケーションフレームワークでは、リソースごとに対応しているメソッドを返すように自前で実装する必要がある。

### べき等性と安全性

ある操作を何回行っても結果が同じことを示す**べき等**と、操作対象のリソースの状態を変化させないこと（リソースに副作用がないこと）を**安全**が、ステートレス性を保ちながら通信エラーに対する対応を考える際に重要である。
メソッドが持つ性質を理解しつつ、べき等性と安全性を損なわないような実装が重要である。

| メソッド | 性質 |
|:--|:--|
|GET, HEAD   | べき等かつ安全  |
|PUT, DELETE   |べき等だが安全でない   |
|POST   | べき等でも安全でもない  |

# 第8章 ステータスコード

レスポンスメッセージの中で、リクエストの結果を伝えるコード。
3桁の数字で、戦闘の数字によって5つに分類される。
ステータスコードを意識し、正しく使用されるような設計にすることが重要である。

| コード | 意味 |
|:--|:--|
|  1xx |処理中   |
|  2xx | 成功  |
|  3xx | リダイレクト  |
|  4xx | クライアントエラー  |
|  5xx |  サーバエラー |



### よく使われるステータスコード

- 200 OK：リクエスト成功
- 201 Created：リソースの作成成功
- 301 Moved Permanently：リソースの恒久的な移動
リクエストで指定したリソースが新しいURIに移動したことを示す。
別のURIにクライアントが自動的に再接続する処理を**リダイレクト**と呼ぶ。

- 303 See Other：別URIの参照
- 400 Bad Request：リクエストの間違い
リクエストの構文やパラメータが間違っていたことを示す。
ほかに適切なクライアントエラーを示すステータスコードない場合にも用いられる。

- 404 Not Found：リソースの不在
- 401 Unauthorized：アクセス権不正
- 500 Internet Server Error：サーバ内部エラー
サーバ側の異常ににより正しいレスポンスを返せないことを示す。
他に適切なサーバエラーを示すステータスコードがない場合にも用いられる。

- 503 Service Unavailable：サービス停止

# 第9章　HTTPヘッダ

HTTP1.0以降、ヘッダが実装されており、クライアントやサーバはヘッダを見てメッセージに対する挙動を決定する。
電子メールのヘッダを参考にしており、利点も多い一方で注意しなければならない制約もある。

### 日時

DateやExpireは値に日時を持っている。
HTTPではGMTで記述する。

### MIMEメディアタイプ

リソースの表現を指定するヘッダ。
Content-Typeではメディアのタイプを指定し、メディアの文字エンコーディングを指定するcharsetパラメータを付加することができる。
デフォルト文字エンコーディングはISO 8859-1である。
また、textタイプのメディアは、文書本体で文字エンコーディングが可能でもcharsetパラメータが優先される。

### 言語タグ

メディアで使われる言語を指定するタグ。

### コンテントネゴシエーション

メディアタイプ、文字エンコーディング、言語タグはサーバが一方的に決定するだけでなく、クライアントと交渉して決めることも可能。
優先度をクライアントが提示し、それに応じてサーバがサポートするものに応じてレスポンス内容を変更する。
Accept、Accept-Charset、Accept-Languageを用いる。

### Content-Lengthとチャンク転送

Content-Lengthはボディの長さを指定する。
また、Transfer-Encodingタグを使うと、長さのわからないボディを少しずつ転送できるようになる。
HTTP1.1では、すべての実装でチャンクエンコーディングを受信できなければならないと規定している。

### 認証

Basic認証とDigest認証がある。
Basic認証を使う機会が多いが、平文でパスワードを送信することになり、盗まれた際のリスクが大きい。
そこでSSL、TLSを用いたHTTPS通信で暗号化したメッセージとして送信する必要が出てくる。

### キャッシュ

サーバから取得したリソースをローカルストレージに蓄積し、再利用する方法。
キャッシュ用ヘッダを用いてキャッシュの可否を伝達する。
条件付きGETを用いれば、サーバが指定した条件を満たしていればクライアントがキャッシュできるようにすることも可能。

### 持続的接続

HTTP1.1では、動作の高速化を図るため、クライアントとサーバのやり取りをリクエストのたびに切断するのではなく、まとめて接続し続ける手法が開発された。