http3: initialize trailer map with empty trailer entries when parsing the header (#4656)

* feat: pre-populate trailers on response with empty values

* fix: improve comment/func name
This commit is contained in:
Kevin McDonald
2024-09-07 08:59:07 +02:00
committed by GitHub
parent 4f48b2ce25
commit b92bf0c80d
5 changed files with 61 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/http"
"net/textproto"
"net/url"
"strconv"
"strings"
@@ -222,6 +223,7 @@ func updateResponseFromHeaders(rsp *http.Response, headerFields []qpack.HeaderFi
rsp.Proto = "HTTP/3.0"
rsp.ProtoMajor = 3
rsp.Header = hdr.Headers
processTrailers(rsp)
rsp.ContentLength = hdr.ContentLength
status, err := strconv.Atoi(hdr.Status)
@@ -232,3 +234,27 @@ func updateResponseFromHeaders(rsp *http.Response, headerFields []qpack.HeaderFi
rsp.Status = hdr.Status + " " + http.StatusText(status)
return nil
}
// processTrailers initializes the rsp.Trailer map, and adds keys for every announced header value.
// The Trailer header is removed from the http.Response.Header map.
// It handles both duplicate as well as comma-separated values for the Trailer header.
// For example:
//
// Trailer: Trailer1, Trailer2
// Trailer: Trailer3
//
// Will result in a http.Response.Trailer map containing the keys "Trailer1", "Trailer2", "Trailer3".
func processTrailers(rsp *http.Response) {
rawTrailers, ok := rsp.Header["Trailer"]
if !ok {
return
}
rsp.Trailer = make(http.Header)
for _, rawVal := range rawTrailers {
for _, val := range strings.Split(rawVal, ",") {
rsp.Trailer[http.CanonicalHeaderKey(textproto.TrimString(val))] = nil
}
}
delete(rsp.Header, "Trailer")
}