github.com/cloudwego/hertz@v0.9.3/pkg/app/client/option.go (about)

     1  /*
     2   * Copyright 2022 CloudWeGo Authors
     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  package client
    18  
    19  import (
    20  	"crypto/tls"
    21  	"time"
    22  
    23  	"github.com/cloudwego/hertz/pkg/app/client/retry"
    24  	"github.com/cloudwego/hertz/pkg/common/config"
    25  	"github.com/cloudwego/hertz/pkg/network"
    26  	"github.com/cloudwego/hertz/pkg/network/dialer"
    27  	"github.com/cloudwego/hertz/pkg/network/standard"
    28  	"github.com/cloudwego/hertz/pkg/protocol/consts"
    29  )
    30  
    31  // WithDialTimeout sets dial timeout.
    32  func WithDialTimeout(dialTimeout time.Duration) config.ClientOption {
    33  	return config.ClientOption{F: func(o *config.ClientOptions) {
    34  		o.DialTimeout = dialTimeout
    35  	}}
    36  }
    37  
    38  // WithMaxConnsPerHost sets maximum number of connections per host which may be established.
    39  func WithMaxConnsPerHost(mc int) config.ClientOption {
    40  	return config.ClientOption{F: func(o *config.ClientOptions) {
    41  		o.MaxConnsPerHost = mc
    42  	}}
    43  }
    44  
    45  // WithMaxIdleConnDuration sets max idle connection duration, idle keep-alive connections are closed after this duration.
    46  func WithMaxIdleConnDuration(t time.Duration) config.ClientOption {
    47  	return config.ClientOption{F: func(o *config.ClientOptions) {
    48  		o.MaxIdleConnDuration = t
    49  	}}
    50  }
    51  
    52  // WithMaxConnDuration sets max connection duration, keep-alive connections are closed after this duration.
    53  func WithMaxConnDuration(t time.Duration) config.ClientOption {
    54  	return config.ClientOption{F: func(o *config.ClientOptions) {
    55  		o.MaxConnDuration = t
    56  	}}
    57  }
    58  
    59  // WithMaxConnWaitTimeout sets maximum duration for waiting for a free connection.
    60  func WithMaxConnWaitTimeout(t time.Duration) config.ClientOption {
    61  	return config.ClientOption{F: func(o *config.ClientOptions) {
    62  		o.MaxConnWaitTimeout = t
    63  	}}
    64  }
    65  
    66  // WithKeepAlive determines whether use keep-alive connection.
    67  func WithKeepAlive(b bool) config.ClientOption {
    68  	return config.ClientOption{F: func(o *config.ClientOptions) {
    69  		o.KeepAlive = b
    70  	}}
    71  }
    72  
    73  // WithClientReadTimeout sets maximum duration for full response reading (including body).
    74  func WithClientReadTimeout(t time.Duration) config.ClientOption {
    75  	return config.ClientOption{F: func(o *config.ClientOptions) {
    76  		o.ReadTimeout = t
    77  	}}
    78  }
    79  
    80  // WithTLSConfig sets tlsConfig to create a tls connection.
    81  func WithTLSConfig(cfg *tls.Config) config.ClientOption {
    82  	return config.ClientOption{F: func(o *config.ClientOptions) {
    83  		o.TLSConfig = cfg
    84  		o.Dialer = standard.NewDialer()
    85  	}}
    86  }
    87  
    88  // WithDialer sets the specific dialer.
    89  func WithDialer(d network.Dialer) config.ClientOption {
    90  	return config.ClientOption{F: func(o *config.ClientOptions) {
    91  		o.Dialer = d
    92  	}}
    93  }
    94  
    95  // WithResponseBodyStream is used to determine whether read body in stream or not.
    96  func WithResponseBodyStream(b bool) config.ClientOption {
    97  	return config.ClientOption{F: func(o *config.ClientOptions) {
    98  		o.ResponseBodyStream = b
    99  	}}
   100  }
   101  
   102  // WithHostClientConfigHook is used to set the function hook for re-configure the host client.
   103  func WithHostClientConfigHook(h func(hc interface{}) error) config.ClientOption {
   104  	return config.ClientOption{F: func(o *config.ClientOptions) {
   105  		o.HostClientConfigHook = h
   106  	}}
   107  }
   108  
   109  // WithDisableHeaderNamesNormalizing is used to set whether disable header names normalizing.
   110  func WithDisableHeaderNamesNormalizing(disable bool) config.ClientOption {
   111  	return config.ClientOption{F: func(o *config.ClientOptions) {
   112  		o.DisableHeaderNamesNormalizing = disable
   113  	}}
   114  }
   115  
   116  // WithName sets client name which used in User-Agent Header.
   117  func WithName(name string) config.ClientOption {
   118  	return config.ClientOption{F: func(o *config.ClientOptions) {
   119  		o.Name = name
   120  	}}
   121  }
   122  
   123  // WithNoDefaultUserAgentHeader sets whether no default User-Agent header.
   124  func WithNoDefaultUserAgentHeader(isNoDefaultUserAgentHeader bool) config.ClientOption {
   125  	return config.ClientOption{F: func(o *config.ClientOptions) {
   126  		o.NoDefaultUserAgentHeader = isNoDefaultUserAgentHeader
   127  	}}
   128  }
   129  
   130  // WithDisablePathNormalizing sets whether disable path normalizing.
   131  func WithDisablePathNormalizing(isDisablePathNormalizing bool) config.ClientOption {
   132  	return config.ClientOption{F: func(o *config.ClientOptions) {
   133  		o.DisablePathNormalizing = isDisablePathNormalizing
   134  	}}
   135  }
   136  
   137  func WithRetryConfig(opts ...retry.Option) config.ClientOption {
   138  	retryCfg := &retry.Config{
   139  		MaxAttemptTimes: consts.DefaultMaxRetryTimes,
   140  		Delay:           1 * time.Millisecond,
   141  		MaxDelay:        100 * time.Millisecond,
   142  		MaxJitter:       20 * time.Millisecond,
   143  		DelayPolicy:     retry.CombineDelay(retry.DefaultDelayPolicy),
   144  	}
   145  	retryCfg.Apply(opts)
   146  
   147  	return config.ClientOption{F: func(o *config.ClientOptions) {
   148  		o.RetryConfig = retryCfg
   149  	}}
   150  }
   151  
   152  // WithWriteTimeout sets write timeout.
   153  func WithWriteTimeout(t time.Duration) config.ClientOption {
   154  	return config.ClientOption{F: func(o *config.ClientOptions) {
   155  		o.WriteTimeout = t
   156  	}}
   157  }
   158  
   159  // WithConnStateObserve sets the connection state observation function.
   160  // The first param is used to set hostclient state func.
   161  // The second param is used to set observation interval, default value is 5 seconds.
   162  // Warn: Do not start go routine in HostClientStateFunc.
   163  func WithConnStateObserve(hs config.HostClientStateFunc, interval ...time.Duration) config.ClientOption {
   164  	return config.ClientOption{F: func(o *config.ClientOptions) {
   165  		o.HostClientStateObserve = hs
   166  		if len(interval) > 0 {
   167  			o.ObservationInterval = interval[0]
   168  		}
   169  	}}
   170  }
   171  
   172  // WithDialFunc is used to set dialer function.
   173  // Note: WithDialFunc will overwrite custom dialer.
   174  func WithDialFunc(f network.DialFunc, dialers ...network.Dialer) config.ClientOption {
   175  	return config.ClientOption{F: func(o *config.ClientOptions) {
   176  		d := dialer.DefaultDialer()
   177  		if len(dialers) != 0 {
   178  			d = dialers[0]
   179  		}
   180  		o.Dialer = newCustomDialerWithDialFunc(d, f)
   181  	}}
   182  }
   183  
   184  // customDialer set customDialerFunc and params to set dailFunc
   185  type customDialer struct {
   186  	network.Dialer
   187  	dialFunc network.DialFunc
   188  }
   189  
   190  func (m *customDialer) DialConnection(network, address string, timeout time.Duration, tlsConfig *tls.Config) (conn network.Conn, err error) {
   191  	if m.dialFunc != nil {
   192  		return m.dialFunc(address)
   193  	}
   194  	return m.Dialer.DialConnection(network, address, timeout, tlsConfig)
   195  }
   196  
   197  func newCustomDialerWithDialFunc(dialer network.Dialer, dialFunc network.DialFunc) network.Dialer {
   198  	return &customDialer{
   199  		Dialer:   dialer,
   200  		dialFunc: dialFunc,
   201  	}
   202  }