概要
HTTPヘッダ項目の Accept-Encoding は、HTTP圧縮通信を行う際に利用できるエンコードを教え合うために利用します。 (詳細は別稿にて解説しています) この Accept-Encoding を指定しない場合と指定した場合とで、動きがどのように変わるかを Telnet を利用して観察してみましょう。
準備
まずはHTTP圧縮通信に対応したWEBサイトを見つけるか、ご自身でHTTP圧縮通信するように設定したWEBサーバーを立ち上げてください。 例えば2018年1月現在、ITmediaさんなどが対応していました。 ただし余計な負荷をかけてしまうのは申し訳ないので、別稿「Apache httpd の mod_deflate でHTTP圧縮通信をサポートしよう」の設定を行って自身でサーバーを構築しました。
また macOS High Sierra に Telnet がインストールされていないため、別稿「macOSからTelnetでHTTP通信する方法」の手順で macOS に Telnet をインストールしました。
Accept-Encoding ヘッダなしの通信を確認する
まずはHTTP圧縮なしの平文通信を確認します。 Telnet コマンドを利用して、次のようにHTTPリクエストを入力します。 GETコマンドとHostヘッダを指定したシンプルなものです。 結果として、次のように平文でHTMLが返却されることを確認します。
$ telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /sample.html HTTP/1.0
Host: localhost
HTTP/1.1 200 OK
Date: Sat, 27 Jan 2018 10:06:15 GMT
Server: Apache/2.4.29 (Unix) PHP/7.2.1
Last-Modified: Sat, 27 Jan 2018 10:05:41 GMT
ETag: "1323-563bf27c9e740"
Accept-Ranges: bytes
Content-Length: 4899
Vary: Accept-Encoding
Connection: close
Content-Type: text/html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
(略)
</body></html>
Connection closed by foreign host.
ここで注目しておくべきは、 Content-Length ヘッダで返却されているHTMLのサイズと、返却されているHTMLが平文である(暗号されていない)ことです。
Accept-Encoding ヘッダありの通信を確認する
さて本題です。 続いて Accept-Encoding ヘッダを付けてHTTPリクエストを送信してみましょう。
$ telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /sample.html HTTP/1.0
Host: localhost
Accept-Encoding: gzip,deflate
HTTP/1.1 200 OK
Date: Sat, 27 Jan 2018 10:06:48 GMT
Server: Apache/2.4.29 (Unix) PHP/7.2.1
Last-Modified: Sat, 27 Jan 2018 10:05:41 GMT
ETag: "1323-563bf27c9e740-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 2002
Connection: close
Content-Type: text/html
?Xo?F???
G?]?p???(???"W??$?????+????.I??R??????7o?,3??x{w?????l?????}xÂa??㷋?쟷??`?h???? ??????n?&???x?1~???mh?G?M????[?t>??rF
(略)
V????K-&?I?P?BEߝ?j~??ďT9??`????\/:~ųщp7??????;?74??ˏ??>?G?gJ?
Accept-Encoding ヘッダを付与したことにより、HTTPレスポンスに次のような変化がありました。
- Content-Encoding ヘッダが付与された。
- Content-Length のサイズが小さくなった。
- 返却されたHTMLは圧縮されているため平文ではなくなった。
Content-Encoding ヘッダにより「gzip」で圧縮されていることが伝えられていますので、HTTPレスポンスを受けたブラウザは gzip 形式の解凍をすることで、平文のHTMLを取得できるというわけです。
本稿の執筆中に気づいたこと
Accept-Encoding をつけてHTTPリクエストを送信しても、リクエストしたコンテンツのサイズが小さい場合には、圧縮をせず平文でサーバーが応答する場合がありました。 圧縮してもあまりコンテンツサイズに変化がないとサーバーが判断したからだと考えられます。
また、HTTPレスポンスヘッダで Content-Length を返却してくれない場合もありました。 PHPのアプリケーションをリクエストした際にそのようなことがありました。 サーバーやアプリケーションによって、そのようなことがありそうです。
おわりに
本稿では Telnet を利用して HTTPヘッダ Accept-Encoding の動きを観察してみました。 HTTPの理解のお役に立てれば幸いです。