「いきなり大荷物を送ってごめんね」を防ぐ!HTTP/1.1のスマートな気遣い『Expect: 100-continue』の世界
こんにちは!ネットワークの世界に飛び込んだ皆さん、日々パケットという名の「小さな手紙」たちが、世界中を駆け巡る様子を想像したことはありますか?
今日は、HTTP/1.1という少し「おせっかいだけど、実はすごく気が利く」プロトコルのお話です。特に、大きなデータを送る時の「Expect: 100-continue」という仕組みに注目してみましょう。
「大きな荷物を送る前に、受け取れるか確認する」——これ、現実世界では当たり前ですよね。この仕組みがネットワーク上でどう動いているのか、一緒に紐解いていきましょう!
—
1. なぜ「確認」が必要なのか?(現実世界の例え)
想像してみてください。あなたは、ものすごく重たい20kgの段ボール箱を、友人の家に送ろうとしています。
もし、友人が不在だったり、家の玄関が鍵で閉まっていたらどうでしょう? 20kgの荷物を必死に運んでいったのに、結局持ち帰らなければなりません。これって、すごく疲れますよね。
ネットワークの世界でも同じです。
サーバー(受け取り手)に対して、数ギガバイトもの巨大なデータをいきなり送りつけると、もし途中で「認証エラーです」「容量オーバーです」と断られたら、その通信はすべて「無駄なパケット」になってしまいます。
そこで登場するのが、『Expect: 100-continue』です。
これは、荷物を送る前に「今から大きな荷物を送るけど、受け取れる準備はできている?」と、身軽な手紙(ヘッダー)だけを先に送るスマートな手法なんです。
—
2. パケットのドラマ:100-continueの旅路
このやり取りは、まるで「丁寧な挨拶」から始まります。
1. クライアント(送る側): 「これから巨大なデータを送りたいんだけど、受け取ってくれるかな?」(`Expect: 100-continue` を含んだリクエストを送信)
2. サーバー(受け取る側): 「お、了解!送ってくれて大丈夫だよ!」(`100 Continue` という応答を返す)
3. クライアント: 「ありがとう!それじゃあ送るね!」(実際のデータ本体を送信)
もしサーバー側が「いや、今はダメ」という状況なら、400番台(エラー)のレスポンスがすぐに返ってくるので、クライアントは巨大なデータを送信する前に止まることができます。これで帯域の節約もバッチリですね!
—
3. 実務での実装サンプル:どう書くの?
実際にプログラムを書く際、この挙動を意識することは少ないかもしれませんが、ライブラリの設定で触れることがあります。Node.jsでリクエストを送る際のイメージを見てみましょう。
const http = require(‘http’);
// 送信先の設定
const options = {
hostname: ‘example.com’,
path: ‘/upload’,
method: ‘POST’,
headers: {
// ここで「送る前に確認させてね!」と伝えます
‘Expect’: ‘100-continue’,
‘Content-Type’: ‘application/octet-stream’
}
};
const req = http.request(options, (res) => {
// サーバーからのレスポンスを処理
res.on(‘data’, (chunk) => { console.log(‘データを受信:’, chunk); });
});
// サーバーが「100 Continue」を返すと、このイベントが発火します
req.on(‘continue’, () => {
console.log(‘サーバーから許可が出たので、データを送ります!’);
req.write(‘ここに巨大なデータが詰まっています…’);
req.end();
});
—
4. 忘れてはいけない「タイムアウト」という落とし穴
さて、ここでインフラエンジニアとして避けて通れないのが「サーバーが返事をくれない場合」のトラブルです。
もしサーバーが古かったり、設定が適切でなかったりすると、クライアントが「送っていい?」と聞いても、サーバーが無視(応答なし)を決め込むことがあります。
このとき、クライアントは無限に待ち続けるわけではありません。ある程度の時間(例えば1秒〜2秒程度)待っても返事がなければ、「きっと受け取る準備はできていないんだな」と判断して、見切り発車でデータを送り始めるのが一般的です。
- なぜ待つのか?: 通信効率を最大化するため。
- なぜ送るのか?: サーバーが「100-continue」という仕組みを理解していない場合でも、通信を完遂させるためです。
この「待ち時間(タイムアウト)」の設定が、ネットワークのレスポンス性能に直結します。現場で「アップロードが異常に遅い」というトラブルがあったら、この「待ち時間」が長すぎていないか、サーバー側のハンドシェイクが遅延していないかを疑うのが定石です。
—
まとめ:ネットワークは「思いやり」の積み重ね
HTTP/1.1の『Expect: 100-continue』は、単なる通信ルールのひとつですが、そこには「相手の状況を慮(おもんぱか)る」という、人間社会にも通じる優しさがあります。
- 送る前に確認する(Expect: 100-continue)
- 準備OKなら許可を出す(100 Continue)
- ダメなら即座に断る(4xx/5xx)
- 返事がなければ自己判断で進む(タイムアウト後の送信)
この一連の流れをイメージできるようになると、ネットワークのログを見た時の視界がガラリと変わるはずです。
パケットの挙動を追うことは、まるで通信の現場を覗き見る探偵のようなもの。ぜひ、皆さんも自分の書くコードや通信環境が、どんな「会話」をしているのか、想像を膨らませてみてくださいね!
それでは、また次回の技術探訪でお会いしましょう!
コメント