From ad8a108453f3ce983fb6c3675ced694ff6bc3b53 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 22 May 2026 12:08:35 +0100 Subject: [PATCH] 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. --- lib/http/server.go | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/http/server.go b/lib/http/server.go index b6d2c6bd5..f94cd8a5e 100644 --- a/lib/http/server.go +++ b/lib/http/server.go @@ -23,8 +23,6 @@ import ( "github.com/rclone/rclone/lib/atexit" sdActivation "github.com/rclone/rclone/lib/sdactivation" "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 @@ -291,26 +289,29 @@ func newInstance(ctx context.Context, s *Server, listener net.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 if tlsCfg == nil { - h2s := &http2.Server{} - handler = h2c.NewHandler(s.mux, h2s) + protocols := new(http.Protocols) + protocols.SetHTTP1(true) + protocols.SetUnencryptedHTTP2(true) + httpServer.Protocols = protocols } return &instance{ - url: url, - listener: listener, - httpServer: &http.Server{ - 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), - }, + url: url, + listener: listener, + httpServer: httpServer, } }