HTTPの基本1 #1 HTTPとは
はじめてのアドベントカレンダー Advent Calendar 2018 - Adventarの12/23の記事です。 読み物でもないし完全に自分がやったことのメモでしかないんですが、初めてtelnetでHTTPメソッドを実行する、ということをやった結果ほぼ1日を費やす羽目になるくらいはまってしまい、せっかくなのでブログにしました。
しかし何も知らないとちょっと勉強しただけで色んなことが吸収できるので収穫が大きいんだけど、ハマるとハマる。ほんとにハマる。
HTTPとは
HTTPは「HyperText Transfer Protocol」の略で、Webサーバとブラウザ(=クライアント)間でウェブページを送受信するためのステートレスなプロトコル。
実際は、以下のようなテキストメッセージのやりとりで成り立っている。
・クライアントはサーバーに対し、要求メッセージを送る
・サーバーはクライアントからきた要求に対し、応答メッセージを送る
ちなみにメッセージに必要なメソッド名やステータス番号は以下のサイトが参考になった。
ステートレスとは
ステートレスは読んで字のごとく(state+less)で「状態を持たないということ」。
例えば、ブラウザがサーバに立て続けに2回リクエストを送ったとして、 サーバには1回目のリクエストと2回目のリクエストはまったく独立したものとして届き、前はどうだったかという状態は保持することができない。
HTTPがステートレスなプロトコルであるということがCookieに深く関わっているのだが、Cookieについては後ほど勉強して記載するため今はふれない。
要求メッセージ
クライアントがサーバーに対して送るメッセージ。
例えばブラウザで Webページを開きたい場合、ブラウザはサーバに以下のような要求メッセージを送信する。
例
GET / HTTP/1.1 Accept: image/gif, image/jpeg, */* Accept-Language: ja Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1;) Host: www.xxx.zzz Connection: Keep-Alive
解説
要求メッセージは以下のような構成をもつ。
【リクエストライン】
GET / HTTP/1.1
HTTPメソッド、パス名、「HTTP/バージョン」の順番に書く。「GET」メソッドを例にあげているがよく使うのは「GET」と「POST」である。2つの違いについてはここがわかりやすかった。
パス名は通常/aaa.html のようなスラッシュで始まるパス名や、http:// などで始まる URL が指定される。バージョンは現在は1.1または2.0が主流*1。
Chromeの拡張機能を使うとHTTP/2.0で通信を行っているかどうか簡単に調べられる。*2
青になったらHTTP/2.0で通信しているということ。
【リクエストヘッダー】
Host: www.xxx.zzz Accept: image/gif, image/jpeg, */* Accept-Language: ja Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1;) Connection: Keep-Alive
要求ヘッダであるHostはHTTP/1.1で唯一の必須ヘッダなのでこれは必ず書かなければならない。
あとのヘッダは必要に応じて書く。 1行1行が要求メッセージなので、この例だと6つの要求をサーバーに投げていることになる。
書き方はメソッドにより異なるが「Accept」の例だとメソッド名、ブラウザが受信可能なデータ形式(MIMEタイプ)の順番に書く。アスタリスクは「すべて」を意味するので、この場合だと「GIF や JPEG、その他どんな形式のデータでも受信可能である」という意味になる。*3
【メッセージボディ】
使用するHTTPメソッドによって使用する場合としない場合がある。
GETメソッドでは使用しないが、POSTメソッドではサーバー側に送信するデータ(クエリ)をメッセージボディに記述する。
リクエストヘッダとメッセージボディの間には1行空行が必要なので忘れないこと。 この空行がないと、リクエストヘッダとメッセージボディの境界がどこなのかが認識できず、リクエストを送信してもうまくいかない原因になる。
応答メッセージ
サーバーがクライアントに対して送るメッセージ。
例えばブラウザ側から「 Webページを開きたい」という要求(前述した例)があった場合、サーバは以下のような応答メッセージを送信する。
例
HTTP/1.1 200 OK Date: Sun, 11 Jan 2004 16:06:23 GMT Server: Apache/1.3.22 (Unix) (Red-Hat/Linux) Last-Modified: Sun, 07 Dec 2003 12:34:18 GMT ETag: "1dba6-131b-3fd31e4a" Accept-Ranges: bytes Content-Length: 4891 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html <!DOCTYPE html> <html> : </html>
解説
応答メッセージは以下のような構成をもつ。
- レスポンスライン
- レスポンスヘッダー
- メッセージボディ
【レスポンスライン】
HTTP/1.1 200 OK
HTTP/バージョン、ステータス番号、補足メッセージの順番に記述される。 補足メッセージにはOKやNot Found などステータス番号の意味や補足メッセージが返される。
【レスポンスヘッダー】
Date: Sun, 11 Jan 2004 16:06:23 GMT Server: Apache/1.3.22 (Unix) (Red-Hat/Linux) Last-Modified: Sun, 07 Dec 2003 12:34:18 GMT ETag: "1dba6-131b-3fd31e4a" Accept-Ranges: bytes Content-Length: 4891 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html
1行1行が応答メッセージなので、この場合だと9つの応答が返ってきている。
【メッセージボディ】
レスポンスヘッダとメッセージボディの間に1行空行があり、その後続けて要求されたファイルの中身が表示される。
*1:HTTPバージョンが違うとなにが違うのかはここを見るとよい。HTTP/1.0, HTTP/1.1, HTTP/2の違いとは?【ネットワーク】 | 学生エンジニアのプログラミング
*2:「HTTP/2通信されているか?」をブラウザで手軽に判別する方法
*3:じゃあ「/」だけ書けば?って思うかもしれないですが、書き方の学習のために今こうしているというだけ。