HTTPのRangeリクエスト

3 min read

こんにちは無能です。
ずっと思っていたのだが、HTTPのGetリクエストって毎回ページ全体を取得されてきてしまい全くエコじゃないと感じていた。
結局必要な情報、例えば
<head>内だけを取得したいのであれば一部だけ取得し、それでもなければ全体取得し抽出を行う
みたいに行えれば、ネットワーク転送コストもhead内などのタグをパースする処理もCPUに優しく短くなるし良いこと尽くめなように感じていて。
しかも、せっかくのTCP通信なのにHTTPでできないことなんて無いだろうと調べたらやっぱり出来るようだ。
HTTP 範囲リクエスト

curlでテスト

こんな感じに-Hオプションでヘッダー情報にレンジ幅を付与してあげることで制限出来るようだ。

$ curl -H "Range: bytes=0-1024" https://soulminingrig.com/
<!DOCTYPE html>
<html lang="ja"><head><meta charset="utf-8"><meta content="width=device-width,initial-scale=1.0" name="viewport"><title>Home - SOULMINIGRIG</title><meta content="light dark" name="supported-color-schemes"><meta content="hsl(220, 20%, 100%)" media="(prefers-color-scheme: light)" name="theme-color"><meta content="hsl(220, 20%, 10%)" media="(prefers-color-scheme: dark)" name="theme-color"><link href="/pagefind/pagefind-ui.css" rel="stylesheet"><link href="/styles.css" rel="stylesheet"><link href="/feed.xml" rel="alternate" title="SOULMINIGRIG" type="application/atom+xml"><link href="/feed.json" rel="alternate" title="SOULMINIGRIG" type="application/json"><link href="/favicon.png" rel="icon" sizes="32x32" type="image/png"><link href="https://soulminingrig.com/" rel="canonical"><script src="/js/main.js" type="module"></script><style>.page-title{background:var(--color-highlight);padding:.5em;font-size:1.2em}</style><script data-website-id="6031aa47-e715-4f87-a99a-9e3046e5dcdc" defer="" src="https://n

範囲指定なので、先頭じゃなくてもOKみたいなので

$ curl -H "Range: bytes=1025-1025" https://soulminingrig.com/
o

もはや1byteでもちゃんと帰ってくる。

実用的には

ヘッダー情報に付与してあげるだけで取得時のレンジ制限は掛けられるので基本的にどの言語でも可能だし、何よりも余り意識していないようなネットワーク帯のエコな使用を行えることが出来る。
HTMLの<head>内だけを抽出したいのであれば、Range: bytes=0-4096のように指定して、駄目だったら全部取得又はもっとエコにするなら4096byte単位で次のレンジ幅でGetリクエストを送るか。
結果的には、後続処理のライブラリがHTMLタグの抽出時間も短くなるし、相手サーバにも優しい。

ただし、MDNのサイトにもあるように
"サーバーが部分リクエストに対応しているかどうかの確認"は今はだいたいどこも対応しているだろう、という想定だと良くないので厳密に行うのであればヘッダー情報からの戻りで判定する条件も使わないと行けない。

しかし、新たなインターネットの帝王が・・・。

新たなインターネットの王だと言わんばかりのティッカーシンボルであるNETを冠するCloudFlareを使用している場合、リクエスト単位で制限がされる様子なので結果的に処理が高速になったところで途中でDDoS対策としてのブロックが入ると結局意味は強くは感じない。
が、例えばVPS上でなにかBotを動かしている場合に激しく外部へのリクエストで帯域を食う(というほど使う人なんて居ないだろうが・・・。)ならば、今回みたいな部分リクエストは効果はあるのかもしれない。

しかしながら、一度メモリ空間にはHTTPリクエストを行ったときの格納されるはずなので多少なりともメモリ使用量も減る気はしなくはないことなので何かしらのサイト情報を取得したいようなツールを作る人がいればこの動作を入れれば相手には少しは優しい動作にすることでもあるので必要に応じて行う必要はありそう。

知っていたようで、何気に知らなかったHTTPのことでした。