github.com/cloudwego/hertz@v0.9.3/pkg/app/server/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 server
    18  
    19  import (
    20  	"context"
    21  	"crypto/tls"
    22  	"net"
    23  	"strings"
    24  	"time"
    25  
    26  	"github.com/cloudwego/hertz/pkg/app/server/binding"
    27  	"github.com/cloudwego/hertz/pkg/app/server/registry"
    28  	"github.com/cloudwego/hertz/pkg/common/config"
    29  	"github.com/cloudwego/hertz/pkg/common/tracer"
    30  	"github.com/cloudwego/hertz/pkg/common/tracer/stats"
    31  	"github.com/cloudwego/hertz/pkg/network"
    32  	"github.com/cloudwego/hertz/pkg/network/standard"
    33  )
    34  
    35  // WithKeepAliveTimeout sets keep-alive timeout.
    36  //
    37  // In most cases, there is no need to care about this option.
    38  func WithKeepAliveTimeout(t time.Duration) config.Option {
    39  	return config.Option{F: func(o *config.Options) {
    40  		o.KeepAliveTimeout = t
    41  	}}
    42  }
    43  
    44  // WithReadTimeout sets read timeout.
    45  //
    46  // Close the connection when read request timeout.
    47  func WithReadTimeout(t time.Duration) config.Option {
    48  	return config.Option{F: func(o *config.Options) {
    49  		o.ReadTimeout = t
    50  	}}
    51  }
    52  
    53  // WithWriteTimeout sets write timeout.
    54  //
    55  // Connection will be closed when write request timeout.
    56  func WithWriteTimeout(t time.Duration) config.Option {
    57  	return config.Option{F: func(o *config.Options) {
    58  		o.WriteTimeout = t
    59  	}}
    60  }
    61  
    62  // WithIdleTimeout sets idle timeout.
    63  //
    64  // Close the connection when the successive request timeout (in keepalive mode).
    65  // Set this to protect server from misbehavior clients.
    66  func WithIdleTimeout(t time.Duration) config.Option {
    67  	return config.Option{F: func(o *config.Options) {
    68  		o.IdleTimeout = t
    69  	}}
    70  }
    71  
    72  // WithRedirectTrailingSlash sets redirectTrailingSlash.
    73  //
    74  // Enables automatic redirection if the current route can't be matched but a
    75  // handler for the path with (without) the trailing slash exists.
    76  // For example if /foo/ is requested but a route only exists for /foo, the
    77  // client is redirected to /foo with http status code 301 for GET requests
    78  // and 307 for all other request methods.
    79  func WithRedirectTrailingSlash(b bool) config.Option {
    80  	return config.Option{F: func(o *config.Options) {
    81  		o.RedirectTrailingSlash = b
    82  	}}
    83  }
    84  
    85  // WithRedirectFixedPath sets redirectFixedPath.
    86  //
    87  // If enabled, the router tries to fix the current request path, if no
    88  // handle is registered for it.
    89  // First superfluous path elements like ../ or // are removed.
    90  // Afterwards the router does a case-insensitive lookup of the cleaned path.
    91  // If a handle can be found for this route, the router makes a redirection
    92  // to the corrected path with status code 301 for GET requests and 308 for
    93  // all other request methods.
    94  // For example /FOO and /..//Foo could be redirected to /foo.
    95  // RedirectTrailingSlash is independent of this option.
    96  func WithRedirectFixedPath(b bool) config.Option {
    97  	return config.Option{F: func(o *config.Options) {
    98  		o.RedirectFixedPath = b
    99  	}}
   100  }
   101  
   102  // WithHandleMethodNotAllowed sets handleMethodNotAllowed.
   103  //
   104  // If enabled, the router checks if another method is allowed for the
   105  // current route, if the current request can not be routed.
   106  // If this is the case, the request is answered with 'Method Not Allowed'
   107  // and HTTP status code 405.
   108  // If no other Method is allowed, the request is delegated to the NotFound
   109  // handler.
   110  func WithHandleMethodNotAllowed(b bool) config.Option {
   111  	return config.Option{F: func(o *config.Options) {
   112  		o.HandleMethodNotAllowed = b
   113  	}}
   114  }
   115  
   116  // WithUseRawPath sets useRawPath.
   117  //
   118  // If enabled, the url.RawPath will be used to find parameters.
   119  func WithUseRawPath(b bool) config.Option {
   120  	return config.Option{F: func(o *config.Options) {
   121  		o.UseRawPath = b
   122  	}}
   123  }
   124  
   125  // WithRemoveExtraSlash sets removeExtraSlash.
   126  //
   127  // RemoveExtraSlash a parameter can be parsed from the URL even with extra slashes.
   128  // If UseRawPath is false (by default), the RemoveExtraSlash effectively is true,
   129  // as url.Path gonna be used, which is already cleaned.
   130  func WithRemoveExtraSlash(b bool) config.Option {
   131  	return config.Option{F: func(o *config.Options) {
   132  		o.RemoveExtraSlash = b
   133  	}}
   134  }
   135  
   136  // WithUnescapePathValues sets unescapePathValues.
   137  //
   138  // If true, the path value will be unescaped.
   139  // If UseRawPath is false (by default), the UnescapePathValues effectively is true,
   140  // as url.Path gonna be used, which is already unescaped.
   141  func WithUnescapePathValues(b bool) config.Option {
   142  	return config.Option{F: func(o *config.Options) {
   143  		o.UnescapePathValues = b
   144  	}}
   145  }
   146  
   147  // WithDisablePreParseMultipartForm sets disablePreParseMultipartForm.
   148  //
   149  // This option is useful for servers that desire to treat
   150  // multipart form data as a binary blob, or choose when to parse the data.
   151  // Server pre parses multipart form data by default.
   152  func WithDisablePreParseMultipartForm(b bool) config.Option {
   153  	return config.Option{F: func(o *config.Options) {
   154  		o.DisablePreParseMultipartForm = b
   155  	}}
   156  }
   157  
   158  // WithHostPorts sets listening address.
   159  func WithHostPorts(hp string) config.Option {
   160  	return config.Option{F: func(o *config.Options) {
   161  		o.Addr = hp
   162  	}}
   163  }
   164  
   165  // WithBasePath sets basePath.Must be "/" prefix and suffix,If not the default concatenate "/"
   166  func WithBasePath(basePath string) config.Option {
   167  	return config.Option{F: func(o *config.Options) {
   168  		// Must be "/" prefix and suffix,If not the default concatenate "/"
   169  		if !strings.HasPrefix(basePath, "/") {
   170  			basePath = "/" + basePath
   171  		}
   172  		if !strings.HasSuffix(basePath, "/") {
   173  			basePath = basePath + "/"
   174  		}
   175  		o.BasePath = basePath
   176  	}}
   177  }
   178  
   179  // WithMaxRequestBodySize sets the limitation of request body size. Unit: byte
   180  //
   181  // Body buffer which larger than this size will be put back into buffer poll.
   182  func WithMaxRequestBodySize(bs int) config.Option {
   183  	return config.Option{F: func(o *config.Options) {
   184  		o.MaxRequestBodySize = bs
   185  	}}
   186  }
   187  
   188  // WithMaxKeepBodySize sets max size of request/response body to keep when recycled. Unit: byte
   189  //
   190  // Body buffer which larger than this size will be put back into buffer poll.
   191  // Note: If memory pressure is high, try setting the value to 0.
   192  func WithMaxKeepBodySize(bs int) config.Option {
   193  	return config.Option{F: func(o *config.Options) {
   194  		o.MaxKeepBodySize = bs
   195  	}}
   196  }
   197  
   198  // WithGetOnly sets whether accept GET request only. Default: false
   199  func WithGetOnly(isOnly bool) config.Option {
   200  	return config.Option{F: func(o *config.Options) {
   201  		o.GetOnly = isOnly
   202  	}}
   203  }
   204  
   205  // WithKeepAlive sets Whether use long connection. Default: true
   206  func WithKeepAlive(b bool) config.Option {
   207  	return config.Option{F: func(o *config.Options) {
   208  		o.DisableKeepalive = !b
   209  	}}
   210  }
   211  
   212  // WithStreamBody determines whether read body in stream or not.
   213  //
   214  // StreamRequestBody enables streaming request body,
   215  // and calls the handler sooner when given body is
   216  // larger than the current limit.
   217  func WithStreamBody(b bool) config.Option {
   218  	return config.Option{F: func(o *config.Options) {
   219  		o.StreamRequestBody = b
   220  	}}
   221  }
   222  
   223  // WithNetwork sets network. Support "tcp", "udp", "unix"(unix domain socket).
   224  func WithNetwork(nw string) config.Option {
   225  	return config.Option{F: func(o *config.Options) {
   226  		o.Network = nw
   227  	}}
   228  }
   229  
   230  // WithExitWaitTime sets timeout for graceful shutdown.
   231  //
   232  // The server may exit ahead after all connections closed.
   233  // All responses after shutdown will be added 'Connection: close' header.
   234  func WithExitWaitTime(timeout time.Duration) config.Option {
   235  	return config.Option{F: func(o *config.Options) {
   236  		o.ExitWaitTimeout = timeout
   237  	}}
   238  }
   239  
   240  // WithTLS sets TLS config to start a tls server.
   241  //
   242  // NOTE: If a tls server is started, it won't accept non-tls request.
   243  func WithTLS(cfg *tls.Config) config.Option {
   244  	return config.Option{F: func(o *config.Options) {
   245  		// If there is no explicit transporter, change it to standard one. Netpoll do not support tls yet.
   246  		if o.TransporterNewer == nil {
   247  			o.TransporterNewer = standard.NewTransporter
   248  		}
   249  		o.TLS = cfg
   250  	}}
   251  }
   252  
   253  // WithListenConfig sets listener config.
   254  func WithListenConfig(l *net.ListenConfig) config.Option {
   255  	return config.Option{F: func(o *config.Options) {
   256  		o.ListenConfig = l
   257  	}}
   258  }
   259  
   260  // WithTransport sets which network library to use.
   261  func WithTransport(transporter func(options *config.Options) network.Transporter) config.Option {
   262  	return config.Option{F: func(o *config.Options) {
   263  		o.TransporterNewer = transporter
   264  	}}
   265  }
   266  
   267  // WithAltTransport sets which network library to use as an alternative transporter(need to be implemented by specific transporter).
   268  func WithAltTransport(transporter func(options *config.Options) network.Transporter) config.Option {
   269  	return config.Option{F: func(o *config.Options) {
   270  		o.AltTransporterNewer = transporter
   271  	}}
   272  }
   273  
   274  // WithH2C sets whether enable H2C.
   275  func WithH2C(enable bool) config.Option {
   276  	return config.Option{F: func(o *config.Options) {
   277  		o.H2C = enable
   278  	}}
   279  }
   280  
   281  // WithReadBufferSize sets the read buffer size which also limit the header size.
   282  func WithReadBufferSize(size int) config.Option {
   283  	return config.Option{F: func(o *config.Options) {
   284  		o.ReadBufferSize = size
   285  	}}
   286  }
   287  
   288  // WithALPN sets whether enable ALPN.
   289  func WithALPN(enable bool) config.Option {
   290  	return config.Option{F: func(o *config.Options) {
   291  		o.ALPN = enable
   292  	}}
   293  }
   294  
   295  // WithTracer adds tracer to server.
   296  func WithTracer(t tracer.Tracer) config.Option {
   297  	return config.Option{F: func(o *config.Options) {
   298  		o.Tracers = append(o.Tracers, t)
   299  	}}
   300  }
   301  
   302  // WithTraceLevel sets the level trace.
   303  func WithTraceLevel(level stats.Level) config.Option {
   304  	return config.Option{F: func(o *config.Options) {
   305  		o.TraceLevel = level
   306  	}}
   307  }
   308  
   309  // WithRegistry sets the registry and registry's info
   310  func WithRegistry(r registry.Registry, info *registry.Info) config.Option {
   311  	return config.Option{F: func(o *config.Options) {
   312  		o.Registry = r
   313  		o.RegistryInfo = info
   314  	}}
   315  }
   316  
   317  // WithAutoReloadRender sets the config of auto reload render.
   318  // If auto reload render is enabled:
   319  // 1. interval = 0 means reload render according to file watch mechanism.(recommended)
   320  // 2. interval > 0 means reload render every interval.
   321  func WithAutoReloadRender(b bool, interval time.Duration) config.Option {
   322  	return config.Option{F: func(o *config.Options) {
   323  		o.AutoReloadRender = b
   324  		o.AutoReloadInterval = interval
   325  	}}
   326  }
   327  
   328  // WithDisablePrintRoute sets whether disable debugPrintRoute
   329  // If we don't set it, it will default to false
   330  func WithDisablePrintRoute(b bool) config.Option {
   331  	return config.Option{F: func(o *config.Options) {
   332  		o.DisablePrintRoute = b
   333  	}}
   334  }
   335  
   336  // WithOnAccept sets the callback function when a new connection is accepted but cannot
   337  // receive data in netpoll. In go net, it will be called before converting tls connection
   338  func WithOnAccept(fn func(conn net.Conn) context.Context) config.Option {
   339  	return config.Option{F: func(o *config.Options) {
   340  		o.OnAccept = fn
   341  	}}
   342  }
   343  
   344  // WithOnConnect sets the onConnect function. It can received data from connection in netpoll.
   345  // In go net, it will be called after converting tls connection.
   346  func WithOnConnect(fn func(ctx context.Context, conn network.Conn) context.Context) config.Option {
   347  	return config.Option{F: func(o *config.Options) {
   348  		o.OnConnect = fn
   349  	}}
   350  }
   351  
   352  // WithBindConfig sets bind config.
   353  func WithBindConfig(bc *binding.BindConfig) config.Option {
   354  	return config.Option{F: func(o *config.Options) {
   355  		o.BindConfig = bc
   356  	}}
   357  }
   358  
   359  // WithValidateConfig sets validate config.
   360  func WithValidateConfig(vc *binding.ValidateConfig) config.Option {
   361  	return config.Option{F: func(o *config.Options) {
   362  		o.ValidateConfig = vc
   363  	}}
   364  }
   365  
   366  // WithCustomBinder sets customized Binder.
   367  func WithCustomBinder(b binding.Binder) config.Option {
   368  	return config.Option{F: func(o *config.Options) {
   369  		o.CustomBinder = b
   370  	}}
   371  }
   372  
   373  // WithCustomValidator sets customized Binder.
   374  func WithCustomValidator(b binding.StructValidator) config.Option {
   375  	return config.Option{F: func(o *config.Options) {
   376  		o.CustomValidator = b
   377  	}}
   378  }
   379  
   380  // WithDisableHeaderNamesNormalizing is used to set whether disable header names normalizing.
   381  func WithDisableHeaderNamesNormalizing(disable bool) config.Option {
   382  	return config.Option{F: func(o *config.Options) {
   383  		o.DisableHeaderNamesNormalizing = disable
   384  	}}
   385  }
   386  
   387  func WithDisableDefaultDate(disable bool) config.Option {
   388  	return config.Option{F: func(o *config.Options) {
   389  		o.NoDefaultDate = disable
   390  	}}
   391  }
   392  
   393  func WithDisableDefaultContentType(disable bool) config.Option {
   394  	return config.Option{F: func(o *config.Options) {
   395  		o.NoDefaultContentType = disable
   396  	}}
   397  }
   398  
   399  // WithSenseClientDisconnection sets the ability to sense client disconnections.
   400  // If we don't set it, it will default to false.
   401  // There are two issues to note when using this option:
   402  // 1. Warning: It only applies to netpoll.
   403  // 2. After opening, the context.Context in the request will be cancelled.
   404  //
   405  //	Example:
   406  //	server.Default(
   407  //	server.WithSenseClientDisconnection(true),
   408  //	)
   409  func WithSenseClientDisconnection(b bool) config.Option {
   410  	return config.Option{F: func(o *config.Options) {
   411  		o.SenseClientDisconnection = b
   412  	}}
   413  }