github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/transports/standard/transport.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package standard 19 20 import ( 21 "fmt" 22 "github.com/aacfactory/errors" 23 "github.com/aacfactory/fns/context" 24 "github.com/aacfactory/fns/transports" 25 ) 26 27 const ( 28 transportName = "standard" 29 ) 30 31 type Config struct { 32 MaxRequestHeaderSize string `json:"maxRequestHeaderSize"` 33 MaxRequestBodySize string `json:"maxRequestBodySize"` 34 ReadTimeout string `json:"readTimeout"` 35 ReadHeaderTimeout string `json:"readHeaderTimeout"` 36 WriteTimeout string `json:"writeTimeout"` 37 IdleTimeout string `json:"idleTimeout"` 38 Client *ClientConfig `json:"client"` 39 } 40 41 func (config *Config) ClientConfig() *ClientConfig { 42 if config.Client == nil { 43 return &ClientConfig{} 44 } 45 return config.Client 46 } 47 48 func New() transports.Transport { 49 return &Transport{} 50 } 51 52 type Transport struct { 53 server *Server 54 dialer *Dialer 55 } 56 57 func (tr *Transport) Name() (name string) { 58 name = transportName 59 return 60 } 61 62 func (tr *Transport) Construct(options transports.Options) (err error) { 63 // log 64 log := options.Log.With("transport", transportName) 65 // tls 66 tlsConfig, tlsConfigErr := options.Config.GetTLS() 67 if tlsConfigErr != nil { 68 err = errors.Warning("fns: standard transport construct failed").WithCause(tlsConfigErr).WithMeta("transport", transportName) 69 return 70 } 71 // handler 72 if options.Handler == nil { 73 err = errors.Warning("fns: standard transport construct failed").WithCause(fmt.Errorf("handler is nil")).WithMeta("transport", transportName) 74 return 75 } 76 77 // port 78 port, portErr := options.Config.GetPort() 79 if portErr != nil { 80 err = errors.Warning("fns: standard transport construct failed").WithCause(portErr).WithMeta("transport", transportName) 81 return 82 } 83 // config 84 optConfig, optConfigErr := options.Config.OptionsConfig() 85 if optConfigErr != nil { 86 err = errors.Warning("fns: standard transport construct failed").WithCause(optConfigErr).WithMeta("transport", transportName) 87 return 88 } 89 config := &Config{} 90 configErr := optConfig.As(config) 91 if configErr != nil { 92 err = errors.Warning("fns: standard transport construct failed").WithCause(configErr).WithMeta("transport", transportName) 93 return 94 } 95 // server 96 srv, srvErr := newServer(log, port, tlsConfig, config, options.Handler) 97 if srvErr != nil { 98 err = errors.Warning("fns: standard transport construct failed").WithCause(srvErr).WithMeta("transport", transportName) 99 return 100 } 101 tr.server = srv 102 103 // dialer 104 clientConfig := config.ClientConfig() 105 if tlsConfig != nil { 106 cliTLS, dialer := tlsConfig.Client() 107 clientConfig.TLSConfig = cliTLS 108 if dialer != nil { 109 clientConfig.TLSDialer = dialer 110 } 111 } 112 dialer, dialerErr := NewDialer(clientConfig) 113 if dialerErr != nil { 114 err = errors.Warning("http: standard transport construct failed").WithCause(dialerErr) 115 return 116 } 117 tr.dialer = dialer 118 return 119 } 120 121 func (tr *Transport) Dial(address []byte) (client transports.Client, err error) { 122 client, err = tr.dialer.Dial(address) 123 return 124 } 125 126 func (tr *Transport) Port() (port int) { 127 port = tr.server.port 128 return 129 } 130 131 func (tr *Transport) ListenAndServe() (err error) { 132 err = tr.server.ListenAndServe() 133 return 134 } 135 136 func (tr *Transport) Shutdown(ctx context.Context) { 137 tr.dialer.Close() 138 _ = tr.server.Shutdown(ctx) 139 return 140 }