Skip to content

Commit 1f20a3a

Browse files
committed
x/net/http2: exclude some header from 1xx responses
Content-Length and Transfer-Encoding must not be sent when the response has no body. Necessary to fix the tests of golang/go#42597.
1 parent 9564170 commit 1f20a3a

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

http2/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,6 +2681,7 @@ func (rws *responseWriterState) writeHeader(code int) {
26812681
streamID: rws.stream.id,
26822682
httpResCode: code,
26832683
h: h,
2684+
noBody: true,
26842685
endStream: rws.handlerDone && !rws.hasTrailers(),
26852686
}) != nil {
26862687
rws.dirty = true

http2/server_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4392,6 +4392,7 @@ func TestServerSendsProcessing(t *testing.T) {
43924392
func TestServerSendsEarlyHints(t *testing.T) {
43934393
testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
43944394
h := w.Header()
4395+
h.Add("Content-Length", "123")
43954396
h.Add("Link", "</style.css>; rel=preload; as=style")
43964397
h.Add("Link", "</script.js>; rel=preload; as=script")
43974398
w.WriteHeader(http.StatusEarlyHints)
@@ -4437,7 +4438,7 @@ func TestServerSendsEarlyHints(t *testing.T) {
44374438
{"link", "</script.js>; rel=preload; as=script"},
44384439
{"link", "</foo.js>; rel=preload; as=script"},
44394440
{"content-type", "text/plain; charset=utf-8"},
4440-
{"content-length", "5"},
4441+
{"content-length", "123"},
44414442
}
44424443

44434444
if !reflect.DeepEqual(goth, wanth) {

http2/write.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ type writeResHeaders struct {
181181
httpResCode int // 0 means no ":status" line
182182
h http.Header // may be nil
183183
trailers []string // if non-nil, which keys of h to write. nil means all.
184+
noBody bool // if true, Content-Length and Transfer-Encoding will not be set
184185
endStream bool
185186

186187
date string
@@ -214,7 +215,12 @@ func (w *writeResHeaders) writeFrame(ctx writeContext) error {
214215
encKV(enc, ":status", httpCodeString(w.httpResCode))
215216
}
216217

217-
encodeHeaders(enc, w.h, w.trailers)
218+
var excludedKeys map[string]bool
219+
if w.noBody {
220+
excludedKeys = map[string]bool{"Content-Length": true, "Transfer-Encoding": true}
221+
}
222+
223+
encodeHeaders(enc, w.h, w.trailers, excludedKeys)
218224

219225
if w.contentType != "" {
220226
encKV(enc, "content-type", w.contentType)
@@ -273,7 +279,7 @@ func (w *writePushPromise) writeFrame(ctx writeContext) error {
273279
encKV(enc, ":scheme", w.url.Scheme)
274280
encKV(enc, ":authority", w.url.Host)
275281
encKV(enc, ":path", w.url.RequestURI())
276-
encodeHeaders(enc, w.h, nil)
282+
encodeHeaders(enc, w.h, nil, nil)
277283

278284
headerBlock := buf.Bytes()
279285
if len(headerBlock) == 0 {
@@ -329,8 +335,9 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
329335
}
330336

331337
// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
332-
// is encoded only if k is in keys.
333-
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
338+
// is encoded only if k is in keys. If excludeKeys is not nil, then
339+
// (k, k[h]) is encoded only if k is not true in excludeKeys.
340+
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string, excludeKeys map[string]bool) {
334341
if keys == nil {
335342
sorter := sorterPool.Get().(*sorter)
336343
// Using defer here, since the returned keys from the
@@ -340,6 +347,10 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
340347
keys = sorter.Keys(h)
341348
}
342349
for _, k := range keys {
350+
if excludeKeys[k] {
351+
continue
352+
}
353+
343354
vv := h[k]
344355
k, ascii := lowerHeader(k)
345356
if !ascii {

0 commit comments

Comments
 (0)