diff --git a/src/net/http/internal/http2/server.go b/src/net/http/internal/http2/server.go
index aed43b2..827d217 100644
--- a/src/net/http/internal/http2/server.go
+++ b/src/net/http/internal/http2/server.go
@@ -2569,6 +2569,13 @@
if !rws.wroteHeader {
rws.writeHeader(200)
}
+ defer func() {
+ if rws.snapHeader != nil {
+ clear(rws.snapHeader)
+ headerPool.Put(rws.snapHeader)
+ rws.snapHeader = nil
+ }
+ }()
if rws.handlerDone {
rws.promoteUndeclaredTrailers()
@@ -2898,8 +2905,12 @@
}
}
+var headerPool = sync.Pool{
+ New: func() any { return make(Header) },
+}
+
func cloneHeader(h Header) Header {
- h2 := make(Header, len(h))
+ h2 := headerPool.Get().(Header)
for k, vv := range h {
vv2 := make([]string, len(vv))
copy(vv2, vv)
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
index 37b8883..eafe7da 100644
--- a/src/net/http/request_test.go
+++ b/src/net/http/request_test.go
@@ -1510,6 +1510,39 @@
}
}
+func BenchmarkSnapHeaderH2(b *testing.B) {
+ handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
+ defer req.Body.Close()
+ rw.Header().Add("Cache-Control", "no-cache")
+ rw.Header().Add("Access-Control-Allow-Origin", "example.com")
+ rw.Header().Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
+ rw.Header().Add("Access-Control-Allow-Headers", "X-Token")
+ rw.Header().Add("X-Request-ID", "")
+ rw.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'")
+ rw.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ rw.Header().Set("X-Content-Type-Options", "nosniff")
+ rw.Header().Set("X-Frame-Options", "SAMEORIGIN")
+ rw.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
+
+ io.WriteString(rw, "response")
+ })
+
+ cst := newClientServerTest(b, http2Mode, handler).ts
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ req, err := NewRequest("GET", cst.URL, nil)
+ if err != nil {
+ b.Fatal(err)
+ }
+ res, err := cst.Client().Do(req)
+ if err != nil {
+ b.Fatalf("Failed to make request to backend: %v", err)
+ }
+ res.Body.Close()
+ }
+}
+
func TestErrNotSupported(t *testing.T) {
if !errors.Is(ErrNotSupported, errors.ErrUnsupported) {
t.Error("errors.Is(ErrNotSupported, errors.ErrUnsupported) failed")