TelnetでHTTPリクエストヘッダAccept-Encodingの動きを観察しよう

投稿者 : OSCA

概要

 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レスポンスに次のような変化がありました。

  1. Content-Encoding ヘッダが付与された。
  2. Content-Length のサイズが小さくなった。
  3. 返却されたHTMLは圧縮されているため平文ではなくなった。

 Content-Encoding ヘッダにより「gzip」で圧縮されていることが伝えられていますので、HTTPレスポンスを受けたブラウザは gzip 形式の解凍をすることで、平文のHTMLを取得できるというわけです。

本稿の執筆中に気づいたこと

 Accept-Encoding をつけてHTTPリクエストを送信しても、リクエストしたコンテンツのサイズが小さい場合には、圧縮をせず平文でサーバーが応答する場合がありました。 圧縮してもあまりコンテンツサイズに変化がないとサーバーが判断したからだと考えられます。

 また、HTTPレスポンスヘッダで Content-Length を返却してくれない場合もありました。 PHPのアプリケーションをリクエストした際にそのようなことがありました。 サーバーやアプリケーションによって、そのようなことがありそうです。

おわりに

 本稿では Telnet を利用して HTTPヘッダ Accept-Encoding の動きを観察してみました。 HTTPの理解のお役に立てれば幸いです。

著者 : OSCA

OSCA

 初級WEBエンジニアです。最近は Android, iOS, WEBアプリの作成に力を入れています。 個人として何か一つでも世の中の多くの人に使ってもらえるアプリを作ろうと日々奮闘中です。
@engineer_osca