lib/http: replace deprecated h2c.NewHandler with http.Server.Protocols

The golang.org/x/net/http2/h2c package was deprecated in v0.54.0 in
favour of setting the http.Server Protocols field to enable unencrypted
HTTP/2.

This replaces the h2c.NewHandler wrapping added in e863f751f with
http.Server.Protocols, which is supported by the standard library
since Go 1.24.

Note that the stdlib only supports HTTP/2 prior-knowledge on cleartext
connections, not HTTP/1.1 Upgrade: h2c negotiation. In practice clients
use prior-knowledge or require TLS, so this should not affect users.
This commit is contained in:
Nick Craig-Wood
2026-05-22 12:20:24 +01:00
parent a03070c960
commit ad8a108453
+18 -17
View File
@@ -23,8 +23,6 @@ import (
"github.com/rclone/rclone/lib/atexit" "github.com/rclone/rclone/lib/atexit"
sdActivation "github.com/rclone/rclone/lib/sdactivation" sdActivation "github.com/rclone/rclone/lib/sdactivation"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
) )
// Help returns text describing the http server to add to the command // Help returns text describing the http server to add to the command
@@ -291,26 +289,29 @@ func newInstance(ctx context.Context, s *Server, listener net.Listener, tlsCfg *
listener = tls.NewListener(listener, tlsCfg) listener = tls.NewListener(listener, tlsCfg)
} }
var handler http.Handler = s.mux httpServer := &http.Server{
Handler: s.mux,
ReadTimeout: time.Duration(s.cfg.ServerReadTimeout),
WriteTimeout: time.Duration(s.cfg.ServerWriteTimeout),
MaxHeaderBytes: s.cfg.MaxHeaderBytes,
ReadHeaderTimeout: 10 * time.Second, // time to send the headers
IdleTimeout: 60 * time.Second, // time to keep idle connections open
TLSConfig: tlsCfg,
BaseContext: NewBaseContext(ctx, url),
}
// Enable h2c (HTTP/2 cleartext) for non-TLS listeners // Enable h2c (HTTP/2 cleartext) for non-TLS listeners
if tlsCfg == nil { if tlsCfg == nil {
h2s := &http2.Server{} protocols := new(http.Protocols)
handler = h2c.NewHandler(s.mux, h2s) protocols.SetHTTP1(true)
protocols.SetUnencryptedHTTP2(true)
httpServer.Protocols = protocols
} }
return &instance{ return &instance{
url: url, url: url,
listener: listener, listener: listener,
httpServer: &http.Server{ httpServer: httpServer,
Handler: handler,
ReadTimeout: time.Duration(s.cfg.ServerReadTimeout),
WriteTimeout: time.Duration(s.cfg.ServerWriteTimeout),
MaxHeaderBytes: s.cfg.MaxHeaderBytes,
ReadHeaderTimeout: 10 * time.Second, // time to send the headers
IdleTimeout: 60 * time.Second, // time to keep idle connections open
TLSConfig: tlsCfg,
BaseContext: NewBaseContext(ctx, url),
},
} }
} }