net/http/internal/http2: don't shrink HPACK decoder table before SETTINGS ack

A server configured with a MaxDecoderHeaderTableSize below the initial
4096 bytes (RFC 7540, section 6.5.2) applied it to its HPACK decoder at
connection start. But the server doesn't know when the client has
received and applied a SETTINGS value until the client acknowledges the
SETTINGS frame (RFC 7540, section 6.5.3), and the client's encoder
signals a table size reduction with a dynamic table size update at the
beginning of the first header block following the settings
acknowledgment (RFC 7541, section 4.2). Until then, the client may keep
using the initial 4096-byte table. A spec-compliant client (including
Go's own http2 client) that sent a header block referencing a dynamic
table entry in the first RTT was rejected with a connection-fatal
COMPRESSION_ERROR.

Instead, start the decoder at the initial table size and apply the
configured smaller size once the client acks our SETTINGS. All header
blocks after the ack were encoded by a client that has processed the
setting, and a compliant encoder begins its next header block with a
dynamic table size update. Memory during the window is bounded by the
same 4096 bytes as today's default.

Change-Id: Idecd25a1e0473c3cff314922ddc97ace14cb2e5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/827024
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Auto-Submit: Brad Fitzpatrick <bradfitz@golang.org>
2 files changed
tree: 00f479235d398ab9d265c343597e1a6b0a4338cc
  1. .github/
  2. api/
  3. doc/
  4. lib/
  5. misc/
  6. src/
  7. test/
  8. .gitattributes
  9. .gitignore
  10. codereview.cfg
  11. CONTRIBUTING.md
  12. go.env
  13. LICENSE
  14. PATENTS
  15. README.md
  16. SECURITY.md
README.md

The Go Programming Language

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Gopher image Gopher image by Renee French, licensed under Creative Commons 4.0 Attribution license.

Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.

Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.

Download and Install

Binary Distributions

Official binary distributions are available at https://go.dev/dl/.

After downloading a binary release, visit https://go.dev/doc/install for installation instructions.

Install From Source

If a binary distribution is not available for your combination of operating system and architecture, visit https://go.dev/doc/install/source for source installation instructions.

Contributing

Go is the work of thousands of contributors. We appreciate your help!

To contribute, please read the contribution guidelines at https://go.dev/doc/contribute.

Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.