Skip to content

Commit c65d39d

Browse files
committed
fix deprecated package
1 parent 3e822e7 commit c65d39d

1 file changed

Lines changed: 19 additions & 17 deletions

File tree

pkg/duplex/server.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import (
1515
"time"
1616

1717
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
18-
"golang.org/x/net/http2"
19-
"golang.org/x/net/http2/h2c"
2018
"google.golang.org/grpc"
2119

2220
"chainguard.dev/go-grpc-kit/pkg/interceptors/clientid"
@@ -25,15 +23,14 @@ import (
2523
)
2624

2725
// handler routes inbound requests to either the gRPC server or the gateway MUX
28-
// based on the request content type, served over h2c so gRPC works on a
29-
// cleartext port. Each request is counted while it runs, so Shutdown can wait
30-
// for in-flight requests to finish: the gRPC requests are served over hijacked
31-
// h2c connections that http.Server.Shutdown does not track, so counting them
32-
// here is the only way to know when they have drained.
26+
// based on the request content type, served over cleartext HTTP/2 (h2c) so gRPC
27+
// works on a cleartext port. Unencrypted HTTP/2 is enabled on the http.Server
28+
// via its Protocols field (see httpServerInstance). Each request is counted
29+
// while it runs, so Shutdown can wait for in-flight requests to finish.
3330
// See also, https://grpc-ecosystem.github.io/grpc-gateway/
3431
// This is based on: https://github.com/philips/grpc-gateway-example/issues/22#issuecomment-490733965
3532
func (d *Duplex) handler() http.Handler {
36-
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
33+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3734
d.inflight.add()
3835
defer d.inflight.done()
3936

@@ -43,7 +40,7 @@ func (d *Duplex) handler() http.Handler {
4340
}
4441

4542
d.MUX.ServeHTTP(w, r)
46-
}), &http2.Server{})
43+
})
4744
}
4845

4946
// allowedHeaders are HTTP headers that should be forwarded as gRPC metadata
@@ -160,9 +157,15 @@ func (d *Duplex) Serve(_ context.Context, listener net.Listener) error {
160157
// first use.
161158
func (d *Duplex) httpServerInstance() *http.Server {
162159
d.httpServerOnce.Do(func() {
160+
// Enable cleartext HTTP/2 (h2c) alongside HTTP/1 so gRPC works on the
161+
// cleartext port. This replaces the deprecated x/net/http2/h2c handler.
162+
protocols := new(http.Protocols)
163+
protocols.SetHTTP1(true)
164+
protocols.SetUnencryptedHTTP2(true)
163165
d.httpServer = &http.Server{
164166
Handler: d.handler(),
165167
ReadHeaderTimeout: 10 * time.Second,
168+
Protocols: protocols,
166169
}
167170
})
168171

@@ -178,10 +181,9 @@ func (d *Duplex) httpServerInstance() *http.Server {
178181
// context with a deadline to cap it, or a long-lived request will hold shutdown
179182
// open indefinitely.
180183
//
181-
// gRPC is served over h2c, whose connections http.Server.Shutdown does not
182-
// track once hijacked, so its return does not imply gRPC has drained; and
184+
// gRPC is served over cleartext HTTP/2 via a grpc.Server.ServeHTTP handler, and
183185
// grpc.Server.GracefulStop panics on a ServeHTTP-backed transport, so it cannot
184-
// drain them either. Shutdown therefore stops the listeners via the HTTP
186+
// drain those requests. Shutdown therefore stops the listeners via the HTTP
185187
// server, waits on its own in-flight counter for requests of both kinds to
186188
// finish, then stops the gRPC server with grpc.Server.Stop and closes the HTTP
187189
// server. Those final steps run on every path: after a clean drain they release
@@ -190,11 +192,11 @@ func (d *Duplex) httpServerInstance() *http.Server {
190192
func (d *Duplex) Shutdown(ctx context.Context) error {
191193
server := d.httpServerInstance()
192194

193-
// Stop accepting new connections and drain the gateway's tracked
194-
// connections. This does not wait for hijacked h2c (gRPC) connections, so
195-
// run it in the background while the in-flight counter is drained below. Its
196-
// error is dropped deliberately: the wait below reports the drain outcome,
197-
// and the Close below is the backstop.
195+
// Stop accepting new connections and drain the HTTP server's connections.
196+
// Run it in the background while the in-flight counter is drained below,
197+
// which is what reports the outcome for requests of both kinds. Its error is
198+
// dropped deliberately: the wait below reports the drain outcome, and the
199+
// Close below is the backstop.
198200
go func() { _ = server.Shutdown(ctx) }()
199201

200202
err := d.inflight.wait(ctx)

0 commit comments

Comments
 (0)