- Published on
HTTPについて学ぶ
- Authors
- Name
- よしかわ たいき
- @yoshikawataiki
この記事は、VOYAGE GROUP のサマーインターン、Treasure2018 の修了生による
Treasure Advent Calendar 2018 25 日目の記事です。
どうも、よしかわです。
今回は HTTP の歴史について少し触れていきたいと思います。
HTTP が出来てから 30 年近く経った現代に、どう Web を学習していくかを模索している僕のような若いエンジニアに読んでもらえるように必死に書きます。
どうぞ、最後までお付き合いいただければ光栄です。
対象読者
- HTTP の理解をしたい人
- Web サービスを開発している人
- これから Web サービスを開発していきたい人
目次
はじめに
HTTP の歴史を話していく上で、いくつか便利なツールを紹介していきましょう。
curl
という便利なツールを使うことにより、HTTP のメソッドを試すことが出来るので、この機会に導入してみましょう。
また、JSON を整形して表示したり集計したり、値を抜き取ったり出来る JSON 用の grep みたいなツールであるjq
を導入しましょう。
詳しくは、以下の URL からどうぞ。
HTTP の歴史
HTTP/0.9 HTTP/1.0、HTTP/1.1、HTTP/2 が存在します。
発表年 | バージョン |
---|---|
1991 年 | HTTP/0.9 |
1996 年 | HTTP/1.0 |
1997 年 | HTTP/1.1 |
2015 年 | HTTP/2 |
余談ですがHTTP/3 のドラフトが発表されましたので、興味のある方は見てみると良いかもしれません。
HTTP/0.9
最初のバージョンである HTTP/0.9 は、 GET メソッドしか 存在しませんでした。
HTTP ヘッダーは存在しません。
HTTP ステータスコードも存在しません。
応答は原則 HTML のみ。
とてもシンプルな設計です。
HTTP/1.0の設計を読めば、シンプルさが一目瞭然ですね。
それでは、HTTP/0.9 がどんなものか試してみましょう。
ターミナルで以下のコマンドを実行します。
livedoor にアクセスしてみましょう。
❯ echo -e "GET /\r\n" | nc livedoor.com 80
<html>
<body>
<h1>It lives!</h1>
</body>
</html>
Amazon にもアクセスしてみましょうか。
❯ echo -e "GET /\r\n" | nc amazon.com 80
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>Server</center>
</body>
</html>
HTML のみしか返ってきません。これが HTTP/0.9 です。
それでは、HTTP/1.0 では、どんな機能が追加されていくのでしょうか。
予測してみましょう。僕ならドキュメントを 1 つではなく複数個送る機能がほしいです。
あとは、ドキュメントの更新などもしたいし、クライアント側からのリクエストを明確に知りたいですね。
HTTP/1.0
上記の僕の欲しい機能が HTTP/1.0 には搭載しています。
HTTP/1.0 で、GET 以外に POST や HEAD メソッド が利用できるようになりました。
リクエスト時に HTTP バージョンが追加されました。
ヘッダーが表示されるようになりました。
例えを以下に記述しましたので、見てみましょう。
curl コマンドに、-v(もしくは --verbose)というオプションを追加して実行してみましょう。詳細な情報が表示されます。
HTTPS なら TLS handshake の様子等が出力されますが、今回は省略します。
❯ curl -v https://yoshikawa.dev
~~~~~~~~
認証まわり
~~~~~~~~
> GET / HTTP/1.1
> Host: yoshikawataiki.net
> User-Agent: curl/7.63.0
> Accept: */*
>
< HTTP/1.1 200 OK
GET メソッドで HTTP のバージョンは HTTP1.1。(今回はバージョンが 1.0 ではないの大目に見てほしい)
ヘッダーは Host、User-Agent、Accept。
レスポンスの先頭に HTTP バージョンと 3 桁のステータスコードが含まれるようになりました。
HTTP/1.1
HTTP/1.0 で目覚ましい進化をしましたが、欠点があります。それは、TCP/IP の 1 回のコネクションで 1 回のやり取りしか行なえませんでした。
HTTP/1.1 では通信の高速化を図るために追加された Keep-Alive という機能。
また、TLS による暗号化通信のサポート。
PUT や DELETE、PATCH などのメソッドの追加。
ただ、HTTP/1.1 だと 1 つのコネクションで何回もやり取りが出来るものの、その中では 1 つのリクエストが完了するまで次のリクエストが送れません。
例えば、1 枚目の画像をダウンロードし終わったら、2 枚目の画像のダウンロードが再開し、ダウンロードし終わったら、3 枚目の画像のダウンロードが始まる。100 枚あれば、どれくらい待たなければならないのか考えるだけで苦ですね。
HTTP/2
HTTP/1.1 でネックだった、バイナリデータを多重に送受信する仕組みに変更。
また、HTTP/2 では ヘッダーが圧縮される ようになりました。
僕のようなサイトでは、バイナリデータがあまりないので、HTTP/2 の恩恵を受けれないので、画像まとめサイトとかだと重要な技術になってくるわけですね。
かなり多機能になった HTTP の歴史はまだまだ続きますが、一旦メソッドの紹介をしたいと思います。
メソッド
メソッド名 | 説明 |
---|---|
GET | リソースの取得 |
POST | リソースの新規登録 |
PUT | 既存のリソースの更新 |
DELETE | リソースの削除 |
PATCH | リソースの一部変更 |
HEAD | リソースのメタ情報の取得 |
ヘッダー
curl コマンドを使ってヘッダーを送ってみましょう。
curl について学ぶにも書いてありますが、こちらにも記載します。
まず以下の URL からリポジトリをクローンしてください。
Golang で書かれているため、配置ディレクトリに気をつけてください。
https://github.com/yoshikawataiki/simple-api
git clone git@github.com:yoshikawataiki/simple-api.git
それではワークディレクトリをsimple-api
にして、以下のコマンドを実行します。
Docker が起動していることが前提ですので、ご了承を。
- make docker/start
- make api/init
- make migrate/init
- make migrate/up
- make run
では curl コマンドで POST してみましょう。
JSON を見やすくするために、| jq
をつけています。
curl -X POST -H "Content-Type:application/json" -d '{"name":"yoshikawa","email":"yoshikawa@hoge.com"}' localhost:8080/users | jq
上記の-H "Content-Type:application/json"
について説明します。
curl コマンドのオプションである-H
は--header
の省略でヘッダーを指定出来ます。
今回は、Content-Type で json を指定しています。
ボディ
ヘッダーとの間に空行を挟んで、それ以降がすべてボディになります。
❯ curl -I https://yoshikawa.dev
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Mon, 24 Dec 2018 18:19:38 GMT
Content-Length: 16247
Content-Length: 16247
が実際のボディの長さです。
ステータスコード
Treasure Advent Calendar 2018 24 日目の記事でりょーたろーが書いてくれましたので、端折ります。
Status Code を下ネタで返すサーバーを書きました。
さいごに
僕より何年も人生の先輩である HTTP についてまとめました。
ここに書いたのはあくまでも一部であって、とても奥深いです。
参考文献はとてもタメになるので、僕みたいなエンジニア志望の学生にはおすすめです!
それでは、良いクリスマスを!!
そして、VOYAGE GROUP のサマーインターン、Treasure2018 の修了生でアドベントカレンダー記事を書いたみんな、お疲れ様でした!
Treasure Advent Calendar 2018はマジで面白い記事ばかりなので、必見!
本当に最高のインターンだった(余韻)