どうも、「知らなかったよ、オッカサンシリーズ」206 回目の司会を務めさせて頂く…かっぱ@inokara)です。


はじめに

HTTP ステータスコードの中に 206 という、個人的にあまり見覚えがないステータスコードがあったので調べてみました。


206 回目のプロポーズ

ま、この 206 というステータスコードは何なのか RFC 2616 Hypertext Transfer Protocol — HTTP/1.1 では…

The server has fulfilled the partial GET request for the resource.
The request MUST have included a Range header field (section 14.35)
indicating the desired range, and MAY have included an If-Range
header field (section 14.27) to make the request conditional.

とあります。超意訳すると以下のような感じでしょうか。

  • サーバーはリソースに対する部分的なリクエストを認めまっせ
  • 但し、リクエストには Range Header を付けてね
  • また、条件付きのリクエストの場合には If-Range ヘッダが含めてね

ほうほう、つまり GET について Range Header 付きでサーバーに投げるとコンテンツの一部だけを取り出せるってことのようですな。


やりましょう

構成

以下のような構成でやってみました。

01

リクエスト

HEAD リクエスト
HEAD /index.html HTTP/1.1
Host: example.com

上記を実行すると…

HTTP/1.1 200 OK
Date: Fri, 08 Aug 2014 22:13:16 GMT
Server: Apache/2.2.27 (Amazon)
Last-Modified: Fri, 25 Apr 2014 22:24:59 GMT
ETag: "41b52-eff-4f7e56f9d64c0"
Accept-Ranges: bytes
Content-Length: 3839
Content-Type: text/html; charset=UTF-8

上記のようなレスポンスが返ってきます。ポイントは Accept-RangesContent-Length です。これで index.html の長さが判ります。

お GET リクエスト
GET /index.html HTTP/1.1
Host: example.com
Range: bytes=0-10

上記のように Range リクエストを投げます。パラメータは bytes=0-10 です。先頭から 11 バイトまでを取得します。

02

おお、途中までしかレスポンスが返ってこないので部分的なリクエストに応えてくれているようです。しかも、ちゃんと HTTP/1.1 206 Partial Content を返してくれています。

ちょい気になった件

コンテンツによっては Range ヘッダを付けても無視されることがありました。

03

例えば、上図の場合 phpinfo() の結果を返すスクリプトに対して Range リクエストを投げても 200 が返ってきてコンテンツを部分的に取得することが出来ませんでした。

なんでや…

その鍵はレスポンスヘッダのようです。

以下は Range ヘッダが効いて一部のコンテンツのみが取得出来る場合のレスポンスヘッダです。

04

そして、以下は Range ヘッダを投げても無視されてしまう場合のレスポンスヘッダです。

05

Range ヘッダを投げても無視されてしまうコンテンツの場合にはレスポンスに Content-Length 等のコンテンツの長さを知る為のレスポンスが含まれていないことが判りました。ほうほう。このことから Range ヘッダはレスポンスの長さを判断出来る(Content-Length がレスポンスヘッダにある)必要があるようです。


知らないことが…

大杉漣です…orz

元記事は、こちら