2020-05-07 19:28:21 +02:00
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
2020-05-07 20:22:26 +02:00
// 🤖 Github Repository: https://github.com/gofiber/fiber
2020-05-07 19:28:21 +02:00
// 📌 API Documentation: https://docs.gofiber.io
2020-02-21 18:07:43 +01:00
2022-03-03 13:54:56 +03:00
// Package fiber is an Express inspired web framework built on top of Fasthttp,
2020-07-06 17:12:35 +02:00
// the fastest HTTP engine for Go. Designed to ease things up for fast
// development with zero memory allocation and performance in mind.
2020-02-21 18:07:43 +01:00
package fiber
import (
"bufio"
2022-12-20 02:40:43 +11:00
"context"
2022-09-23 09:17:34 +03:00
"encoding/json"
"encoding/xml"
2020-12-16 02:40:28 +01:00
"errors"
2020-02-21 18:07:43 +01:00
"fmt"
"net"
"net/http"
"net/http/httputil"
2020-02-27 04:10:26 -05:00
"reflect"
2020-02-21 18:07:43 +01:00
"strconv"
"strings"
2020-05-09 15:15:34 +02:00
"sync"
2020-02-21 18:07:43 +01:00
"time"
2023-11-07 20:22:31 +03:00
"github.com/gofiber/fiber/v3/log"
2022-10-31 13:44:53 +00:00
"github.com/gofiber/utils/v2"
2023-01-27 09:01:37 +01:00
2020-09-13 11:20:11 +02:00
"github.com/valyala/fasthttp"
2020-02-21 18:07:43 +01:00
)
2020-09-14 06:07:34 +02:00
// Version of current fiber package
2024-04-07 20:27:48 +02:00
const Version = "3.0.0-beta.2"
2020-02-21 18:07:43 +01:00
2020-10-31 07:51:44 +01:00
// Handler defines a function to serve HTTP requests.
2022-07-13 08:48:29 +03:00
type Handler = func ( Ctx ) error
2020-10-31 07:51:44 +01:00
2022-05-31 17:41:38 +03:00
// Map is a shortcut for map[string]any, useful for JSON returns
type Map map [ string ] any
2020-03-24 05:31:51 +01:00
2020-11-18 08:57:27 +01:00
// Storage interface for communicating with different database/key-value
// providers
2020-10-26 00:10:35 +00:00
type Storage interface {
2020-11-18 08:57:27 +01:00
// Get gets the value for the given key.
2022-02-22 10:10:55 +03:00
// `nil, nil` is returned when the key does not exist
2020-10-31 06:36:02 +01:00
Get ( key string ) ( [ ] byte , error )
2022-02-22 10:10:55 +03:00
// Set stores the given value for the given key along
// with an expiration value, 0 means no expiration.
2020-11-18 08:57:27 +01:00
// Empty key or value will be ignored without an error.
2022-02-22 10:10:55 +03:00
Set ( key string , val [ ] byte , exp time . Duration ) error
2020-10-31 06:36:02 +01:00
2020-11-18 08:57:27 +01:00
// Delete deletes the value for the given key.
// It returns no error if the storage does not contain the key,
2020-10-31 06:36:02 +01:00
Delete ( key string ) error
2020-11-18 08:57:27 +01:00
// Reset resets the storage and delete all keys.
2020-11-06 01:52:05 +01:00
Reset ( ) error
2020-11-18 08:57:27 +01:00
// Close closes the storage and will stop any running garbage
// collectors and open connections.
2020-11-06 01:52:05 +01:00
Close ( ) error
2020-10-26 00:10:35 +00:00
}
2020-09-13 11:20:11 +02:00
// ErrorHandler defines a function that will process all errors
// returned from any handlers in the stack
2022-08-08 09:21:00 +03:00
//
// cfg := fiber.Config{}
2022-08-19 14:33:31 +03:00
// cfg.ErrorHandler = func(c Ctx, err error) error {
2022-08-08 09:21:00 +03:00
// code := StatusInternalServerError
2022-08-15 21:25:26 +03:00
// var e *fiber.Error
// if errors.As(err, &e) {
2022-08-08 09:21:00 +03:00
// code = e.Code
// }
// c.Set(HeaderContentType, MIMETextPlainCharsetUTF8)
// return c.Status(code).SendString(err.Error())
// }
// app := fiber.New(cfg)
2022-07-13 08:48:29 +03:00
type ErrorHandler = func ( Ctx , error ) error
2020-05-24 10:02:21 -04:00
2020-06-08 13:09:40 +02:00
// Error represents an error that occurred while handling a request.
type Error struct {
2022-08-08 09:21:00 +03:00
Code int ` json:"code" `
Message string ` json:"message" `
2020-06-08 13:09:40 +02:00
}
2020-06-07 20:57:55 +02:00
2020-03-31 10:03:39 +02:00
// App denotes the Fiber application.
type App struct {
2020-05-23 09:25:18 +02:00
mutex sync . Mutex
2020-06-20 17:26:48 +02:00
// Route stack divided by HTTP methods
2020-05-23 09:25:18 +02:00
stack [ ] [ ] * Route
2020-08-10 10:54:41 +02:00
// Route stack divided by HTTP methods and route prefixes
2020-08-09 21:53:15 +02:00
treeStack [ ] map [ string ] [ ] * Route
2021-01-24 13:02:21 +01:00
// contains the information if the route stack has been changed to build the optimized tree
routesRefreshed bool
2020-08-09 21:53:15 +02:00
// Amount of registered routes
2021-05-05 23:53:54 +08:00
routesCount uint32
2020-07-22 02:06:32 +02:00
// Amount of registered handlers
2021-12-29 17:26:50 +08:00
handlersCount uint32
2020-05-23 09:25:18 +02:00
// Ctx pool
pool sync . Pool
2020-05-11 04:30:31 +02:00
// Fasthttp server
2020-05-16 05:11:25 +02:00
server * fasthttp . Server
2020-09-13 11:20:11 +02:00
// App config
config Config
2021-05-05 17:24:26 -03:00
// Converts string to a byte slice
getBytes func ( s string ) ( b [ ] byte )
// Converts byte slice to a string
getString func ( b [ ] byte ) string
2022-03-10 10:35:15 +03:00
// Hooks
2022-08-16 09:13:38 +03:00
hooks * Hooks
2022-03-10 10:35:15 +03:00
// Latest route & group
latestRoute * Route
2022-07-13 08:48:29 +03:00
// newCtxFunc
newCtxFunc func ( app * App ) CustomCtx
2022-08-08 10:16:08 +03:00
// custom binders
customBinders [ ] CustomBinder
2022-08-19 08:19:22 +02:00
// TLS handler
2022-08-24 10:47:37 +03:00
tlsHandler * TLSHandler
2022-10-25 08:51:44 +03:00
// Mount fields
mountFields * mountFields
2022-11-15 06:13:11 -05:00
// Indicates if the value was explicitly configured
configured Config
2024-02-02 11:56:58 +03:00
// customConstraints is a list of external constraints
customConstraints [ ] CustomConstraint
2020-09-13 11:20:11 +02:00
}
// Config is a struct holding the server settings.
type Config struct {
2020-06-03 00:01:55 +02:00
// Enables the "Server: value" HTTP header.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: ""
2020-07-02 20:26:38 +02:00
ServerHeader string ` json:"server_header" `
2020-05-23 09:25:18 +02:00
2020-07-12 23:29:15 +09:00
// When set to true, the router treats "/foo" and "/foo/" as different.
2020-05-23 09:25:18 +02:00
// By default this is disabled and both "/foo" and "/foo/" will execute the same handler.
2020-09-17 01:39:42 +02:00
//
// Default: false
2020-07-02 20:26:38 +02:00
StrictRouting bool ` json:"strict_routing" `
2020-05-23 09:25:18 +02:00
2020-07-12 23:29:15 +09:00
// When set to true, enables case sensitive routing.
// E.g. "/FoO" and "/foo" are treated as different routes.
2020-05-23 09:25:18 +02:00
// By default this is disabled and both "/FoO" and "/foo" will execute the same handler.
2020-09-17 01:39:42 +02:00
//
// Default: false
2020-07-02 20:26:38 +02:00
CaseSensitive bool ` json:"case_sensitive" `
2020-05-23 09:25:18 +02:00
2020-07-12 23:29:15 +09:00
// When set to true, this relinquishes the 0-allocation promise in certain
2020-07-12 22:48:12 +09:00
// cases in order to access the handler values (e.g. request bodies) in an
// immutable fashion so that these values are available even if you return
// from handler.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: false
2020-07-02 20:26:38 +02:00
Immutable bool ` json:"immutable" `
2020-05-23 09:25:18 +02:00
2020-07-12 23:29:15 +09:00
// When set to true, converts all encoded characters in the route back
2021-01-06 13:28:48 +01:00
// before setting the path for the context, so that the routing,
// the returning of the current url from the context `ctx.Path()`
2021-07-17 22:20:14 +07:00
// and the parameters `ctx.Params(%key%)` with decoded characters will work
2020-09-17 01:39:42 +02:00
//
2020-06-25 08:44:29 +02:00
// Default: false
2020-07-02 20:26:38 +02:00
UnescapePath bool ` json:"unescape_path" `
2020-06-25 08:44:29 +02:00
2020-07-12 23:29:15 +09:00
// Max body size that the server accepts.
2020-11-18 08:57:27 +01:00
// -1 will decline any body size
//
2020-06-03 00:01:55 +02:00
// Default: 4 * 1024 * 1024
2020-07-02 20:26:38 +02:00
BodyLimit int ` json:"body_limit" `
2020-05-23 09:25:18 +02:00
2020-04-19 16:10:19 +02:00
// Maximum number of concurrent connections.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: 256 * 1024
2020-07-02 20:26:38 +02:00
Concurrency int ` json:"concurrency" `
2020-05-23 09:25:18 +02:00
2020-06-12 12:29:57 +02:00
// Views is the interface that wraps the Render function.
2020-09-17 01:39:42 +02:00
//
2020-06-12 12:29:57 +02:00
// Default: nil
2020-07-02 20:26:38 +02:00
Views Views ` json:"-" `
2020-06-12 12:29:57 +02:00
2021-06-14 14:55:49 +05:45
// Views Layout is the global layout for all template render until override on Render function.
//
// Default: ""
ViewsLayout string ` json:"views_layout" `
2022-01-24 08:29:46 +01:00
// PassLocalsToViews Enables passing of the locals set on a fiber.Ctx to the template engine
//
// Default: false
PassLocalsToViews bool ` json:"pass_locals_to_views" `
2020-03-24 05:31:51 +01:00
// The amount of time allowed to read the full request including body.
2020-06-21 18:00:57 +02:00
// It is reset after the request handler has returned.
// The connection's read deadline is reset when the connection opens.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: unlimited
2020-07-02 20:26:38 +02:00
ReadTimeout time . Duration ` json:"read_timeout" `
2020-05-23 09:25:18 +02:00
2020-03-24 05:31:51 +01:00
// The maximum duration before timing out writes of the response.
2020-06-21 18:00:57 +02:00
// It is reset after the request handler has returned.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: unlimited
2020-07-02 20:26:38 +02:00
WriteTimeout time . Duration ` json:"write_timeout" `
2020-05-23 09:25:18 +02:00
2020-03-24 05:31:51 +01:00
// The maximum amount of time to wait for the next request when keep-alive is enabled.
2020-06-21 18:00:57 +02:00
// If IdleTimeout is zero, the value of ReadTimeout is used.
2020-09-17 01:39:42 +02:00
//
2020-06-03 00:01:55 +02:00
// Default: unlimited
2020-07-02 20:26:38 +02:00
IdleTimeout time . Duration ` json:"idle_timeout" `
2020-02-21 18:07:43 +01:00
2020-06-15 13:36:50 +02:00
// Per-connection buffer size for requests' reading.
// This also limits the maximum header size.
// Increase this buffer if your clients send multi-KB RequestURIs
// and/or multi-KB headers (for example, BIG cookies).
2020-09-17 01:39:42 +02:00
//
2020-07-12 23:29:15 +09:00
// Default: 4096
2020-07-02 20:26:38 +02:00
ReadBufferSize int ` json:"read_buffer_size" `
2020-06-15 13:36:50 +02:00
// Per-connection buffer size for responses' writing.
2020-09-17 01:39:42 +02:00
//
2020-07-12 23:29:15 +09:00
// Default: 4096
2020-07-02 20:26:38 +02:00
WriteBufferSize int ` json:"write_buffer_size" `
2020-06-15 13:36:50 +02:00
2020-06-07 20:35:41 +02:00
// CompressedFileSuffix adds suffix to the original file name and
// tries saving the resulting compressed file under the new file name.
2020-09-17 01:39:42 +02:00
//
2020-06-07 20:35:41 +02:00
// Default: ".fiber.gz"
2020-07-02 20:26:38 +02:00
CompressedFileSuffix string ` json:"compressed_file_suffix" `
2020-06-07 20:35:41 +02:00
2020-09-13 11:20:11 +02:00
// ProxyHeader will enable c.IP() to return the value of the given header key
// By default c.IP() will return the Remote IP from the TCP connection
// This property can be useful if you are behind a load balancer: X-Forwarded-*
// NOTE: headers are easily spoofed and the detected IP addresses are unreliable.
2020-09-17 01:39:42 +02:00
//
2020-09-13 11:20:11 +02:00
// Default: ""
ProxyHeader string ` json:"proxy_header" `
// GETOnly rejects all non-GET requests if set to true.
// This option is useful as anti-DoS protection for servers
// accepting only GET requests. The request size is limited
// by ReadBufferSize if GETOnly is set.
2020-09-17 01:39:42 +02:00
//
// Default: false
2020-09-13 11:20:11 +02:00
GETOnly bool ` json:"get_only" `
// ErrorHandler is executed when an error is returned from fiber.Handler.
2020-09-17 01:39:42 +02:00
//
// Default: DefaultErrorHandler
2020-09-13 11:20:11 +02:00
ErrorHandler ErrorHandler ` json:"-" `
// When set to true, disables keep-alive connections.
// The server will close incoming connections after sending the first response to client.
2020-09-17 01:39:42 +02:00
//
2020-09-13 11:20:11 +02:00
// Default: false
2020-09-14 04:54:26 +02:00
DisableKeepalive bool ` json:"disable_keepalive" `
2020-09-13 11:20:11 +02:00
// When set to true, causes the default date header to be excluded from the response.
2020-09-17 01:39:42 +02:00
//
2020-09-13 11:20:11 +02:00
// Default: false
DisableDefaultDate bool ` json:"disable_default_date" `
// When set to true, causes the default Content-Type header to be excluded from the response.
2020-09-17 01:39:42 +02:00
//
2020-09-13 11:20:11 +02:00
// Default: false
DisableDefaultContentType bool ` json:"disable_default_content_type" `
// When set to true, disables header normalization.
// By default all header names are normalized: conteNT-tYPE -> Content-Type.
2020-09-17 01:39:42 +02:00
//
2020-09-13 11:20:11 +02:00
// Default: false
DisableHeaderNormalizing bool ` json:"disable_header_normalizing" `
2021-07-16 12:29:11 +05:45
// This function allows to setup app name for the app
//
// Default: nil
AppName string ` json:"app_name" `
2021-07-11 11:45:46 +02:00
// StreamRequestBody enables request body streaming,
// and calls the handler sooner when given body is
2024-03-10 15:10:21 +03:30
// larger than the current limit.
2021-07-11 11:45:46 +02:00
StreamRequestBody bool
// Will not pre parse Multipart Form data if set to true.
//
// This option is useful for servers that desire to treat
// multipart form data as a binary blob, or choose when to parse the data.
//
// Server pre parses multipart form data by default.
DisablePreParseMultipartForm bool
2020-10-07 11:55:17 +02:00
// Aggressively reduces memory usage at the cost of higher CPU usage
// if set to true.
//
// Try enabling this option only if the server consumes too much memory
// serving mostly idle keep-alive connections. This may reduce memory
// usage by more than 50%.
//
// Default: false
ReduceMemoryUsage bool ` json:"reduce_memory_usage" `
2020-11-11 14:18:19 +01:00
// FEATURE: v2.3.x
2020-05-23 09:25:18 +02:00
// The router executes the same handler by default if StrictRouting or CaseSensitive is disabled.
2023-01-27 09:01:37 +01:00
// Enabling RedirectFixedPath will change this behavior into a client redirect to the original route path.
2020-05-23 09:25:18 +02:00
// Using the status code 301 for GET requests and 308 for all other request methods.
2020-09-17 01:39:42 +02:00
//
// Default: false
2020-05-23 09:25:18 +02:00
// RedirectFixedPath bool
2021-01-19 19:42:51 -08:00
// When set by an external client of Fiber it will use the provided implementation of a
2021-01-23 02:15:59 -06:00
// JSONMarshal
2021-01-19 19:42:51 -08:00
//
2021-01-23 02:15:59 -06:00
// Allowing for flexibility in using another json library for encoding
// Default: json.Marshal
JSONEncoder utils . JSONMarshal ` json:"-" `
2021-02-07 13:55:13 +08:00
2021-08-18 17:56:07 +05:30
// When set by an external client of Fiber it will use the provided implementation of a
// JSONUnmarshal
//
2022-02-01 22:42:23 +03:00
// Allowing for flexibility in using another json library for decoding
2021-08-18 17:56:07 +05:30
// Default: json.Unmarshal
JSONDecoder utils . JSONUnmarshal ` json:"-" `
2022-08-16 09:05:35 +03:00
// XMLEncoder set by an external client of Fiber it will use the provided implementation of a
// XMLMarshal
//
// Allowing for flexibility in using another XML library for encoding
// Default: xml.Marshal
XMLEncoder utils . XMLMarshal ` json:"-" `
2021-06-30 09:03:45 +03:00
// If you find yourself behind some sort of proxy, like a load balancer,
// then certain header information may be sent to you using special X-Forwarded-* headers or the Forwarded header.
// For example, the Host HTTP header is usually used to return the requested host.
// But when you’ re behind a proxy, the actual host may be stored in an X-Forwarded-Host header.
//
// If you are behind a proxy, you should enable TrustedProxyCheck to prevent header spoofing.
// If you enable EnableTrustedProxyCheck and leave TrustedProxies empty Fiber will skip
// all headers that could be spoofed.
// If request ip in TrustedProxies whitelist then:
2022-06-21 17:24:34 +03:00
// 1. c.Scheme() get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header
2021-06-30 09:03:45 +03:00
// 2. c.IP() get value from ProxyHeader header.
2022-09-06 18:43:06 +03:00
// 3. c.Host() and c.Hostname() get value from X-Forwarded-Host header
2021-06-30 09:03:45 +03:00
// But if request ip NOT in Trusted Proxies whitelist then:
2022-06-21 17:24:34 +03:00
// 1. c.Scheme() WON't get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header,
2021-06-30 09:03:45 +03:00
// will return https in case when tls connection is handled by the app, of http otherwise
// 2. c.IP() WON'T get value from ProxyHeader header, will return RemoteIP() from fasthttp context
2022-09-06 18:43:06 +03:00
// 3. c.Host() and c.Hostname() WON'T get value from X-Forwarded-Host header, fasthttp.Request.URI().Host()
2021-06-30 09:03:45 +03:00
// will be used to get the hostname.
//
// Default: false
EnableTrustedProxyCheck bool ` json:"enable_trusted_proxy_check" `
// Read EnableTrustedProxyCheck doc.
//
// Default: []string
2021-12-31 12:32:39 -05:00
TrustedProxies [ ] string ` json:"trusted_proxies" `
trustedProxiesMap map [ string ] struct { }
trustedProxyRanges [ ] * net . IPNet
2021-12-30 21:13:31 +08:00
2022-08-23 02:32:21 -04:00
// If set to true, c.IP() and c.IPs() will validate IP addresses before returning them.
// Also, c.IP() will return only the first valid IP rather than just the raw header
// WARNING: this has a performance cost associated with it.
//
// Default: false
EnableIPValidation bool ` json:"enable_ip_validation" `
2022-08-01 09:24:37 +03:00
// You can define custom color scheme. They'll be used for startup message, route list and some middlewares.
//
// Optional. Default: DefaultColors
ColorScheme Colors ` json:"color_scheme" `
2022-08-19 14:33:31 +03:00
2022-08-08 10:16:08 +03:00
// If you want to validate header/form/query... automatically when to bind, you can define struct validator.
// Fiber doesn't have default validator, so it'll skip validator step if you don't use any validator.
//
// Default: nil
StructValidator StructValidator
2022-11-27 20:34:48 +03:00
2022-11-11 14:23:30 +07:00
// RequestMethods provides customizibility for HTTP methods. You can add/remove methods as you wish.
//
2022-11-21 08:54:34 +01:00
// Optional. Default: DefaultMethods
2022-11-11 14:23:30 +07:00
RequestMethods [ ] string
2023-08-21 10:44:02 +03:00
// EnableSplittingOnParsers splits the query/body/header parameters by comma when it's true.
// For example, you can use it to parse multiple values from a query parameter like this:
// /api?foo=bar,baz == foo[]=bar&foo[]=baz
//
// Optional. Default: false
EnableSplittingOnParsers bool ` json:"enable_splitting_on_parsers" `
2020-03-22 01:51:53 +01:00
}
2020-07-13 00:41:19 +09:00
// Static defines configuration options when defining static assets.
2020-04-28 21:34:34 +02:00
type Static struct {
2020-07-13 00:41:19 +09:00
// When set to true, the server tries minimizing CPU usage by caching compressed files.
// This works differently than the github.com/gofiber/compression middleware.
2020-04-28 21:34:34 +02:00
// Optional. Default value false
2020-09-13 11:20:11 +02:00
Compress bool ` json:"compress" `
2020-05-23 09:25:18 +02:00
2020-07-13 00:41:19 +09:00
// When set to true, enables byte range requests.
2020-04-28 21:34:34 +02:00
// Optional. Default value false
2020-09-13 11:20:11 +02:00
ByteRange bool ` json:"byte_range" `
2020-05-23 09:25:18 +02:00
2020-07-13 00:41:19 +09:00
// When set to true, enables directory browsing.
2020-04-28 21:34:34 +02:00
// Optional. Default value false.
2020-09-13 11:20:11 +02:00
Browse bool ` json:"browse" `
2020-05-23 09:25:18 +02:00
2022-02-03 08:41:45 -05:00
// When set to true, enables direct download.
// Optional. Default value false.
Download bool ` json:"download" `
2020-07-13 00:41:19 +09:00
// The name of the index file for serving a directory.
2020-04-28 21:34:34 +02:00
// Optional. Default value "index.html".
2020-09-13 11:20:11 +02:00
Index string ` json:"index" `
2020-10-07 10:20:19 +02:00
2020-11-11 14:18:19 +01:00
// Expiration duration for inactive file handlers.
// Use a negative time.Duration to disable it.
//
// Optional. Default value 10 * time.Second.
CacheDuration time . Duration ` json:"cache_duration" `
2020-10-07 10:20:19 +02:00
// The value for the Cache-Control HTTP-header
// that is set on the file response. MaxAge is defined in seconds.
//
// Optional. Default value 0.
MaxAge int ` json:"max_age" `
2021-01-22 23:07:22 +01:00
2022-10-05 12:14:37 -04:00
// ModifyResponse defines a function that allows you to alter the response.
//
// Optional. Default: nil
ModifyResponse Handler
2021-01-22 23:07:22 +01:00
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
2022-07-13 08:48:29 +03:00
Next func ( c Ctx ) bool
2020-04-28 21:34:34 +02:00
}
2021-12-30 21:13:31 +08:00
// RouteMessage is some message need to be print when server starts
type RouteMessage struct {
name string
method string
path string
handlers string
}
2020-09-13 11:39:55 +02:00
// Default Config values
2020-07-13 00:49:56 +09:00
const (
2020-09-13 11:20:11 +02:00
DefaultBodyLimit = 4 * 1024 * 1024
DefaultConcurrency = 256 * 1024
DefaultReadBufferSize = 4096
DefaultWriteBufferSize = 4096
DefaultCompressedFileSuffix = ".fiber.gz"
2020-06-08 13:09:40 +02:00
)
2020-05-23 09:25:18 +02:00
2022-11-11 14:23:30 +07:00
// HTTP methods enabled by default
var DefaultMethods = [ ] string {
MethodGet ,
MethodHead ,
MethodPost ,
MethodPut ,
MethodDelete ,
MethodConnect ,
MethodOptions ,
MethodTrace ,
MethodPatch ,
}
2020-10-25 12:23:10 +01:00
// DefaultErrorHandler that process return errors from handlers
2023-02-05 23:43:42 +03:00
func DefaultErrorHandler ( c Ctx , err error ) error {
2020-07-13 00:49:56 +09:00
code := StatusInternalServerError
2022-07-04 10:15:17 +03:00
var e * Error
if errors . As ( err , & e ) {
2020-07-13 00:49:56 +09:00
code = e . Code
}
2020-09-13 11:20:11 +02:00
c . Set ( HeaderContentType , MIMETextPlainCharsetUTF8 )
return c . Status ( code ) . SendString ( err . Error ( ) )
2020-07-13 00:49:56 +09:00
}
2020-03-24 05:31:51 +01:00
// New creates a new Fiber named instance.
2022-08-08 09:21:00 +03:00
//
// app := fiber.New()
//
2020-09-14 04:54:26 +02:00
// You can pass optional configuration options by passing a Config struct:
2022-08-08 09:21:00 +03:00
//
// app := fiber.New(fiber.Config{
// Prefork: true,
// ServerHeader: "Fiber",
// })
2020-09-13 11:20:11 +02:00
func New ( config ... Config ) * App {
2020-05-23 09:25:18 +02:00
// Create a new app
app := & App {
2020-09-13 11:20:11 +02:00
// Create config
2022-08-08 10:16:08 +03:00
config : Config { } ,
getBytes : utils . UnsafeBytes ,
getString : utils . UnsafeString ,
latestRoute : & Route { } ,
customBinders : [ ] CustomBinder { } ,
2020-05-23 09:25:18 +02:00
}
2022-03-10 10:35:15 +03:00
2022-07-13 08:48:29 +03:00
// Create Ctx pool
app . pool = sync . Pool {
New : func ( ) any {
V2 to v3 merge (#2864)
* Update pull_request_template.md
* Update v3-changes.md
* Update CONTRIBUTING.md (#2752)
Grammar correction.
* chore(encryptcookie)!: update default config (#2753)
* chore(encryptcookie)!: update default config
docs(encryptcookie): enhance documentation and examples
BREAKING CHANGE: removed the hardcoded "csrf_" from the Except.
* docs(encryptcookie): reads or modifies cookies
* chore(encryptcookie): csrf config example
* docs(encryptcookie): md table spacing
* build(deps): bump actions/setup-go from 4 to 5 (#2754)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)
---
updated-dependencies:
- dependency-name: actions/setup-go
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* 🩹 middleware/logger/: log client IP address by default (#2755)
* middleware/logger: Log client IP address by default.
* Update doc.
* fix: don't constrain middlewares' context-keys to strings :bug: (#2751)
* Revert "Revert ":bug: requestid.Config.ContextKey is interface{} (#2369)" (#2742)"
This reverts commit 28be17f929cfa7d3c27dd292fc3956f2f9882e22.
* fix: request ContextKey default value condition
Should check for `nil` since it is `any`.
* fix: don't constrain middlewares' context-keys to strings
`context` recommends using "unexported type" as context keys to avoid
collisions https://pkg.go.dev/github.com/gofiber/fiber/v2#Ctx.Locals.
The official go blog also recommends this https://go.dev/blog/context.
`fiber.Ctx.Locals(key any, value any)` correctly allows consumers to
use unexported types or e.g. strings.
But some fiber middlewares constrain their context-keys to `string` in
their "default config structs", making it impossible to use unexported
types.
This PR removes the `string` _constraint_ from all middlewares, allowing
to now use unexported types as per the official guidelines. However
the default value is still a string, so it's not a breaking change, and
anyone still using strings as context keys is not affected.
* 📚 Update app.md for indentation (#2761)
Update app.md for indentation
* build(deps): bump github.com/google/uuid from 1.4.0 to 1.5.0 (#2762)
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0)
---
updated-dependencies:
- dependency-name: github.com/google/uuid
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* build(deps): bump github/codeql-action from 2 to 3 (#2763)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)
---
updated-dependencies:
- dependency-name: github/codeql-action
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Changing default log output (#2730)
changing default log output
Closes #2729
* Update hooks.md
fix wrong hooks signature
* 🩹 Fix: CORS middleware should use the defined AllowedOriginsFunc config when AllowedOrigins is empty (#2771)
* 🐛 [Bug]: Adaptator + otelfiber issue #2641 (#2772)
* 🩹🚨 - fix for redirect with query params (#2748)
* redirect with query params did not work, fix it and add test for it
* redirect middleware - fix test typo
* ♻️ logger/middleware colorize logger error message #2593 (#2773)
* :sparkles: feat: add liveness and readiness checks (#2509)
* :sparkles: feat: add liveness and readiness checkers
* :memo: docs: add docs for liveness and readiness
* :sparkles: feat: add options method for probe checkers
* :white_check_mark: tests: add tests for liveness and readiness
* :recycle: refactor: change default endpoint values
* :recycle: refactor: change default value for liveness endpoint
* :memo: docs: add return status for liveness and readiness probes
* :recycle: refactor: change probechecker to middleware
* :memo: docs: move docs to middleware session
* :recycle: refactor: apply gofumpt formatting
* :recycle: refactor: remove unused parameter
* split config and apply a review
* apply reviews and add testcases
* add benchmark
* cleanup
* rename middleware
* fix linter
* Update docs and config values
* Revert change to IsReady
* Updates based on code review
* Update docs to match other middlewares
---------
Co-authored-by: Muhammed Efe Cetin <efectn@protonmail.com>
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: Juan Calderon-Perez <jgcalderonperez@protonmail.com>
* prepare release v2.52.0
- add more Parser tests
* fix healthcheck.md
* configure workflows for V2 branch
* configure workflows for V2 branch
* Fix default value to false in docs of QueryBool (#2811)
fix default value to false in docs of QueryBool
* update queryParser config
* Update ctx.md
* Update routing.md
* merge v2 in v3
* merge v2 in v3
* lint fixes
* :books: Doc: Fix code snippet indentation in /docs/api/middleware/keyauth.md
Removes an an extra level of indentation in line 51 of
`keyauth.md` [here](https://github.com/gofiber/fiber/blob/v2/docs/api/middleware/keyauth.md?plain=1#L51)
* fix: healthcheck middleware not working with route group (#2863)
* fix: healthcheck middleware not working with route group
* perf: change verification method to improve perf
* Update healthcheck_test.go
* test: add not matching route test for strict routing
* add more test cases
* correct tests
* correct test helpers
* correct tests
* correct tests
---------
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: René Werner <rene@gofiber.io>
* merge v2 in v3
* Merge pull request from GHSA-fmg4-x8pw-hjhg
* Enforce Wildcard Origins with AllowCredentials check
* Expand unit-tests, fix issues with subdomains logic, update docs
* Update cors.md
* Added test using localhost, ipv4, and ipv6 address
* improve documentation markdown
---------
Co-authored-by: René Werner <rene@gofiber.io>
* Update app.go
prepare release v2.52.1
* fix cors domain normalize
* fix sync-docs workflow
* test: fix failing tests
* fix sync-docs workflow
* test: cors middleware use testify require
* chore: fix lint warnings
* chore: revert test isolation.
* fixed the fasthttp ctx race condition problem
* Update middleware/cors/utils.go
Co-authored-by: Renan Bastos <renanbastos.tec@gmail.com>
* fix sync_docs.sh
* fix review comments/hints
* fix review comments/hints
* stabilize Test_Proxy_Timeout_Slow_Server test
* stabilize Test_Proxy_.* tests
* ignore bodyclose linter for tests
use http.NoBody instead of nil
* revert(tests): undo http.NoBody usage
* fix(ctx pool): postpone the reset for some values
shortly before the release in the pool
* refactor(tests): use testify panic method instead of custom solution
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: tokelo-12 <113810058+tokelo-12@users.noreply.github.com>
Co-authored-by: Jason McNeil <sixcolors@mac.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: iRedMail <2048991+iredmail@users.noreply.github.com>
Co-authored-by: Benjamin Grosse <ste3ls@gmail.com>
Co-authored-by: Mehmet Firat KOMURCU <mehmetfiratkomurcu@hotmail.com>
Co-authored-by: Bruno <bdm2943@icloud.com>
Co-authored-by: Muhammad Kholid B <muhammadkholidb@gmail.com>
Co-authored-by: gilwo <gilwo@users.noreply.github.com>
Co-authored-by: Lucas Lemos <lucashenriqueblemos@gmail.com>
Co-authored-by: Muhammed Efe Cetin <efectn@protonmail.com>
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: Juan Calderon-Perez <jgcalderonperez@protonmail.com>
Co-authored-by: Jongmin Kim <kjongmin26@gmail.com>
Co-authored-by: Giovanni Rivera <rivera.giovanni271@gmail.com>
Co-authored-by: Renan Bastos <renanbastos.tec@gmail.com>
2024-02-29 08:29:59 +01:00
return app . newCtx ( )
2022-07-13 08:48:29 +03:00
} ,
}
2022-03-10 10:35:15 +03:00
// Define hooks
app . hooks = newHooks ( app )
2022-10-25 08:51:44 +03:00
// Define mountFields
app . mountFields = newMountFields ( app )
2020-09-13 11:20:11 +02:00
// Override config if provided
if len ( config ) > 0 {
app . config = config [ 0 ]
2020-03-14 12:30:21 +01:00
}
2020-10-15 16:53:29 +08:00
2022-11-15 06:13:11 -05:00
// Initialize configured before defaults are set
app . configured = app . config
2020-09-13 11:20:11 +02:00
// Override default values
2020-11-18 08:57:27 +01:00
if app . config . BodyLimit == 0 {
2020-09-13 11:20:11 +02:00
app . config . BodyLimit = DefaultBodyLimit
2020-06-07 20:57:55 +02:00
}
2020-09-13 11:20:11 +02:00
if app . config . Concurrency <= 0 {
app . config . Concurrency = DefaultConcurrency
2020-06-15 13:36:50 +02:00
}
2020-09-13 11:20:11 +02:00
if app . config . ReadBufferSize <= 0 {
app . config . ReadBufferSize = DefaultReadBufferSize
2020-06-15 13:36:50 +02:00
}
2020-09-13 11:20:11 +02:00
if app . config . WriteBufferSize <= 0 {
app . config . WriteBufferSize = DefaultWriteBufferSize
2020-06-07 20:57:55 +02:00
}
2020-09-13 11:20:11 +02:00
if app . config . CompressedFileSuffix == "" {
app . config . CompressedFileSuffix = DefaultCompressedFileSuffix
2020-06-07 20:57:55 +02:00
}
2020-09-13 11:20:11 +02:00
if app . config . Immutable {
2021-05-05 17:24:26 -03:00
app . getBytes , app . getString = getBytesImmutable , getStringImmutable
2020-06-07 20:57:55 +02:00
}
2021-10-05 08:03:20 -04:00
2020-09-13 11:20:11 +02:00
if app . config . ErrorHandler == nil {
app . config . ErrorHandler = DefaultErrorHandler
}
2021-10-05 08:03:20 -04:00
2021-01-23 02:15:59 -06:00
if app . config . JSONEncoder == nil {
app . config . JSONEncoder = json . Marshal
2021-01-19 19:42:51 -08:00
}
2021-08-18 17:56:07 +05:30
if app . config . JSONDecoder == nil {
app . config . JSONDecoder = json . Unmarshal
}
2022-08-16 09:05:35 +03:00
if app . config . XMLEncoder == nil {
app . config . XMLEncoder = xml . Marshal
}
2022-11-11 14:23:30 +07:00
if len ( app . config . RequestMethods ) == 0 {
app . config . RequestMethods = DefaultMethods
}
2020-11-18 08:57:27 +01:00
2021-06-30 09:03:45 +03:00
app . config . trustedProxiesMap = make ( map [ string ] struct { } , len ( app . config . TrustedProxies ) )
2021-12-31 12:32:39 -05:00
for _ , ipAddress := range app . config . TrustedProxies {
app . handleTrustedProxy ( ipAddress )
2021-06-30 09:03:45 +03:00
}
2022-11-11 14:23:30 +07:00
// Create router stack
app . stack = make ( [ ] [ ] * Route , len ( app . config . RequestMethods ) )
app . treeStack = make ( [ ] map [ string ] [ ] * Route , len ( app . config . RequestMethods ) )
2022-08-01 09:24:37 +03:00
// Override colors
app . config . ColorScheme = defaultColors ( app . config . ColorScheme )
2020-09-13 11:20:11 +02:00
// Init app
app . init ( )
2020-11-18 08:57:27 +01:00
2020-06-12 12:29:57 +02:00
// Return app
return app
2020-02-21 18:07:43 +01:00
}
2021-12-31 12:32:39 -05:00
// Adds an ip address to trustedProxyRanges or trustedProxiesMap based on whether it is an IP range or not
2021-10-28 01:46:39 +03:00
func ( app * App ) handleTrustedProxy ( ipAddress string ) {
if strings . Contains ( ipAddress , "/" ) {
2021-12-31 12:32:39 -05:00
_ , ipNet , err := net . ParseCIDR ( ipAddress )
2021-10-28 01:46:39 +03:00
if err != nil {
2023-06-26 14:16:57 +08:00
log . Warnf ( "IP range %q could not be parsed: %v" , ipAddress , err )
2022-12-05 08:27:51 +01:00
} else {
app . config . trustedProxyRanges = append ( app . config . trustedProxyRanges , ipNet )
2021-10-28 01:46:39 +03:00
}
2021-12-31 12:32:39 -05:00
} else {
app . config . trustedProxiesMap [ ipAddress ] = struct { } { }
2021-10-28 01:46:39 +03:00
}
}
2022-07-13 08:48:29 +03:00
// NewCtxFunc allows to customize ctx methods as we want.
// Note: It doesn't allow adding new methods, only customizing exist methods.
func ( app * App ) NewCtxFunc ( function func ( app * App ) CustomCtx ) {
app . newCtxFunc = function
}
2024-02-02 11:56:58 +03:00
// RegisterCustomConstraint allows to register custom constraint.
func ( app * App ) RegisterCustomConstraint ( constraint CustomConstraint ) {
app . customConstraints = append ( app . customConstraints , constraint )
}
2022-08-08 10:16:08 +03:00
// You can register custom binders to use as Bind().Custom("name").
// They should be compatible with CustomBinder interface.
func ( app * App ) RegisterCustomBinder ( binder CustomBinder ) {
app . customBinders = append ( app . customBinders , binder )
}
2022-08-24 10:47:37 +03:00
// You can use SetTLSHandler to use ClientHelloInfo when using TLS with Listener.
func ( app * App ) SetTLSHandler ( tlsHandler * TLSHandler ) {
// Attach the tlsHandler to the config
app . mutex . Lock ( )
app . tlsHandler = tlsHandler
app . mutex . Unlock ( )
}
2022-09-16 14:21:40 +04:30
// Name Assign name to specific route.
2021-12-28 16:04:04 +03:00
func ( app * App ) Name ( name string ) Router {
2022-03-10 10:35:15 +03:00
app . mutex . Lock ( )
2023-06-05 12:00:51 +01:00
defer app . mutex . Unlock ( )
2022-11-09 18:03:16 +03:00
2023-06-05 12:00:51 +01:00
for _ , routes := range app . stack {
for _ , route := range routes {
2023-10-23 10:12:52 +03:00
isMethodValid := route . Method == app . latestRoute . Method || app . latestRoute . use ||
( app . latestRoute . Method == MethodGet && route . Method == MethodHead )
2023-06-05 12:00:51 +01:00
2023-10-23 10:12:52 +03:00
if route . Path == app . latestRoute . Path && isMethodValid {
route . Name = name
2023-06-05 12:00:51 +01:00
if route . group != nil {
route . Name = route . group . name + route . Name
}
}
}
2021-12-28 16:04:04 +03:00
}
2022-03-10 10:35:15 +03:00
if err := app . hooks . executeOnNameHooks ( * app . latestRoute ) ; err != nil {
panic ( err )
}
2021-12-28 16:04:04 +03:00
return app
}
2022-09-16 14:21:40 +04:30
// GetRoute Get route by name
2021-12-28 16:04:04 +03:00
func ( app * App ) GetRoute ( name string ) Route {
for _ , routes := range app . stack {
for _ , route := range routes {
if route . Name == name {
return * route
}
}
}
return Route { }
}
2022-09-27 15:02:38 +08:00
// GetRoutes Get all routes. When filterUseOption equal to true, it will filter the routes registered by the middleware.
func ( app * App ) GetRoutes ( filterUseOption ... bool ) [ ] Route {
var rs [ ] Route
var filterUse bool
if len ( filterUseOption ) != 0 {
filterUse = filterUseOption [ 0 ]
}
for _ , routes := range app . stack {
for _ , route := range routes {
if filterUse && route . use {
continue
}
rs = append ( rs , * route )
}
}
return rs
}
2020-09-14 04:54:26 +02:00
// Use registers a middleware route that will match requests
// with the provided prefix (which is optional and defaults to "/").
2022-11-03 12:55:31 +03:00
// Also, you can pass another app instance as a sub-router along a routing path.
// It's very useful to split up a large API as many independent routers and
// compose them as a single service using Use. The fiber's error handler and
// any of the fiber's sub apps are added to the application's error handlers
// to be invoked on errors that happen within the prefix route.
2020-09-13 11:20:11 +02:00
//
2022-11-03 12:55:31 +03:00
// app.Use(func(c fiber.Ctx) error {
// return c.Next()
// })
// app.Use("/api", func(c fiber.Ctx) error {
// return c.Next()
// })
// app.Use("/api", handler, func(c fiber.Ctx) error {
// return c.Next()
// })
// subApp := fiber.New()
// app.Use("/mounted-path", subApp)
2020-05-16 05:11:25 +02:00
//
2020-09-13 11:20:11 +02:00
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
2022-05-31 17:41:38 +03:00
func ( app * App ) Use ( args ... any ) Router {
2020-05-16 05:11:25 +02:00
var prefix string
2022-11-03 12:55:31 +03:00
var subApp * App
2022-11-13 18:56:34 +03:00
var prefixes [ ] string
2020-05-24 10:02:21 -04:00
var handlers [ ] Handler
2020-05-16 05:11:25 +02:00
2020-02-27 04:10:26 -05:00
for i := 0 ; i < len ( args ) ; i ++ {
switch arg := args [ i ] . ( type ) {
case string :
2020-05-16 05:11:25 +02:00
prefix = arg
2022-11-03 12:55:31 +03:00
case * App :
subApp = arg
2022-11-13 18:56:34 +03:00
case [ ] string :
prefixes = arg
2020-05-24 10:02:21 -04:00
case Handler :
2020-02-27 04:10:26 -05:00
handlers = append ( handlers , arg )
default :
2020-07-15 17:43:30 +02:00
panic ( fmt . Sprintf ( "use: invalid handler %v\n" , reflect . TypeOf ( arg ) ) )
2020-02-27 04:10:26 -05:00
}
}
2022-11-03 12:55:31 +03:00
2022-11-13 18:56:34 +03:00
if len ( prefixes ) == 0 {
prefixes = append ( prefixes , prefix )
}
for _ , prefix := range prefixes {
2022-11-27 20:34:48 +03:00
if subApp != nil {
app . mount ( prefix , subApp )
return app
}
app . register ( [ ] string { methodUse } , prefix , nil , nil , handlers ... )
2022-11-03 12:55:31 +03:00
}
2020-07-19 10:04:21 +02:00
return app
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Get registers a route for GET methods that requests a representation
// of the specified resource. Requests using GET should only retrieve data.
2022-11-01 18:45:43 +11:00
func ( app * App ) Get ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodGet } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Head registers a route for HEAD methods that asks for a response identical
// to that of a GET request, but without the response body.
2022-11-01 18:45:43 +11:00
func ( app * App ) Head ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodHead } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Post registers a route for POST methods that is used to submit an entity to the
// specified resource, often causing a change in state or side effects on the server.
2022-11-01 18:45:43 +11:00
func ( app * App ) Post ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodPost } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Put registers a route for PUT methods that replaces all current representations
// of the target resource with the request payload.
2022-11-01 18:45:43 +11:00
func ( app * App ) Put ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodPut } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Delete registers a route for DELETE methods that deletes the specified resource.
2022-11-01 18:45:43 +11:00
func ( app * App ) Delete ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodDelete } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Connect registers a route for CONNECT methods that establishes a tunnel to the
// server identified by the target resource.
2022-11-01 18:45:43 +11:00
func ( app * App ) Connect ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodConnect } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Options registers a route for OPTIONS methods that is used to describe the
// communication options for the target resource.
2022-11-01 18:45:43 +11:00
func ( app * App ) Options ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodOptions } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Trace registers a route for TRACE methods that performs a message loop-back
// test along the path to the target resource.
2022-11-01 18:45:43 +11:00
func ( app * App ) Trace ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodTrace } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-07-06 17:57:00 +02:00
// Patch registers a route for PATCH methods that is used to apply partial
// modifications to a resource.
2022-11-01 18:45:43 +11:00
func ( app * App ) Patch ( path string , handler Handler , middleware ... Handler ) Router {
return app . Add ( [ ] string { MethodPatch } , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2022-11-01 18:45:43 +11:00
// Add allows you to specify multiple HTTP methods to register a route.
func ( app * App ) Add ( methods [ ] string , path string , handler Handler , middleware ... Handler ) Router {
2023-08-05 22:02:01 +03:00
app . register ( methods , path , nil , handler , middleware ... )
2023-06-05 12:00:51 +01:00
return app
2020-05-16 05:11:25 +02:00
}
2020-09-13 11:20:11 +02:00
// Static will create a file server serving static files
2020-07-19 10:04:21 +02:00
func ( app * App ) Static ( prefix , root string , config ... Static ) Router {
2023-06-05 12:00:51 +01:00
app . registerStatic ( prefix , root , config ... )
return app
2020-05-16 05:11:25 +02:00
}
2020-09-13 11:20:11 +02:00
// All will register the handler on all HTTP methods
2022-11-01 18:45:43 +11:00
func ( app * App ) All ( path string , handler Handler , middleware ... Handler ) Router {
2022-11-27 20:34:48 +03:00
return app . Add ( app . config . RequestMethods , path , handler , middleware ... )
2020-02-21 18:07:43 +01:00
}
2020-03-24 05:31:51 +01:00
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
2022-08-08 09:21:00 +03:00
//
// api := app.Group("/api")
// api.Get("/users", handler)
2020-07-19 10:04:21 +02:00
func ( app * App ) Group ( prefix string , handlers ... Handler ) Router {
2022-11-09 18:03:16 +03:00
grp := & Group { Prefix : prefix , app : app }
2020-03-22 01:51:53 +01:00
if len ( handlers ) > 0 {
2022-11-27 20:34:48 +03:00
app . register ( [ ] string { methodUse } , prefix , grp , nil , handlers ... )
2020-05-16 05:11:25 +02:00
}
2022-03-10 10:35:15 +03:00
if err := app . hooks . executeOnGroupHooks ( * grp ) ; err != nil {
panic ( err )
}
return grp
2020-03-22 01:51:53 +01:00
}
2022-01-24 18:37:28 +03:00
// Route is used to define routes with a common prefix inside the common function.
// Uses Group method to define new sub-router.
2022-09-18 17:35:57 +08:00
func ( app * App ) Route ( path string ) Register {
// Create new route
route := & Registering { app : app , path : path }
2022-01-24 18:37:28 +03:00
2022-09-18 17:35:57 +08:00
return route
2022-01-24 18:37:28 +03:00
}
2020-09-13 11:20:11 +02:00
// Error makes it compatible with the `error` interface.
2020-06-22 15:12:50 +02:00
func ( e * Error ) Error ( ) string {
2022-08-08 09:21:00 +03:00
return e . Message
2020-06-22 15:12:50 +02:00
}
2022-08-08 09:21:00 +03:00
// NewError creates a new Error instance with an optional message
func NewError ( code int , message ... string ) * Error {
err := & Error {
2022-01-27 14:41:10 +03:00
Code : code ,
Message : utils . StatusMessage ( code ) ,
2020-09-13 11:20:11 +02:00
}
2022-08-08 09:21:00 +03:00
if len ( message ) > 0 {
err . Message = message [ 0 ]
2020-06-22 15:12:50 +02:00
}
2022-08-08 09:21:00 +03:00
return err
2022-01-10 21:22:34 +08:00
}
2020-09-13 11:20:11 +02:00
// Config returns the app config as value ( read-only ).
func ( app * App ) Config ( ) Config {
return app . config
}
2020-07-13 01:01:51 +09:00
// Handler returns the server handler.
2023-01-27 09:01:37 +01:00
func ( app * App ) Handler ( ) fasthttp . RequestHandler { //revive:disable-line:confusing-naming // Having both a Handler() (uppercase) and a handler() (lowercase) is fine. TODO: Use nolint:revive directive instead. See https://github.com/golangci/golangci-lint/issues/3476
2021-01-24 13:02:21 +01:00
// prepare the server for the start
app . startupProcess ( )
2023-03-06 17:35:39 +03:00
return app . requestHandler
2020-06-24 21:36:40 +02:00
}
2020-09-13 11:20:11 +02:00
// Stack returns the raw router stack.
2020-07-21 22:49:49 +02:00
func ( app * App ) Stack ( ) [ ] [ ] * Route {
return app . stack
}
2021-12-29 09:23:14 +03:00
// HandlersCount returns the amount of registered handlers.
func ( app * App ) HandlersCount ( ) uint32 {
2021-12-29 17:26:50 +08:00
return app . handlersCount
2021-12-29 09:23:14 +03:00
}
2020-09-13 11:20:11 +02:00
// Shutdown gracefully shuts down the server without interrupting any active connections.
2022-12-20 02:40:43 +11:00
// Shutdown works by first closing all open listeners and then waiting indefinitely for all connections to return to idle before shutting down.
2020-03-24 05:31:51 +01:00
//
// Make sure the program doesn't exit and waits instead for Shutdown to return.
//
// Shutdown does not close keepalive connections so its recommended to set ReadTimeout to something else than 0.
2020-03-31 10:03:39 +02:00
func ( app * App ) Shutdown ( ) error {
2023-04-09 15:08:03 +02:00
return app . ShutdownWithContext ( context . Background ( ) )
2022-12-20 02:40:43 +11:00
}
// ShutdownWithTimeout gracefully shuts down the server without interrupting any active connections. However, if the timeout is exceeded,
// ShutdownWithTimeout will forcefully close any active connections.
// ShutdownWithTimeout works by first closing all open listeners and then waiting for all connections to return to idle before shutting down.
//
// Make sure the program doesn't exit and waits instead for ShutdownWithTimeout to return.
//
// ShutdownWithTimeout does not close keepalive connections so its recommended to set ReadTimeout to something else than 0.
func ( app * App ) ShutdownWithTimeout ( timeout time . Duration ) error {
ctx , cancelFunc := context . WithTimeout ( context . Background ( ) , timeout )
defer cancelFunc ( )
2023-04-09 15:08:03 +02:00
return app . ShutdownWithContext ( ctx )
2022-12-20 02:40:43 +11:00
}
2023-04-09 15:08:03 +02:00
// ShutdownWithContext shuts down the server including by force if the context's deadline is exceeded.
//
// Make sure the program doesn't exit and waits instead for ShutdownWithTimeout to return.
//
// ShutdownWithContext does not close keepalive connections so its recommended to set ReadTimeout to something else than 0.
func ( app * App ) ShutdownWithContext ( ctx context . Context ) error {
2022-03-10 10:35:15 +03:00
if app . hooks != nil {
2022-09-08 08:57:05 +03:00
// TODO: check should be defered?
app . hooks . executeOnShutdownHooks ( )
2022-03-10 10:35:15 +03:00
}
2020-05-09 15:15:34 +02:00
app . mutex . Lock ( )
defer app . mutex . Unlock ( )
2020-02-21 18:07:43 +01:00
if app . server == nil {
2024-02-19 05:33:10 -08:00
return ErrNotRunning
2020-02-21 18:07:43 +01:00
}
2022-12-20 02:40:43 +11:00
return app . server . ShutdownWithContext ( ctx )
2020-02-21 18:07:43 +01:00
}
2020-09-27 23:23:28 +02:00
// Server returns the underlying fasthttp server
func ( app * App ) Server ( ) * fasthttp . Server {
return app . server
}
2022-03-10 10:35:15 +03:00
// Hooks returns the hook struct to register hooks.
2022-08-16 09:13:38 +03:00
func ( app * App ) Hooks ( ) * Hooks {
2022-03-10 10:35:15 +03:00
return app . hooks
}
2020-07-13 01:01:51 +09:00
// Test is used for internal debugging by passing a *http.Request.
2020-04-27 23:34:35 +02:00
// Timeout is optional and defaults to 1s, -1 will disable it completely.
2024-03-05 08:59:39 +01:00
func ( app * App ) Test ( req * http . Request , timeout ... time . Duration ) ( * http . Response , error ) {
2020-09-13 11:20:11 +02:00
// Set timeout
2024-03-05 08:59:39 +01:00
to := 1 * time . Second
if len ( timeout ) > 0 {
to = timeout [ 0 ]
2020-03-22 17:35:12 +01:00
}
2020-09-13 11:20:11 +02:00
2020-05-16 08:12:43 +02:00
// Add Content-Length if not provided with body
2020-09-13 11:20:11 +02:00
if req . Body != http . NoBody && req . Header . Get ( HeaderContentLength ) == "" {
req . Header . Add ( HeaderContentLength , strconv . FormatInt ( req . ContentLength , 10 ) )
2020-05-16 08:12:43 +02:00
}
2020-09-13 11:20:11 +02:00
2020-03-20 16:43:28 +01:00
// Dump raw http request
2020-09-13 11:20:11 +02:00
dump , err := httputil . DumpRequest ( req , true )
2020-02-21 18:07:43 +01:00
if err != nil {
2023-01-27 09:01:37 +01:00
return nil , fmt . Errorf ( "failed to dump request: %w" , err )
2020-02-21 18:07:43 +01:00
}
2020-09-13 11:20:11 +02:00
2020-05-12 19:24:04 +02:00
// Create test connection
conn := new ( testConn )
2020-09-13 11:20:11 +02:00
2020-03-20 16:43:28 +01:00
// Write raw http request
2023-01-27 09:01:37 +01:00
if _ , err := conn . r . Write ( dump ) ; err != nil {
return nil , fmt . Errorf ( "failed to write: %w" , err )
2020-02-21 18:07:43 +01:00
}
2021-01-24 13:02:21 +01:00
// prepare the server for the start
app . startupProcess ( )
2020-09-13 11:20:11 +02:00
2020-02-21 18:07:43 +01:00
// Serve conn to server
channel := make ( chan error )
go func ( ) {
2022-08-08 14:18:57 +08:00
var returned bool
defer func ( ) {
if ! returned {
2024-02-19 05:33:10 -08:00
channel <- ErrHandlerExited
2022-08-08 14:18:57 +08:00
}
} ( )
2020-05-12 19:24:04 +02:00
channel <- app . server . ServeConn ( conn )
2022-08-08 14:18:57 +08:00
returned = true
2020-02-21 18:07:43 +01:00
} ( )
2020-09-13 11:20:11 +02:00
2020-03-23 21:52:37 +01:00
// Wait for callback
2024-03-05 08:59:39 +01:00
if to >= 0 {
2020-04-27 23:34:35 +02:00
// With timeout
select {
case err = <- channel :
2024-03-05 08:59:39 +01:00
case <- time . After ( to ) :
return nil , fmt . Errorf ( "test: timeout error after %s" , to )
2020-02-21 18:07:43 +01:00
}
2020-04-27 23:34:35 +02:00
} else {
// Without timeout
2020-05-12 23:24:04 +02:00
err = <- channel
2020-04-27 23:34:35 +02:00
}
2020-09-13 11:20:11 +02:00
2020-04-27 23:34:35 +02:00
// Check for errors
2023-01-27 09:01:37 +01:00
if err != nil && ! errors . Is ( err , fasthttp . ErrGetOnly ) {
2020-04-27 23:34:35 +02:00
return nil , err
2020-03-24 03:43:13 +01:00
}
2020-09-13 11:20:11 +02:00
2020-03-20 16:43:28 +01:00
// Read response
2020-05-12 19:24:04 +02:00
buffer := bufio . NewReader ( & conn . w )
2020-09-13 11:20:11 +02:00
2020-03-20 16:43:28 +01:00
// Convert raw http response to *http.Response
2023-01-27 09:01:37 +01:00
res , err := http . ReadResponse ( buffer , req )
if err != nil {
return nil , fmt . Errorf ( "failed to read response: %w" , err )
}
return res , nil
2020-02-21 18:07:43 +01:00
}
2020-03-29 14:13:02 +02:00
type disableLogger struct { }
2024-03-18 06:50:40 -07:00
func ( * disableLogger ) Printf ( string , ... any ) {
2020-03-29 14:13:02 +02:00
}
2020-05-23 09:25:18 +02:00
func ( app * App ) init ( ) * App {
2020-09-13 11:20:11 +02:00
// lock application
2020-05-12 19:24:04 +02:00
app . mutex . Lock ( )
2020-08-11 00:08:04 +02:00
2021-10-05 08:03:20 -04:00
// Only load templates if a view engine is specified
2020-09-13 11:20:11 +02:00
if app . config . Views != nil {
if err := app . config . Views . Load ( ) ; err != nil {
2023-06-26 14:16:57 +08:00
log . Warnf ( "failed to load views: %v" , err )
2020-06-12 12:29:57 +02:00
}
}
2020-09-13 11:20:11 +02:00
// create fasthttp server
app . server = & fasthttp . Server {
Logger : & disableLogger { } ,
LogAllErrors : false ,
2021-10-05 08:03:20 -04:00
ErrorHandler : app . serverErrorHandler ,
2020-05-16 05:11:25 +02:00
}
2020-09-13 11:20:11 +02:00
// fasthttp server settings
2023-03-06 17:35:39 +03:00
app . server . Handler = app . requestHandler
2020-09-13 11:20:11 +02:00
app . server . Name = app . config . ServerHeader
app . server . Concurrency = app . config . Concurrency
app . server . NoDefaultDate = app . config . DisableDefaultDate
app . server . NoDefaultContentType = app . config . DisableDefaultContentType
app . server . DisableHeaderNamesNormalizing = app . config . DisableHeaderNormalizing
app . server . DisableKeepalive = app . config . DisableKeepalive
app . server . MaxRequestBodySize = app . config . BodyLimit
app . server . NoDefaultServerHeader = app . config . ServerHeader == ""
app . server . ReadTimeout = app . config . ReadTimeout
app . server . WriteTimeout = app . config . WriteTimeout
app . server . IdleTimeout = app . config . IdleTimeout
app . server . ReadBufferSize = app . config . ReadBufferSize
app . server . WriteBufferSize = app . config . WriteBufferSize
app . server . GetOnly = app . config . GETOnly
2020-10-07 11:55:17 +02:00
app . server . ReduceMemoryUsage = app . config . ReduceMemoryUsage
2021-07-11 11:45:46 +02:00
app . server . StreamRequestBody = app . config . StreamRequestBody
app . server . DisablePreParseMultipartForm = app . config . DisablePreParseMultipartForm
2020-09-13 11:20:11 +02:00
// unlock application
app . mutex . Unlock ( )
2020-05-23 09:25:18 +02:00
return app
2020-02-21 18:07:43 +01:00
}
2020-06-07 21:10:38 +02:00
2021-10-05 08:03:20 -04:00
// ErrorHandler is the application's method in charge of finding the
2021-11-05 08:00:03 +01:00
// appropriate handler for the given request. It searches any mounted
2021-10-05 08:03:20 -04:00
// sub fibers by their prefixes and if it finds a match, it uses that
// error handler. Otherwise it uses the configured error handler for
// the app, which if not set is the DefaultErrorHandler.
2022-07-13 08:48:29 +03:00
func ( app * App ) ErrorHandler ( ctx Ctx , err error ) error {
2021-10-05 08:03:20 -04:00
var (
mountedErrHandler ErrorHandler
mountedPrefixParts int
)
2022-10-25 08:51:44 +03:00
for prefix , subApp := range app . mountFields . appList {
2022-07-13 08:48:29 +03:00
if prefix != "" && strings . HasPrefix ( ctx . Path ( ) , prefix ) {
2021-10-05 08:03:20 -04:00
parts := len ( strings . Split ( prefix , "/" ) )
if mountedPrefixParts <= parts {
2022-11-15 06:13:11 -05:00
if subApp . configured . ErrorHandler != nil {
mountedErrHandler = subApp . config . ErrorHandler
}
2021-10-05 08:03:20 -04:00
mountedPrefixParts = parts
}
}
}
if mountedErrHandler != nil {
return mountedErrHandler ( ctx , err )
}
return app . config . ErrorHandler ( ctx , err )
}
// serverErrorHandler is a wrapper around the application's error handler method
// user for the fasthttp server configuration. It maps a set of fasthttp errors to fiber
// errors before calling the application's error handler method.
func ( app * App ) serverErrorHandler ( fctx * fasthttp . RequestCtx , err error ) {
2022-07-13 08:48:29 +03:00
// Acquire Ctx with fasthttp request from pool
V2 to v3 merge (#2864)
* Update pull_request_template.md
* Update v3-changes.md
* Update CONTRIBUTING.md (#2752)
Grammar correction.
* chore(encryptcookie)!: update default config (#2753)
* chore(encryptcookie)!: update default config
docs(encryptcookie): enhance documentation and examples
BREAKING CHANGE: removed the hardcoded "csrf_" from the Except.
* docs(encryptcookie): reads or modifies cookies
* chore(encryptcookie): csrf config example
* docs(encryptcookie): md table spacing
* build(deps): bump actions/setup-go from 4 to 5 (#2754)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)
---
updated-dependencies:
- dependency-name: actions/setup-go
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* 🩹 middleware/logger/: log client IP address by default (#2755)
* middleware/logger: Log client IP address by default.
* Update doc.
* fix: don't constrain middlewares' context-keys to strings :bug: (#2751)
* Revert "Revert ":bug: requestid.Config.ContextKey is interface{} (#2369)" (#2742)"
This reverts commit 28be17f929cfa7d3c27dd292fc3956f2f9882e22.
* fix: request ContextKey default value condition
Should check for `nil` since it is `any`.
* fix: don't constrain middlewares' context-keys to strings
`context` recommends using "unexported type" as context keys to avoid
collisions https://pkg.go.dev/github.com/gofiber/fiber/v2#Ctx.Locals.
The official go blog also recommends this https://go.dev/blog/context.
`fiber.Ctx.Locals(key any, value any)` correctly allows consumers to
use unexported types or e.g. strings.
But some fiber middlewares constrain their context-keys to `string` in
their "default config structs", making it impossible to use unexported
types.
This PR removes the `string` _constraint_ from all middlewares, allowing
to now use unexported types as per the official guidelines. However
the default value is still a string, so it's not a breaking change, and
anyone still using strings as context keys is not affected.
* 📚 Update app.md for indentation (#2761)
Update app.md for indentation
* build(deps): bump github.com/google/uuid from 1.4.0 to 1.5.0 (#2762)
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0)
---
updated-dependencies:
- dependency-name: github.com/google/uuid
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* build(deps): bump github/codeql-action from 2 to 3 (#2763)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)
---
updated-dependencies:
- dependency-name: github/codeql-action
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Changing default log output (#2730)
changing default log output
Closes #2729
* Update hooks.md
fix wrong hooks signature
* 🩹 Fix: CORS middleware should use the defined AllowedOriginsFunc config when AllowedOrigins is empty (#2771)
* 🐛 [Bug]: Adaptator + otelfiber issue #2641 (#2772)
* 🩹🚨 - fix for redirect with query params (#2748)
* redirect with query params did not work, fix it and add test for it
* redirect middleware - fix test typo
* ♻️ logger/middleware colorize logger error message #2593 (#2773)
* :sparkles: feat: add liveness and readiness checks (#2509)
* :sparkles: feat: add liveness and readiness checkers
* :memo: docs: add docs for liveness and readiness
* :sparkles: feat: add options method for probe checkers
* :white_check_mark: tests: add tests for liveness and readiness
* :recycle: refactor: change default endpoint values
* :recycle: refactor: change default value for liveness endpoint
* :memo: docs: add return status for liveness and readiness probes
* :recycle: refactor: change probechecker to middleware
* :memo: docs: move docs to middleware session
* :recycle: refactor: apply gofumpt formatting
* :recycle: refactor: remove unused parameter
* split config and apply a review
* apply reviews and add testcases
* add benchmark
* cleanup
* rename middleware
* fix linter
* Update docs and config values
* Revert change to IsReady
* Updates based on code review
* Update docs to match other middlewares
---------
Co-authored-by: Muhammed Efe Cetin <efectn@protonmail.com>
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: Juan Calderon-Perez <jgcalderonperez@protonmail.com>
* prepare release v2.52.0
- add more Parser tests
* fix healthcheck.md
* configure workflows for V2 branch
* configure workflows for V2 branch
* Fix default value to false in docs of QueryBool (#2811)
fix default value to false in docs of QueryBool
* update queryParser config
* Update ctx.md
* Update routing.md
* merge v2 in v3
* merge v2 in v3
* lint fixes
* :books: Doc: Fix code snippet indentation in /docs/api/middleware/keyauth.md
Removes an an extra level of indentation in line 51 of
`keyauth.md` [here](https://github.com/gofiber/fiber/blob/v2/docs/api/middleware/keyauth.md?plain=1#L51)
* fix: healthcheck middleware not working with route group (#2863)
* fix: healthcheck middleware not working with route group
* perf: change verification method to improve perf
* Update healthcheck_test.go
* test: add not matching route test for strict routing
* add more test cases
* correct tests
* correct test helpers
* correct tests
* correct tests
---------
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: René Werner <rene@gofiber.io>
* merge v2 in v3
* Merge pull request from GHSA-fmg4-x8pw-hjhg
* Enforce Wildcard Origins with AllowCredentials check
* Expand unit-tests, fix issues with subdomains logic, update docs
* Update cors.md
* Added test using localhost, ipv4, and ipv6 address
* improve documentation markdown
---------
Co-authored-by: René Werner <rene@gofiber.io>
* Update app.go
prepare release v2.52.1
* fix cors domain normalize
* fix sync-docs workflow
* test: fix failing tests
* fix sync-docs workflow
* test: cors middleware use testify require
* chore: fix lint warnings
* chore: revert test isolation.
* fixed the fasthttp ctx race condition problem
* Update middleware/cors/utils.go
Co-authored-by: Renan Bastos <renanbastos.tec@gmail.com>
* fix sync_docs.sh
* fix review comments/hints
* fix review comments/hints
* stabilize Test_Proxy_Timeout_Slow_Server test
* stabilize Test_Proxy_.* tests
* ignore bodyclose linter for tests
use http.NoBody instead of nil
* revert(tests): undo http.NoBody usage
* fix(ctx pool): postpone the reset for some values
shortly before the release in the pool
* refactor(tests): use testify panic method instead of custom solution
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: tokelo-12 <113810058+tokelo-12@users.noreply.github.com>
Co-authored-by: Jason McNeil <sixcolors@mac.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: iRedMail <2048991+iredmail@users.noreply.github.com>
Co-authored-by: Benjamin Grosse <ste3ls@gmail.com>
Co-authored-by: Mehmet Firat KOMURCU <mehmetfiratkomurcu@hotmail.com>
Co-authored-by: Bruno <bdm2943@icloud.com>
Co-authored-by: Muhammad Kholid B <muhammadkholidb@gmail.com>
Co-authored-by: gilwo <gilwo@users.noreply.github.com>
Co-authored-by: Lucas Lemos <lucashenriqueblemos@gmail.com>
Co-authored-by: Muhammed Efe Cetin <efectn@protonmail.com>
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: Juan Calderon-Perez <jgcalderonperez@protonmail.com>
Co-authored-by: Jongmin Kim <kjongmin26@gmail.com>
Co-authored-by: Giovanni Rivera <rivera.giovanni271@gmail.com>
Co-authored-by: Renan Bastos <renanbastos.tec@gmail.com>
2024-02-29 08:29:59 +01:00
c := app . AcquireCtx ( fctx )
2023-02-09 22:33:45 +03:00
defer app . ReleaseCtx ( c )
2023-04-21 13:41:19 +02:00
var (
errNetOP * net . OpError
netErr net . Error
)
2023-01-27 09:01:37 +01:00
switch {
case errors . As ( err , new ( * fasthttp . ErrSmallBuffer ) ) :
2021-10-05 08:03:20 -04:00
err = ErrRequestHeaderFieldsTooLarge
2023-01-27 09:01:37 +01:00
case errors . As ( err , & errNetOP ) && errNetOP . Timeout ( ) :
2021-10-05 08:03:20 -04:00
err = ErrRequestTimeout
2023-04-21 13:41:19 +02:00
case errors . As ( err , & netErr ) :
err = ErrBadGateway
2023-01-27 09:01:37 +01:00
case errors . Is ( err , fasthttp . ErrBodyTooLarge ) :
2021-10-05 08:03:20 -04:00
err = ErrRequestEntityTooLarge
2023-01-27 09:01:37 +01:00
case errors . Is ( err , fasthttp . ErrGetOnly ) :
2021-10-05 08:03:20 -04:00
err = ErrMethodNotAllowed
2023-01-27 09:01:37 +01:00
case strings . Contains ( err . Error ( ) , "timeout" ) :
2021-10-05 08:03:20 -04:00
err = ErrRequestTimeout
2023-01-27 09:01:37 +01:00
default :
2022-12-11 02:28:39 +08:00
err = NewError ( StatusBadRequest , err . Error ( ) )
2021-10-05 08:03:20 -04:00
}
if catch := app . ErrorHandler ( c , err ) ; catch != nil {
2023-06-26 14:16:57 +08:00
log . Errorf ( "serverErrorHandler: failed to call ErrorHandler: %v" , catch )
2023-01-27 09:01:37 +01:00
_ = c . SendStatus ( StatusInternalServerError ) //nolint:errcheck // It is fine to ignore the error here
return
2021-10-05 08:03:20 -04:00
}
}
2021-01-24 13:02:21 +01:00
// startupProcess Is the method which executes all the necessary processes just before the start of the server.
func ( app * App ) startupProcess ( ) * App {
app . mutex . Lock ( )
2022-10-25 08:51:44 +03:00
defer app . mutex . Unlock ( )
2023-04-13 14:19:04 +02:00
app . mountStartupProcess ( )
2022-10-25 08:51:44 +03:00
// build route tree stack
2021-01-24 13:02:21 +01:00
app . buildTree ( )
2022-10-25 08:51:44 +03:00
2021-01-24 13:02:21 +01:00
return app
}
2023-06-09 23:42:50 +03:00
// Run onListen hooks. If they return an error, panic.
2023-06-19 14:41:22 +03:30
func ( app * App ) runOnListenHooks ( listenData ListenData ) {
if err := app . hooks . executeOnListenHooks ( listenData ) ; err != nil {
2023-06-09 23:42:50 +03:00
panic ( err )
}
}