Skip to content

Commit a1278a7

Browse files
elindseygopherbot
authored andcommitted
http2: add common header caching to Transport to reduce allocations
Currently Server builds two process-global maps to cut down allocations due to lower-casing and canonicalization of common headers. Lower-casing/canonicalization has also been a significant source of garbage in Transport - this change extends use of the same process-global maps to the client. Change-Id: I2324c9567a61f28d4dd633a2c0618f08ddbf457c Reviewed-on: https://go-review.googlesource.com/c/net/+/442175 Run-TryBot: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Damien Neil <[email protected]> Reviewed-by: Bryan Mills <[email protected]>
1 parent c877839 commit a1278a7

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

http2/headermap.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,11 @@ func lowerHeader(v string) (lower string, ascii bool) {
9595
}
9696
return asciiToLower(v)
9797
}
98+
99+
func canonicalHeader(v string) string {
100+
buildCommonHeaderMapsOnce()
101+
if s, ok := commonCanonHeader[v]; ok {
102+
return s
103+
}
104+
return http.CanonicalHeaderKey(v)
105+
}

http2/transport.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ var errRequestCanceled = errors.New("net/http: request canceled")
10751075
func commaSeparatedTrailers(req *http.Request) (string, error) {
10761076
keys := make([]string, 0, len(req.Trailer))
10771077
for k := range req.Trailer {
1078-
k = http.CanonicalHeaderKey(k)
1078+
k = canonicalHeader(k)
10791079
switch k {
10801080
case "Transfer-Encoding", "Trailer", "Content-Length":
10811081
return "", fmt.Errorf("invalid Trailer key %q", k)
@@ -1915,7 +1915,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
19151915

19161916
// Header list size is ok. Write the headers.
19171917
enumerateHeaders(func(name, value string) {
1918-
name, ascii := asciiToLower(name)
1918+
name, ascii := lowerHeader(name)
19191919
if !ascii {
19201920
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
19211921
// field names have to be ASCII characters (just as in HTTP/1.x).
@@ -1968,7 +1968,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {
19681968
}
19691969

19701970
for k, vv := range trailer {
1971-
lowKey, ascii := asciiToLower(k)
1971+
lowKey, ascii := lowerHeader(k)
19721972
if !ascii {
19731973
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
19741974
// field names have to be ASCII characters (just as in HTTP/1.x).
@@ -2301,15 +2301,15 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
23012301
Status: status + " " + http.StatusText(statusCode),
23022302
}
23032303
for _, hf := range regularFields {
2304-
key := http.CanonicalHeaderKey(hf.Name)
2304+
key := canonicalHeader(hf.Name)
23052305
if key == "Trailer" {
23062306
t := res.Trailer
23072307
if t == nil {
23082308
t = make(http.Header)
23092309
res.Trailer = t
23102310
}
23112311
foreachHeaderElement(hf.Value, func(v string) {
2312-
t[http.CanonicalHeaderKey(v)] = nil
2312+
t[canonicalHeader(v)] = nil
23132313
})
23142314
} else {
23152315
vv := header[key]
@@ -2414,7 +2414,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr
24142414

24152415
trailer := make(http.Header)
24162416
for _, hf := range f.RegularFields() {
2417-
key := http.CanonicalHeaderKey(hf.Name)
2417+
key := canonicalHeader(hf.Name)
24182418
trailer[key] = append(trailer[key], hf.Value)
24192419
}
24202420
cs.trailer = trailer

0 commit comments

Comments
 (0)