@@ -13,6 +13,7 @@ import (
13
13
"compress/zlib"
14
14
"context"
15
15
"crypto/tls"
16
+ "crypto/x509"
16
17
"encoding/json"
17
18
"errors"
18
19
"fmt"
@@ -7303,3 +7304,71 @@ func testServerReadAfterHandlerAbort100Continue(t *testing.T, mode testMode) {
7303
7304
readyc <- struct {}{} // server starts reading from the request body
7304
7305
readyc <- struct {}{} // server finishes reading from the request body
7305
7306
}
7307
+
7308
+ // Issue #72100: Verify that we don't modify the caller's TLS.Config.NextProtos slice.
7309
+ func TestServerTLSNextProtos (t * testing.T ) {
7310
+ run (t , testServerTLSNextProtos , []testMode {https1Mode , http2Mode })
7311
+ }
7312
+ func testServerTLSNextProtos (t * testing.T , mode testMode ) {
7313
+ CondSkipHTTP2 (t )
7314
+
7315
+ cert , err := tls .X509KeyPair (testcert .LocalhostCert , testcert .LocalhostKey )
7316
+ if err != nil {
7317
+ t .Fatal (err )
7318
+ }
7319
+ leafCert , err := x509 .ParseCertificate (cert .Certificate [0 ])
7320
+ if err != nil {
7321
+ t .Fatal (err )
7322
+ }
7323
+ certpool := x509 .NewCertPool ()
7324
+ certpool .AddCert (leafCert )
7325
+
7326
+ protos := new (Protocols )
7327
+ switch mode {
7328
+ case https1Mode :
7329
+ protos .SetHTTP1 (true )
7330
+ case http2Mode :
7331
+ protos .SetHTTP2 (true )
7332
+ }
7333
+
7334
+ wantNextProtos := []string {"http/1.1" , "h2" , "other" }
7335
+ nextProtos := slices .Clone (wantNextProtos )
7336
+
7337
+ // We don't use httptest here because it overrides the tls.Config.
7338
+ srv := & Server {
7339
+ TLSConfig : & tls.Config {
7340
+ Certificates : []tls.Certificate {cert },
7341
+ NextProtos : nextProtos ,
7342
+ },
7343
+ Handler : HandlerFunc (func (w ResponseWriter , req * Request ) {}),
7344
+ Protocols : protos ,
7345
+ }
7346
+ tr := & Transport {
7347
+ TLSClientConfig : & tls.Config {
7348
+ RootCAs : certpool ,
7349
+ NextProtos : nextProtos ,
7350
+ },
7351
+ Protocols : protos ,
7352
+ }
7353
+
7354
+ listener := newLocalListener (t )
7355
+ srvc := make (chan error , 1 )
7356
+ go func () {
7357
+ srvc <- srv .ServeTLS (listener , "" , "" )
7358
+ }()
7359
+ t .Cleanup (func () {
7360
+ srv .Close ()
7361
+ <- srvc
7362
+ })
7363
+
7364
+ client := & Client {Transport : tr }
7365
+ resp , err := client .Get ("https://" + listener .Addr ().String ())
7366
+ if err != nil {
7367
+ t .Fatal (err )
7368
+ }
7369
+ resp .Body .Close ()
7370
+
7371
+ if ! slices .Equal (nextProtos , wantNextProtos ) {
7372
+ t .Fatalf ("after running test: original NextProtos slice = %v, want %v" , nextProtos , wantNextProtos )
7373
+ }
7374
+ }
0 commit comments