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  }