-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathserve.go
127 lines (104 loc) · 3.21 KB
/
serve.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package cmd
import (
"crypto/tls"
"fmt"
"io"
"log"
"mime"
"net"
"net/http"
"strings"
"github.com/philips/grpc-gateway-example/pkg/ui/data/swagger"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/philips/go-bindata-assetfs"
"github.com/spf13/cobra"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
pb "github.com/philips/grpc-gateway-example/echopb"
)
// serveCmd represents the serve command
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Launches the example webserver on https://localhost:10000",
Run: func(cmd *cobra.Command, args []string) {
serve()
},
}
func init() {
RootCmd.AddCommand(serveCmd)
}
type myService struct{}
func (m *myService) Echo(c context.Context, s *pb.EchoMessage) (*pb.EchoMessage, error) {
fmt.Printf("rpc request Echo(%q)\n", s.Value)
return s, nil
}
func newServer() *myService {
return new(myService)
}
// grpcHandlerFunc returns an http.Handler that delegates to grpcServer on incoming gRPC
// connections or otherHandler otherwise. Copied from cockroachdb.
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO(tamird): point to merged gRPC code rather than a PR.
// This is a partial recreation of gRPC's internal checks https://github.com/grpc/grpc-go/pull/514/files#diff-95e9a25b738459a2d3030e1e6fa2a718R61
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
})
}
func serveSwagger(mux *http.ServeMux) {
mime.AddExtensionType(".svg", "image/svg+xml")
// Expose files in third_party/swagger-ui/ on <host>/swagger-ui
fileServer := http.FileServer(&assetfs.AssetFS{
Asset: swagger.Asset,
AssetDir: swagger.AssetDir,
Prefix: "third_party/swagger-ui",
})
prefix := "/swagger-ui/"
mux.Handle(prefix, http.StripPrefix(prefix, fileServer))
}
func serve() {
opts := []grpc.ServerOption{
grpc.Creds(credentials.NewClientTLSFromCert(demoCertPool, "localhost:10000"))}
grpcServer := grpc.NewServer(opts...)
pb.RegisterEchoServiceServer(grpcServer, newServer())
ctx := context.Background()
dcreds := credentials.NewTLS(&tls.Config{
ServerName: demoAddr,
RootCAs: demoCertPool,
})
dopts := []grpc.DialOption{grpc.WithTransportCredentials(dcreds)}
mux := http.NewServeMux()
mux.HandleFunc("/swagger.json", func(w http.ResponseWriter, req *http.Request) {
io.Copy(w, strings.NewReader(pb.Swagger))
})
gwmux := runtime.NewServeMux()
err := pb.RegisterEchoServiceHandlerFromEndpoint(ctx, gwmux, demoAddr, dopts)
if err != nil {
fmt.Printf("serve: %v\n", err)
return
}
mux.Handle("/", gwmux)
serveSwagger(mux)
conn, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
panic(err)
}
srv := &http.Server{
Addr: demoAddr,
Handler: grpcHandlerFunc(grpcServer, mux),
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{*demoKeyPair},
NextProtos: []string{"h2"},
},
}
fmt.Printf("grpc on port: %d\n", port)
err = srv.Serve(tls.NewListener(conn, srv.TLSConfig))
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
return
}