【入門編】HTTP/1.1ステータスコード1xx(Informational)の役割とクライアントの待機挙動 – HTTPプロトコル・通信規格実践ガイド

こんにちは!世界最高峰(自称!)のネットワークアーキテクトがお届けする、ちょっと深掘り技術ブログへようこそ!

今回は、普段あまり意識されないけれど、実は裏側でとても大切な役割を担っているHTTPステータスコードの世界、その中でも特に「ちょっと異色の存在」である1xx系のInformational(情報提供)コードにスポットを当ててみましょう。

特に「100 Continue」や「101 Switching Protocols」といったコードが、私たちのPCやスマホとWebサーバーの間でどんな「会話」を繰り広げているのか、そして、それがネットワークの安定性や効率性にどう貢献しているのかを、一緒に紐解いていきましょう!

難しいパケットの中身とか、英語のヘッダー名がずらずら並ぶような話は、僕が全部噛み砕いてお話ししますから、安心してついてきてくださいね!

—

郵便配達で例えるHTTPステータスコードの世界

まずは、HTTPステータスコード全体をざっくりと理解するために、身近な「郵便配達」に例えてみましょう。

あなたが誰かに手紙(リクエスト)を送ったとします。その手紙を受け取った相手(Webサーバー)は、手紙の内容を読んで、何らかの「返事」(レスポンス)をくれますよね。その返事の状態を数字で表したものが、HTTPステータスコードなんです。

  • 2xx (Success):「手紙、確かに受け取ったよ!ありがとう!」(リクエスト成功)
  • 3xx (Redirection):「ごめん、引っ越しちゃったから、こっちの住所に送ってくれる?」(別の場所へ転送)
  • 4xx (Client Error):「手紙の住所が間違ってるよ!ちゃんと書いてくれないと届かないよ!」(クライアント側の間違い)
  • 5xx (Server Error):「ごめん!今、体調悪くて返事書けないんだ…」(サーバー側の問題)

…と、こんな感じで、ステータスコードは「相手からの返事の内容」を教えてくれる、とっても便利な数字なんです。

1xxコードは「ちょっと確認させて!」の事前会話

じゃあ、今回の主役である1xx系のコードは、この郵便配達で言うと何になるでしょう?
これは「本物の返事の前に、ちょっとした確認の会話を挟む」イメージなんです。

例えば、あなたがものすごく重たい荷物(大量のデータ)を友達に送りたいとします。
いきなり「ヨイショ!」と荷物を抱えて友達の家まで持っていく前に、ちょっと電話で「今からすごく重い荷物持って行くけど、受け取れるかな?」「玄関に置いといても大丈夫?」なんて、事前に確認しますよね?

この「事前にちょっと確認する」という会話が、まさに1xxコードの役割なんです。
本命のリクエストに対する最終的な応答(2xx, 4xx, 5xxなど)が来る前に、一時的に状況を知らせたり、次のステップを促したりする、暫定的な情報を伝えるために使われます。

なぜHTTP/1.1で「1xxコード」が必要になったの?

HTTPは、インターネットが始まった頃から使われている、とっても歴史のあるプロトコルです。その歴史の中で、何度か大きな進化を遂げてきました。

  • HTTP/0.9: 最初期は、本当にシンプル。「ファイルちょうだい!」と言ったら、ファイルが返ってくるだけ。手紙を送ったら、ただ返ってくるだけ、みたいな。
  • HTTP/1.0: ここから「ヘッダー」という概念が導入されます。「この手紙は日本語で書いてますよ」「このファイルは写真ですよ」といった、手紙やファイルの「おまけ情報」を付けられるようになりました。
  • HTTP/1.1: そして、今回のお話の舞台であるHTTP/1.1。インターネットがどんどん普及し、Webサイトがリッチになり、送るデータ量も格段に増えていきました。

この「送るデータ量の増大」こそが、1xxコードが必要になった大きな理由の一つなんです。
例えば、Webサイトのフォームから何百MBもある動画ファイルをアップロードする、なんてことも当たり前になりましたよね。

もし、サーバーがその動画を受け取れない状態だったとしても、クライアント(あなたのブラウザなど)が「ヨシ!送るぞ!」といきなり全データを送り始めてしまったらどうなるでしょう?
サーバー側で「ごめん、ディスクがいっぱいでもう受け取れないよ!」なんてエラーが返ってくる頃には、すでに大量のデータがネットワークを無駄に流れてしまっていますよね。これは、ネットワークにとっても、サーバーにとっても、そしてあなたにとっても、無駄な労力と時間の消費になってしまいます。

そこで、「いきなり全部送る前に、ちょっとサーバーに確認してみようよ」という仕組みが求められるようになりました。これが、`100 Continue`コードの誕生に繋がっていきます。

—

1. 100 Continue: 「とりあえずヘッダーだけ送るから、準備OKか教えて?」

役割と具体的な挙動

`100 Continue`は、クライアントが「もしかしたら大量のボディデータを送るかもしれないから、先にヘッダーだけ送るね。サーバー側で受け入れ準備ができてたら『Continue』って教えてくれる?」と、サーバーに打診するためのステータスコードです。

もう少し具体的に見ていきましょう。

1. クライアントの打診

  • クライアントは、ボディデータ(例えばアップロードするファイルの中身)をまだ送らずに、リクエストヘッダーの中に「`Expect: 100-continue`」という特別な指示を付けて、まずヘッダー部分だけをサーバーに送ります。
  • これは「P.S. 〇〇について確認させてください」という補足指示を付けて手紙を送るようなものですね。

2. サーバーの応答

  • サーバーはそのヘッダーを受け取ると、クライアントからのボディデータを受け入れられるかどうかを判断します。
  • もし受け入れ可能であれば、「100 Continue」というレスポンスを返します。「うん、準備OKだよ!データ送っていいよ!」という意味ですね。
  • もし受け入れ不可能であれば(例えば、認証情報がおかしい、ディスク容量がないなど)、「401 Unauthorized」(認証失敗)や「413 Payload Too Large」(データが大きすぎる)といった、最終的なエラーコードをすぐに返します。

3. クライアントの次のアクション

  • クライアントが「100 Continue」を受け取ったら、「よし、サーバーは準備OKだ!」と判断し、残りのボディデータを送信し始めます。
  • もしエラーコードを受け取ったら、「あっ、ダメだったか…」と判断し、ボディデータの送信を中止します。

100 Continueのメリット

この「打診→確認」のプロセスを踏むことで、次のような大きなメリットが生まれます。

  • 無駄な帯域消費の防止: サーバーがデータを受け取れないのに、何百MBものデータをクライアントが送り続ける、という無駄を未然に防げます。ネットワークの回線が無駄に使われません。
  • サーバーリソースの節約: サーバー側も、受け取れないデータを延々と処理しようとする無駄な負荷を避けることができます。
  • 効率的なエラーハンドリング: クライアントは、早い段階でサーバーの状態を知ることができるため、問題があればすぐに処理を中断し、ユーザーにエラーを通知したり、別の解決策を提示したりできます。

現場での注意点とトラブルシューティング

普段意識しないところで動いている100 Continueですが、現場ではちょっとした落とし穴になることもあります。

クライアントの待機挙動とタイムアウト

クライアントは`Expect: 100-continue`ヘッダーを送った後、サーバーからの100 Continue、またはエラーコードが返ってくるまで、ボディデータの送信を一時的に停止して待機します。

この「待機」には、当然「いつまで待つか」というタイムリミット(タイムアウト)が必要です。
もしサーバーからの応答がなかなか来なかったり、途中のネットワーク機器(プロキシサーバーなど)が応答をブロックしてしまったりすると、クライアントは永遠に待ち続けてしまう可能性があります。

多くのHTTPクライアントライブラリやWebブラウザは、この待機時間にデフォルトのタイムアウトを設定しています(例えば、数秒程度)。もしこのタイムアウトが発生すると、クライアントはボディデータを送る前に処理を中断し、エラー(例: `500 Internal Server Error`のような汎用的なエラーや、クライアント固有のエラー)を返すことがあります。

プロキシサーバーの扱い

ネットワークの途中にプロキシサーバーが挟まっている場合、そのプロキシが`Expect: 100-continue`ヘッダーを正しく解釈し、サーバーへ転送してくれるかが重要です。古いプロキシや設定によっては、このヘッダーを無視したり、逆に勝手に100 Continueを返してしまったりすることがあり、予期せぬ挙動に繋がることがあります。

このような場合は、クライアント側で`Expect: 100-continue`ヘッダーを送らないように設定することも可能です。

curlコマンドで100 Continueを体験してみよう!

実際に`Expect: 100-continue`ヘッダーを付けてリクエストを送る様子を、`curl`コマンドで試してみましょう。

ヘッダーだけを送信し、ボディデータの送信を待機する例
(実際にはサーバー側で100 Continueを返す設定が必要です)
このコマンドは、サーバーが100 Continueを返さない限り、ボディデータの送信を待ち続けます。
サーバーが100 Continueを返すと、ダミーのボディデータ(”Hello World”)が送信されます。
curl -v \
-X POST \
-H “Expect: 100-continue” \
-H “Content-Type: text/plain” \
–data-binary “Hello World” \
http://localhost:8080/upload # ここはテスト用のサーバーURLに置き換えてください

Expectヘッダーを付けない場合(通常のリクエスト)
この場合、クライアントは打診せずにいきなりボディデータを送信します。
curl -v \
-X POST \
-H “Content-Type: text/plain” \
–data-binary “Hello World” \
http://localhost:8080/upload

Webサーバー(Apache, Nginxなど)の設定によっては、`Expect: 100-continue`ヘッダーの扱いを変えることができます。例えばNginxではデフォルトでこのヘッダーをサポートしており、特別な設定なしに動作することが多いですが、特定の状況下で無効にすることも可能です。

—

2. 101 Switching Protocols: 「手紙のやり取りから、電話に切り替えよう!」

役割と具体的な挙動

`101 Switching Protocols`は、クライアントとサーバーが「今までの通信プロトコルは一旦終わりにして、これからは別のプロトコルで通信しようね!」と、お互いに合意したことを示すステータスコードです。

これも、私たちの会話で例えると分かりやすいでしょう。

「すみません、今までは手紙でやり取りしていましたが、これからはもっとリアルタイムに話したいので、電話に切り替えませんか?」とあなたが提案し、相手が「うん、いいよ!電話で話そう!」と合意するようなものです。

最も代表的な利用例は、WebSocketへのプロトコルアップグレードです。

1. クライアントの提案

  • クライアントは、通常のHTTPリクエストの中に「`Upgrade: websocket`」と「`Connection: Upgrade`」という特別なヘッダーを付けてサーバーに送ります。
  • これは「もしよければ、WebSocketという別の通信方法に切り替えたいのですが、いかがですか?」という提案ですね。

2. サーバーの合意

  • サーバーはこの提案を受け取ると、WebSocketプロトコルに切り替える準備ができていれば、「101 Switching Protocols」というレスポンスを返します。
  • これは「はい、承知しました!では、これからはWebSocketで通信しましょう!」という合意のサインです。

3. プロトコルの切り替え

  • クライアントが101 Switching Protocolsを受け取った瞬間から、HTTP通信は終了し、以降はWebSocketプロトコルに基づいた通信が始まります。
  • この時、ネットワークの「回線」自体は同じTCPコネクションを使い続けますが、その上で流れる「言葉のルール」(プロトコル)が変わる、というイメージです。

101 Switching Protocolsのメリット

  • リアルタイム通信の実現: HTTPの「リクエスト→レスポンス」という一問一答形式では難しかった、サーバーからの能動的なデータ送信(プッシュ通知)や、低遅延での双方向通信が可能になります。チャットアプリやオンラインゲームなどで活躍していますね。
  • 通信効率の向上: 一度プロトコルを切り替えてしまえば、それ以降はHTTPのヘッダー情報を何度もやり取りする必要がなくなるため、通信量が削減され、効率が向上します。

WebSocketアップグレードリクエストのイメージ

WebSocketへのアップグレードは、以下のようなHTTPリクエストから始まります。

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

これに対して、サーバーがプロトコルを切り替える準備ができている場合、以下のようなレスポンスを返します。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

このレスポンスを受け取った後、クライアントとサーバーはHTTPのルールを離れ、WebSocketのルールに従ってデータのやり取りを始める、という流れになります。なんだか、ワクワクするでしょう?

—

その他の1xxコードたち

今回は100 Continueと101 Switching Protocolsに焦点を当ててきましたが、他にもいくつか1xxコードが存在します。

  • 102 Processing (WebDAV):
  • リクエストの処理に時間がかかっていることを示すコードです。特にWebDAV(WebDAVはファイル共有や管理に使われるHTTPの拡張プロトコル)のような、複雑な操作を伴うリクエストで使われることがあります。
  • 「今、一生懸命作業してるから、もう少しだけ待っててね!」というメッセージですね。
  • 103 Early Hints (RFC 8297):
  • これは比較的新しいコードで、メインのレスポンス(例えばHTMLページ全体)がまだ準備できていない段階で、クライアントに「このページにはこういう画像とかCSSファイルが必要になるから、先にダウンロードの準備をしておくといいよ!」といったヒントを教えるために使われます。
  • 「メインのお料理はまだだけど、先に箸と皿を用意しとくといいよ!」という、気の利いた案内係のようなイメージです。Webページの表示速度向上に貢献します。

これらのコードも、ネットワーク通信をより賢く、より効率的にするための工夫が詰まっているんですよ。

—

クライアントの待機挙動とタイムアウト制御の重要性

1xxコードは、クライアントに「最終的な応答を待つ間、一時的にどういう状況なのか」を伝えてくれる、とても親切な仕組みです。しかし、クライアント側からすると、この「待機」の管理が非常に重要になります。

想像してみてください。あなたは宅配便で大きな荷物を送りたいと思い、事前に「受け取り可能ですか?」と電話で確認しました。もし、相手からの返事が一向に来なかったら、いつまで待ちますか?

数分待っても返事がなければ、「あれ?もしかして電話が繋がってないのかな?」「相手は忙しいのかな?」と考えて、一旦電話を切って別の方法を考えますよね。

これと全く同じで、HTTPクライアントも、100 Continueのような情報提供の応答を待つ間に、「いつまで待つか」というタイムアウトを設定しておく必要があります。

  • もしタイムアウトが短すぎると、サーバーは処理中なのにクライアントが勝手に諦めてしまい、エラーになる可能性があります。
  • もしタイムアウトが長すぎると、サーバーからの応答がないままクライアントが長時間待ち続け、結果的にユーザー体験が悪化したり、リソースが無駄になったりする可能性があります。

このため、Webアプリケーションやシステムを開発する際には、HTTPクライアントのタイムアウト設定が適切であるかどうかが、安定した通信を実現する上で非常に重要なポイントになるんです。これは、現場でトラブルシューティングをする際にも、真っ先に確認すべき項目の一つになります。

—

まとめ:1xxコードは「調整役」!

今回は、HTTP/1.1の1xx系ステータスコード、特に100 Continueと101 Switching Protocolsについて深掘りしてきました。

いかがでしたでしょうか?数字だけの無機質なコードに見えて、実はクライアントとサーバーの間で、まるで人間が会話するように「準備OK?」「じゃあ、やり方変えようか!」といった、きめ細やかな調整役を担っていることが、少しでも伝わったなら嬉しいです。

これらのコードは、インターネット上のデータ通信がより効率的に、そして柔軟に行われるために、裏側でそっと活躍している縁の下の力持ちなんです。

今日からあなたも、Webサービスを利用する際、ブラウザの開発者ツールなどを開いて、どんなステータスコードが返ってきているのかを少しだけ意識してみると、ネットワークの世界がもっと面白く見えてくるはずですよ!

一歩ずつ、ネットワークの奥深さを一緒に探求していきましょう!それでは、また次回の記事でお会いしましょう!

コメント

タイトルとURLをコピーしました