ホームページ > バックエンド開発 > Golang > `json.NewDecoder().Decode()` が HTTP コンテキストの期限を尊重しないのはなぜですか?

`json.NewDecoder().Decode()` が HTTP コンテキストの期限を尊重しないのはなぜですか?

Mary-Kate Olsen
リリース: 2024-10-29 09:34:29
オリジナル
710 人が閲覧しました

Why doesn't `json.NewDecoder().Decode()` respect HTTP Context Deadlines?

json.NewDecoder().Decode() によって HTTP コンテキストの期限が無視されました

質問:

context.WithTimeout を使用して HTTP リクエストの時間制限を設定する場合、タイムアウトを超えると ioutil.ReadAll メソッドはリクエストを中断し、適切なエラーを返します。ただし、json.NewDecoder(resp.Body).Decode は期限を無視しているようで、context.DeadlineExceeded ではなく nil エラーを返します。これはバグですか?

答え:

いいえ、これはバグではありません。 net/http パッケージはリクエストの処理にバッファを利用するため、プログラムが応答本文を読み取る前に、応答本文の一部または全体がバッファに読み込まれる可能性があります。したがって、コンテキストの有効期限が切れても、必ずしもプログラムによる読み取り操作の完了が妨げられるわけではありません。

例:

意図的に応答を遅らせる、変更された HTTP テスト サーバーを考えてみましょう。 readDoesntFail を使用する場合、サーバーは部分応答 (10 バイト) を送信し、それをフラッシュし、6 秒待ってから残りを送信します。

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    s := []byte(`{"ip":"12.34.56.78"}`)
    w.Write(s[:10])
    if f, ok := w.(http.Flusher); ok {
        f.Flush()
    }
    time.Sleep(time.Second * 6)
    w.Write(s[10:])}))
defer ts.Close()
ログイン後にコピー

このシナリオでは、json.Decoder.Decode() は読み取りを試みます。データがまだバッファリングされていないため、接続から切り離されます。コンテキストの有効期限が切れると、接続からさらに読み取ると context.DeadlineExceeded エラーがトリガーされます。

結論:

json.Decoder.Decode() は、次の場合にコンテキストの期限を尊重します。データはまだバッファリングされていません。ただし、データが部分的または完全にバッファリングされている場合、コンテキストの期限によってプログラムが読み取り操作を完了することが妨げられない可能性があります。コンテキストの期限に合わせて動作の一貫性を高めるには、ioutil.ReadAll または同様のアプローチを使用することをお勧めします。

以上が`json.NewDecoder().Decode()` が HTTP コンテキストの期限を尊重しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート