github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/api/server/router/grpc/grpc_routes.go (about) 1 package grpc // import "github.com/docker/docker/api/server/router/grpc" 2 3 import ( 4 "context" 5 "net/http" 6 7 "github.com/pkg/errors" 8 "golang.org/x/net/http2" 9 ) 10 11 func (gr *grpcRouter) serveGRPC(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 12 h, ok := w.(http.Hijacker) 13 if !ok { 14 return errors.New("handler does not support hijack") 15 } 16 proto := r.Header.Get("Upgrade") 17 if proto == "" { 18 return errors.New("no upgrade proto in request") 19 } 20 if proto != "h2c" { 21 return errors.Errorf("protocol %s not supported", proto) 22 } 23 24 conn, _, err := h.Hijack() 25 if err != nil { 26 return err 27 } 28 resp := &http.Response{ 29 StatusCode: http.StatusSwitchingProtocols, 30 ProtoMajor: 1, 31 ProtoMinor: 1, 32 Header: http.Header{}, 33 } 34 resp.Header.Set("Connection", "Upgrade") 35 resp.Header.Set("Upgrade", proto) 36 37 // set raw mode 38 conn.Write([]byte{}) 39 resp.Write(conn) 40 41 // https://godoc.org/golang.org/x/net/http2#Server.ServeConn 42 // TODO: is it a problem that conn has already been written to? 43 gr.h2Server.ServeConn(conn, &http2.ServeConnOpts{Handler: gr.grpcServer}) 44 return nil 45 }