github.com/gofunct/common@v0.0.0-20190131174352-fd058c7fbf22/pkg/transport/config/config.go (about) 1 package config 2 3 import ( 4 "crypto/tls" 5 "github.com/gofunct/common/pkg/transport/api" 6 "github.com/gofunct/common/pkg/transport/middleware" 7 "net" 8 "net/http" 9 "os" 10 "path/filepath" 11 pkg_runtime "runtime" 12 "time" 13 14 "github.com/grpc-ecosystem/go-grpc-middleware" 15 "github.com/grpc-ecosystem/grpc-gateway/runtime" 16 "github.com/pkg/errors" 17 "google.golang.org/grpc" 18 ) 19 20 // Config contains configurations of gRPC and Gateway server. 21 type Config struct { 22 GrpcAddr *Address 23 GrpcInternalAddr *Address 24 GatewayAddr *Address 25 Servers []api.Server 26 GrpcServerUnaryInterceptors []grpc.UnaryServerInterceptor 27 GrpcServerStreamInterceptors []grpc.StreamServerInterceptor 28 GatewayServerUnaryInterceptors []grpc.UnaryClientInterceptor 29 GatewayServerStreamInterceptors []grpc.StreamClientInterceptor 30 GrpcServerOption []grpc.ServerOption 31 GatewayDialOption []grpc.DialOption 32 GatewayMuxOptions []runtime.ServeMuxOption 33 GatewayServerConfig *HTTPServerConfig 34 MaxConcurrentStreams uint32 35 GatewayServerMiddlewares []middleware.HTTPServerMiddleware 36 } 37 38 func CreateDefaultConfig() *Config { 39 config := &Config{ 40 GrpcInternalAddr: &Address{ 41 Network: "unix", 42 Addr: "tmp/server.sock", 43 }, 44 GatewayAddr: &Address{ 45 Network: "tcp", 46 Addr: ":3000", 47 }, 48 GatewayServerConfig: &HTTPServerConfig{ 49 ReadTimeout: 8 * time.Second, 50 WriteTimeout: 8 * time.Second, 51 IdleTimeout: 2 * time.Minute, 52 }, 53 MaxConcurrentStreams: 1000, 54 } 55 if pkg_runtime.GOOS == "windows" { 56 config.GrpcInternalAddr = &Address{ 57 Network: "tcp", 58 Addr: ":5050", 59 } 60 } 61 return config 62 } 63 64 // Address represents a network end point address. 65 type Address struct { 66 Network string 67 Addr string 68 } 69 70 func (a *Address) CreateListener() (net.Listener, error) { 71 if a.Network == "unix" { 72 dir := filepath.Dir(a.Addr) 73 f, err := os.Stat(dir) 74 if err != nil { 75 if err = os.MkdirAll(dir, 0755); err != nil { 76 return nil, errors.Wrap(err, "failed to create the directory") 77 } 78 } else if !f.IsDir() { 79 return nil, errors.Errorf("file %q already exists", dir) 80 } 81 } 82 lis, err := net.Listen(a.Network, a.Addr) 83 if err != nil { 84 return nil, errors.Wrapf(err, "failed to listen %s %s", a.Network, a.Addr) 85 } 86 return lis, nil 87 } 88 89 type HTTPServerConfig struct { 90 TLSConfig *tls.Config 91 ReadTimeout time.Duration 92 ReadHeaderTimeout time.Duration 93 WriteTimeout time.Duration 94 IdleTimeout time.Duration 95 MaxHeaderBytes int 96 TLSNextProto map[string]func(*http.Server, *tls.Conn, http.Handler) 97 ConnState func(net.Conn, http.ConnState) 98 } 99 100 func (c *HTTPServerConfig) ApplyTo(s *http.Server) { 101 s.TLSConfig = c.TLSConfig 102 s.ReadTimeout = c.ReadTimeout 103 s.ReadHeaderTimeout = c.ReadHeaderTimeout 104 s.WriteTimeout = c.WriteTimeout 105 s.IdleTimeout = c.IdleTimeout 106 s.MaxHeaderBytes = c.MaxHeaderBytes 107 s.TLSNextProto = c.TLSNextProto 108 s.ConnState = c.ConnState 109 } 110 111 func (c *Config) ServerOptions() []grpc.ServerOption { 112 return append( 113 []grpc.ServerOption{ 114 grpc_middleware.WithUnaryServerChain(c.GrpcServerUnaryInterceptors...), 115 grpc_middleware.WithStreamServerChain(c.GrpcServerStreamInterceptors...), 116 grpc.MaxConcurrentStreams(c.MaxConcurrentStreams), 117 }, 118 c.GrpcServerOption..., 119 ) 120 } 121 122 func (c *Config) ClientOptions() []grpc.DialOption { 123 return append( 124 []grpc.DialOption{ 125 grpc.WithInsecure(), 126 grpc.WithDialer(func(a string, t time.Duration) (net.Conn, error) { 127 return net.Dial(c.GrpcInternalAddr.Network, a) 128 }), 129 grpc.WithUnaryInterceptor( 130 grpc_middleware.ChainUnaryClient(c.GatewayServerUnaryInterceptors...), 131 ), 132 grpc.WithStreamInterceptor( 133 grpc_middleware.ChainStreamClient(c.GatewayServerStreamInterceptors...), 134 ), 135 }, 136 c.GatewayDialOption..., 137 ) 138 }