fork of https://github.com/sourcegraph/zoekt
1package grpcutil
2
3import (
4 "net/http"
5 "strings"
6
7 "golang.org/x/net/http2"
8 "golang.org/x/net/http2/h2c"
9 "google.golang.org/grpc"
10)
11
12// SplitMethodName splits a full gRPC method name (e.g. "/package.service/method") in to its individual components (service, method)
13//
14// Copied from github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go
15func SplitMethodName(fullMethod string) (string, string) {
16 fullMethod = strings.TrimPrefix(fullMethod, "/") // remove leading slash
17 if i := strings.Index(fullMethod, "/"); i >= 0 {
18 return fullMethod[:i], fullMethod[i+1:]
19 }
20 return "unknown", "unknown"
21}
22
23// MultiplexGRPC takes a gRPC server and a plain HTTP handler and multiplexes the
24// request handling. Any requests that declare themselves as gRPC requests are routed
25// to the gRPC server, all others are routed to the httpHandler.
26func MultiplexGRPC(grpcServer *grpc.Server, httpHandler http.Handler) http.Handler {
27 newHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28 if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
29 grpcServer.ServeHTTP(w, r)
30 } else {
31 httpHandler.ServeHTTP(w, r)
32 }
33 })
34
35 // Until we enable TLS, we need to fall back to the h2c protocol, which is
36 // basically HTTP2 without TLS. The standard library does not implement the
37 // h2s protocol, so this hijacks h2s requests and handles them correctly.
38 return h2c.NewHandler(newHandler, &http2.Server{})
39}