drpc
drpc copied to clipboard
http based drpc client
i'm try to create api gateway that support http rest, grpc and drpc on the same port
i'm create grpc server, drpc http handler, and plain http handler and use the in http2 server as handler.
plain http and grpc works fine, but drpc request does not goes to http2 server =( does it possible to get this worked with native drpc clients ?
gsrv := grpc.NewServer(grpc.UnknownServiceHandler(h.ServeGRPC))
comboHandler := newComboMux(h, gsrv, drpchttp.New(h))
http2Server := &http2.Server{}
hs := &http.Server{Handler: h2c.NewHandler(comboHandler, http2Server)}
func (h *Handler) ServeDRPC(stream drpc.Stream, rpc string) error {
ctx := stream.Context()
logger.Infof(ctx, "drpc: %#+v", rpc)
return nil
}
func (h *Handler) HandleRPC(stream drpc.Stream, rpc string) error {
return h.ServeDRPC(stream, rpc)
}
func newComboMux(httph http.Handler, grpch http.Handler, drpch http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ProtoMajor == 2 {
ct := r.Header.Get("content-type")
switch {
case strings.HasPrefix(ct, "application/grpc"):
grpch.ServeHTTP(w, r)
return
case strings.HasPrefix(ct, "application/drpc"):
drpch.ServeHTTP(w, r)
return
}
}
httph.ServeHTTP(w, r)
})
}
as i understand that drpc does not send any http2 headers by default so its not possible to determine how to handle this request in this combo server ? does it possible to handle native drpc client without drpcmigrate client helper that sends special bytes before data?
What do you mean by "native drpc client?" Since it's going through http, something has to exist to map the http request into a drpc stream, which is a drpchttp.Protocol with the built in ones defined here. There's no built in way for a drpc client to wrap a request into an http request, though.
Let me explain - with grpc i can handle incoming grpc connections to http2 server. Parse incoming stream data and get service/method and payload. With drpc - i cant handle simple drpc connection created with tcp connect and drpc.New()
how can i create drpc connection to http based drpc server that can switch protocol by content-type header ?
may be i need to create drpc.Transport that utilise http1/http2 connection?
can you add to drpchttp transport that uses http connection for drpc?
One option might be to use a websocket based transport like https://pkg.go.dev/go.bryk.io/pkg/net/drpc/ws
This will be a tracking issue to extend the drpchttp package to include a client that wraps an http.Transport or something. It may be limited to unitary streams. It'd be cool if it worked against twirp or grpc-web servers as well as the basic drpchttp server.