blob: 3acf9b1ed0e5b92f046b1213e145908cf03b2da6 [file] [log] [blame]
Serge Bazanski3fd70d82018-10-14 08:12:46 -07001package mirko
2
3import (
4 "flag"
5 "fmt"
6 "net"
7 "net/http"
8 "time"
9
10 "code.hackerspace.pl/q3k/hspki"
11 "github.com/golang/glog"
12 "github.com/q3k/statusz"
13 "golang.org/x/net/trace"
14 "google.golang.org/grpc"
15 "google.golang.org/grpc/reflection"
16)
17
18var (
19 flagListenAddress string
20 flagDebugAddress string
21)
22
23func init() {
24 flag.StringVar(&flagListenAddress, "listen_address", "127.0.0.1:42000", "gRPC listen address")
25 flag.StringVar(&flagDebugAddress, "debug_address", "127.0.0.1:42001", "HTTP debug/status listen address")
26}
27
28type Mirko struct {
29 grpcListen net.Listener
30 grpcServer *grpc.Server
31 httpListen net.Listener
32 httpServer *http.Server
33 httpMux *http.ServeMux
34}
35
36func New() *Mirko {
37 return &Mirko{}
38}
39
40func (m *Mirko) Listen() error {
41 grpc.EnableTracing = true
42 grpcLis, err := net.Listen("tcp", flagListenAddress)
43 if err != nil {
44 return fmt.Errorf("net.Listen: %v", err)
45 }
46 m.grpcListen = grpcLis
47 m.grpcServer = grpc.NewServer(hspki.WithServerHSPKI()...)
48 reflection.Register(m.grpcServer)
49
50 httpLis, err := net.Listen("tcp", flagDebugAddress)
51 if err != nil {
52 return fmt.Errorf("net.Listen: %v", err)
53 }
54
55 m.httpMux = http.NewServeMux()
56 // Canonical URLs
57 m.httpMux.HandleFunc("/debug/status", statusz.StatusHandler)
58 m.httpMux.HandleFunc("/debug/requests", trace.Traces)
59
60 // -z legacy URLs
61 m.httpMux.HandleFunc("/statusz", func(w http.ResponseWriter, r *http.Request) {
62 http.Redirect(w, r, "/debug/status", http.StatusSeeOther)
63 })
64 m.httpMux.HandleFunc("/rpcz", func(w http.ResponseWriter, r *http.Request) {
65 http.Redirect(w, r, "/debug/requests", http.StatusSeeOther)
66 })
67 m.httpMux.HandleFunc("/requestz", func(w http.ResponseWriter, r *http.Request) {
68 http.Redirect(w, r, "/debug/requests", http.StatusSeeOther)
69 })
70
71 // root redirect
72 m.httpMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
73 http.Redirect(w, r, "/debug/status", http.StatusSeeOther)
74 })
75
76 m.httpListen = httpLis
77 m.httpServer = &http.Server{
78 Addr: flagDebugAddress,
79 Handler: m.httpMux,
80 }
81
82 return nil
83}
84
85func (m *Mirko) GRPC() *grpc.Server {
86 if m.grpcServer == nil {
87 panic("GRPC() called before Listen()")
88 }
89 return m.grpcServer
90}
91
92func (m *Mirko) HTTPMux() *http.ServeMux {
93 if m.httpMux == nil {
94 panic("HTTPMux() called before Listen()")
95 }
96 return m.httpMux
97}
98
99func (m *Mirko) Serve() error {
100 errs := make(chan error, 1)
101 go func() {
102 if err := m.grpcServer.Serve(m.grpcListen); err != nil {
103 errs <- err
104 }
105 }()
106 go func() {
107 if err := m.httpServer.Serve(m.httpListen); err != nil {
108 errs <- err
109 }
110 }()
111
112 ticker := time.NewTicker(1 * time.Second)
113 select {
114 case <-ticker.C:
115 glog.Infof("gRPC listening on %s", flagListenAddress)
116 glog.Infof("HTTP listening on %s", flagDebugAddress)
117 return nil
118 case err := <-errs:
119 return err
120 }
121}