巨大な荷物を「賢く」受け取る方法:HTTP/1.1の「If-Range」という魔法
こんにちは!インフラエンジニアの視点から、Webの裏側を紐解くこのブログへようこそ。
インターネットで大きなファイルをダウンロードしているとき、途中で回線が切れて「あぁ、最初からやり直しだ……」と絶望した経験はありませんか?Webの世界には、そんな悲劇を防ぐための「部分取得(レンジリクエスト)」という仕組みがあります。
しかし、ただ分割して受け取るだけでは不十分なケースがあります。「ダウンロードしている最中に、サーバーのファイルが更新されてしまったらどうなるの?」という問題です。
今日は、そんなトラブルを華麗に回避する「If-Rangeヘッダー」という賢い仕組みについて、一緒に見ていきましょう。
—
そもそも「部分リクエスト」って何?
まず、基本のおさらいです。もしあなたが、1000ページの巨大な辞書を郵便で送ってもらうと想像してください。
普通なら「辞書を丸ごと一冊送ってください!」と頼みますよね。これが通常のHTTPリクエストです。しかし、辞書の後半の500ページだけが必要な場合、「全部送らなくていいよ、後半の500ページだけちょうだい!」と頼むのが「レンジリクエスト」です。
ネットワークの世界でも同じです。「ファイルの〇〇バイト目から〇〇バイト目までをちょうだい」と頼むことで、通信量を節約し、効率よくデータをやり取りしているんです。
—
そこで立ちはだかる「更新」の壁
さて、ここからが本題です。あなたが「辞書の後半500ページ」を頼んだとします。郵便屋さんがそのページを切り取っている間に、元の辞書が新しい版に改訂されてしまったらどうでしょう?
古い版の後半500ページと、新しい版の後半500ページ。これらが混ざってしまうと、辞書として使い物になりませんよね。
この「ファイルが変わっていたら、部分的に受け取るのはやめて、最初から全部やり直したい!」という高度な要求を叶えてくれるのが、`If-Range`ヘッダーの役割なんです。
—
If-Rangeヘッダーがやっていること
`If-Range`は、サーバーに向かってこう確認をしています。
> 「ねえ、僕が持っているこのファイルの『指紋(ETag)』や『作成日時(Last-Modified)』と、今サーバーにあるファイルの情報は一致する?
>
> 一致するなら、続きのデータをちょうだい(部分取得)。
> 一致しないなら、ファイルが新しくなっているみたいだから、最初から全部送り直して!」
郵便屋さんにお願いする時に、「この古い辞書の表紙と一致するなら続きを。違うなら最新版を全ページよろしく!」と付け加えるようなものですね。
具体的なリクエストの様子
ブラウザ(クライアント)がサーバーに送るリクエストの中身は、こんな風になっています。
GET /big-file.zip HTTP/1.1
Host: example.com
Range: bytes=5000- # 5000バイト目以降が欲しい!
If-Range: “abc-123” # この「指紋(ETag)」が一致する時だけ続きをちょうだい
サーバー側の反応
サーバーは、現在持っているファイルのETagと、送られてきた`”abc-123″`を照らし合わせます。
1. 一致した場合:`206 Partial Content`(一部のデータ)を返します。
2. 一致しなかった場合:`200 OK`(全部のデータ)を最初から返します。
—
なぜこれがインフラとして重要なの?
初学者のうちは「全部一気に送ればいいじゃん」と思うかもしれません。しかし、世界中のユーザーがスマホで動画を見たり、巨大なアプリをアップデートしたりする現代のWebでは、「通信の効率」と「データの整合性」は命綱です。
もし`If-Range`がなかったら、ブラウザは「とりあえず続きを……」とリクエストして、結果として壊れたファイルを受け取ってしまうことになります。その壊れたファイルをユーザーが展開してエラーになる……そんな無駄な通信やトラブルを防ぐために、この小さなヘッダーが裏側で絶えず働いているのです。
—
まとめ:一歩ずつ理解していきましょう
今日覚えていただきたいのは、この2点だけです。
- レンジリクエスト:大きなファイルを小分けに受け取る、便利な仕組み。
- If-Rangeヘッダー:ファイルの「指紋(ETag)」を照らし合わせて、最新の状態かどうかを確認してから続きを受け取るための、転ばぬ先の杖。
ネットワークのプロトコルは、まるで人間同士の会話のように「確認」と「合意」を繰り返しています。一見難しそうなヘッダーも、こうして「郵便物」に例えてみると、意外と親しみやすく感じませんか?
ぜひ、ブラウザの開発者ツール(F12キーを押して「ネットワーク」タブ)を開いて、実際に通信を覗いてみてください。`If-Range`や`Range`といった言葉が、現実の通信の中で活き活きと働いている様子が確認できるはずですよ。
それでは、また次回の深掘りでお会いしましょう!
コメント