1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-14 13:46:23 +00:00

More cleaning

This commit is contained in:
Fenny 2020-03-24 05:31:51 +01:00
parent b52d702616
commit 3c8f582cad
5 changed files with 109 additions and 110 deletions

View File

@ -28,7 +28,7 @@ import (
// It has methods for the request query string, parameters, body, HTTP headers and so on.
// For more information please visit our documentation: https://fiber.wiki/context
type Ctx struct {
app *App // Reference to *App
app *Fiber // Reference to *Fiber
route *Route // Reference to *Route
index int // Index of the current stack
method string // HTTP method

View File

@ -23,99 +23,90 @@ import (
fasthttp "github.com/valyala/fasthttp"
)
// Version of Fiber
// Version of current package
const Version = "1.8.42"
type (
// App denotes the Fiber application.
App struct {
server *fasthttp.Server // Fasthttp server settings
routes []*Route // Route stack
child bool // If current process is a child ( for prefork )
Settings *Settings // Fiber settings
}
// Map defines a generic map of type `map[string]interface{}`.
Map map[string]interface{}
// Settings is a struct holding the server settings
Settings struct {
// This will spawn multiple Go processes listening on the same port
Prefork bool // Default: false / Spawns Multiple Go processes listening on the same port`default:"false"`
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different.
StrictRouting bool `default:"false"`
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes.
CaseSensitive bool `default:"false"`
// Enables the "Server: value" HTTP header.
ServerHeader string `default:""`
// Enables handler values to be immutable even if you return from handler
Immutable bool `default:"false"`
// Max body size that the server accepts
BodyLimit int `default:"4 * 1024 * 1024"`
// Folder containing template files
TemplateFolder string `default:""`
// Template engine: html, amber, handlebars , mustache or pug
TemplateEngine func(raw string, bind interface{}) (string, error) `default:"nil"`
// Extension for the template files
TemplateExtension string `default:""`
// The amount of time allowed to read the full request including body.
// The connection's read deadline is reset when the connection opens, or for
// keep-alive connections after the first byte has been read.
// Default timeout is unlimited.
ReadTimeout time.Duration
// The maximum duration before timing out writes of the response.
// It is reset after the request handler has returned.
// Default timeout is unlimited.
WriteTimeout time.Duration
// The maximum amount of time to wait for the next request when keep-alive is enabled.
// If IdleTimeout is zero, the value of ReadTimeout is used.
IdleTimeout time.Duration
}
)
// Map is a shortcut for map[string]interface{}
type Map map[string]interface{}
// Fiber denotes the Fiber application.
type Fiber struct {
server *fasthttp.Server // FastHTTP server
routes []*Route // Route stack
Settings *Settings // Fiber settings
}
// Settings holds is a struct holding the server settings
type Settings struct {
// This will spawn multiple Go processes listening on the same port
Prefork bool // default: false
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different.
StrictRouting bool // default: false
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes.
CaseSensitive bool // default: false
// Enables the "Server: value" HTTP header.
ServerHeader string // default: ""
// Enables handler values to be immutable even if you return from handler
Immutable bool // default: false
// Max body size that the server accepts
BodyLimit int // default: 4 * 1024 * 1024
// Folder containing template files
TemplateFolder string // default: ""
// Template engine: html, amber, handlebars , mustache or pug
TemplateEngine func(raw string, bind interface{}) (string, error) // default: nil
// Extension for the template files
TemplateExtension string // default: ""
// The amount of time allowed to read the full request including body.
ReadTimeout time.Duration // default: unlimited
// The maximum duration before timing out writes of the response.
WriteTimeout time.Duration // default: unlimited
// The maximum amount of time to wait for the next request when keep-alive is enabled.
IdleTimeout time.Duration // default: unlimited
}
// Group struct
type Group struct {
prefix string
app *App
app *Fiber
}
// This method creates a new Fiber named instance.
// New creates a new Fiber named instance.
// You can pass optional settings when creating a new instance.
func New(settings ...*Settings) *App {
var prefork, child bool
// Loop trought args without using flag.Parse()
func New(settings ...*Settings) *Fiber {
// Parse arguments
for _, v := range os.Args[1:] {
if v == "-prefork" {
prefork = true
isPrefork = true
} else if v == "-child" {
child = true
isChild = true
}
}
// Create default app
app := &App{
child: child,
Settings: &Settings{
Prefork: prefork,
BodyLimit: 4 * 1024 * 1024,
},
}
// Create app
app := new(Fiber)
// Create settings
app.Settings = new(Settings)
// Set default settings
app.Settings.Prefork = isPrefork
app.Settings.BodyLimit = 4 * 1024 * 1024
// If settings exist, set some defaults
if len(settings) > 0 {
app.Settings = settings[0] // Set custom settings
if !app.Settings.Prefork { // Default to -prefork flag if false
app.Settings.Prefork = prefork
app.Settings.Prefork = isPrefork
}
if app.Settings.BodyLimit == 0 { // Default MaxRequestBodySize
app.Settings.BodyLimit = 4 * 1024 * 1024
}
if app.Settings.Immutable { // Replace unsafe conversion funcs
getString = func(b []byte) string { return string(b) }
getBytes = func(s string) []byte { return []byte(s) }
getString = getStringImmutable
getBytes = getBytesImmutable
}
}
return app
}
// You can group routes by creating a *Group struct.
func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
func (app *Fiber) Group(prefix string, handlers ...func(*Ctx)) *Group {
if len(handlers) > 0 {
app.registerMethod("USE", prefix, handlers...)
}
@ -125,7 +116,7 @@ func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
}
}
// Settings struct for serving static files
// Static struct
type Static struct {
// Transparently compresses responses if set to true
// This works differently than the github.com/gofiber/compression middleware
@ -144,15 +135,16 @@ type Static struct {
Index string
}
// Serve static files such as images, CSS and JavaScript files, you can use the Static method.
func (app *App) Static(prefix, root string, config ...Static) *App {
// Static registers a new route with path prefix to serve static files from the provided root directory.
func (app *Fiber) Static(prefix, root string, config ...Static) *Fiber {
app.registerStatic(prefix, root, config...)
return app
}
// Use only match requests starting with the specified prefix
// It's optional to provide a prefix, default: "/"
func (app *App) Use(args ...interface{}) *App {
// Use registers a middleware route.
// Middleware matches requests beginning with the provided prefix.
// Providing a prefix is optional, it defaults to "/"
func (app *Fiber) Use(args ...interface{}) *Fiber {
var path = ""
var handlers []func(*Ctx)
for i := 0; i < len(args); i++ {
@ -170,66 +162,66 @@ func (app *App) Use(args ...interface{}) *App {
}
// Connect : https://fiber.wiki/application#http-methods
func (app *App) Connect(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Connect(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodConnect, path, handlers...)
return app
}
// Put : https://fiber.wiki/application#http-methods
func (app *App) Put(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Put(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodPut, path, handlers...)
return app
}
// Post : https://fiber.wiki/application#http-methods
func (app *App) Post(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Post(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodPost, path, handlers...)
return app
}
// Delete : https://fiber.wiki/application#http-methods
func (app *App) Delete(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Delete(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodDelete, path, handlers...)
return app
}
// Head : https://fiber.wiki/application#http-methods
func (app *App) Head(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Head(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodHead, path, handlers...)
return app
}
// Patch : https://fiber.wiki/application#http-methods
func (app *App) Patch(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Patch(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodPatch, path, handlers...)
return app
}
// Options : https://fiber.wiki/application#http-methods
func (app *App) Options(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Options(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodOptions, path, handlers...)
return app
}
// Trace : https://fiber.wiki/application#http-methods
func (app *App) Trace(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Trace(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodTrace, path, handlers...)
return app
}
// Get : https://fiber.wiki/application#http-methods
func (app *App) Get(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) Get(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod(MethodGet, path, handlers...)
return app
}
// All matches all HTTP methods and complete paths
func (app *App) All(path string, handlers ...func(*Ctx)) *App {
func (app *Fiber) All(path string, handlers ...func(*Ctx)) *Fiber {
app.registerMethod("ALL", path, handlers...)
return app
}
// Group : https://fiber.wiki/application#group
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
prefix = groupPaths(grp.prefix, prefix)
if len(handlers) > 0 {
@ -248,8 +240,9 @@ func (grp *Group) Static(prefix, root string, config ...Static) *Group {
return grp
}
// Use only match requests starting with the specified prefix
// It's optional to provide a prefix, default: "/"
// Use registers a middleware route.
// Middleware matches requests beginning with the provided prefix.
// Providing a prefix is optional, it defaults to "/"
func (grp *Group) Use(args ...interface{}) *Group {
var path = ""
var handlers []func(*Ctx)
@ -327,8 +320,9 @@ func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
return grp
}
// Listen : https://fiber.wiki/application#listen
func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
// Listen serves HTTP requests from the given addr or port.
// You can pass an optional *tls.Config to enable TLS.
func (app *Fiber) Listen(address interface{}, tlsconfig ...*tls.Config) error {
addr, ok := address.(string)
if !ok {
port, ok := address.(int)
@ -343,7 +337,7 @@ func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
// Create fasthttp server
app.server = app.newServer()
// Print listening message
if !app.child {
if !isChild {
fmt.Printf("Fiber v%s listening on %s\n", Version, addr)
}
var ln net.Listener
@ -366,24 +360,29 @@ func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
return app.server.Serve(ln)
}
// Shutdown : TODO: Docs
// Shutsdown the server gracefully
func (app *App) Shutdown() error {
// Shutdown gracefully shuts down the server without interrupting any active connections.
// Shutdown works by first closing all open listeners and then waiting indefinitely for all connections to return to idle and then shut down.
//
// When Shutdown is called, Serve, ListenAndServe, and ListenAndServeTLS immediately return nil.
// 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.
func (app *Fiber) Shutdown() error {
if app.server == nil {
return fmt.Errorf("Server is not running")
}
return app.server.Shutdown()
}
// Test : https://fiber.wiki/application#test
func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, error) {
// Test is used for internal debugging by passing a *http.Request.
// Timeout is optional and defaults to 200ms, -1 will disable it completely.
func (app *Fiber) Test(request *http.Request, msTimeout ...int) (*http.Response, error) {
timeout := 200
if len(msTimeout) > 0 {
timeout = msTimeout[0]
}
// if timeout equals -1 we extend the timeout to 10 minutes
if timeout < 0 {
timeout = 600000 // 10 minutes
timeout = 60000 // 1 minute
}
// Dump raw http request
dump, err := httputil.DumpRequest(request, true)
@ -424,9 +423,9 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e
}
// https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/
func (app *App) prefork(address string) (ln net.Listener, err error) {
func (app *Fiber) prefork(address string) (ln net.Listener, err error) {
// Master proc
if !app.child {
if !isChild {
addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
return ln, err
@ -465,13 +464,7 @@ func (app *App) prefork(address string) (ln net.Listener, err error) {
return ln, err
}
type customLogger struct{}
func (cl *customLogger) Printf(format string, args ...interface{}) {
// fmt.Println(fmt.Sprintf(format, args...))
}
func (app *App) newServer() *fasthttp.Server {
func (app *Fiber) newServer() *fasthttp.Server {
return &fasthttp.Server{
Handler: app.handler,
Name: app.Settings.ServerHeader,
@ -480,7 +473,6 @@ func (app *App) newServer() *fasthttp.Server {
ReadTimeout: app.Settings.ReadTimeout,
WriteTimeout: app.Settings.WriteTimeout,
IdleTimeout: app.Settings.IdleTimeout,
Logger: &customLogger{},
LogAllErrors: false,
ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) {
if err.Error() == "body size exceeds the given limit" {

View File

@ -11,7 +11,7 @@ import (
var handler = func(c *Ctx) {}
func is200(t *testing.T, app *App, url string, m ...string) {
func is200(t *testing.T, app *Fiber, url string, m ...string) {
method := "GET"
if len(m) > 0 {

View File

@ -31,7 +31,7 @@ type Route struct {
Handler func(*Ctx) // ctx handler
}
func (app *App) nextRoute(ctx *Ctx) {
func (app *Fiber) nextRoute(ctx *Ctx) {
// Keep track of head matches
lenr := len(app.routes) - 1
for ctx.index < lenr {
@ -101,7 +101,7 @@ func (r *Route) matchRoute(method, path string) (match bool, values []string) {
return false, values
}
func (app *App) handler(fctx *fasthttp.RequestCtx) {
func (app *Fiber) handler(fctx *fasthttp.RequestCtx) {
// get fiber context from sync pool
ctx := acquireCtx(fctx)
defer releaseCtx(ctx)
@ -120,7 +120,7 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) {
app.nextRoute(ctx)
}
func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
func (app *Fiber) registerMethod(method, path string, handlers ...func(*Ctx)) {
// Route requires atleast one handler
if len(handlers) == 0 {
log.Fatalf("Missing handler in route")
@ -185,7 +185,7 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
}
}
func (app *App) registerStatic(prefix, root string, config ...Static) {
func (app *Fiber) registerStatic(prefix, root string, config ...Static) {
// Cannot have an empty prefix
if prefix == "" {
prefix = "/"

View File

@ -19,6 +19,7 @@ import (
jsoniter "github.com/json-iterator/go"
)
var isPrefork, isChild bool
var jsonParser = jsoniter.ConfigCompatibleWithStandardLibrary
var schemaDecoder = schema.NewDecoder()
@ -107,6 +108,9 @@ func getMIME(extension string) (mime string) {
var getString = func(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
var getStringImmutable = func(b []byte) string {
return string(b)
}
// #nosec G103
// getBytes converts string to a byte slice without memory allocation.
@ -114,6 +118,9 @@ var getString = func(b []byte) string {
var getBytes = func(s string) (b []byte) {
return *(*[]byte)(unsafe.Pointer(&s))
}
var getBytesImmutable = func(s string) (b []byte) {
return []byte(s)
}
// https://golang.org/src/net/net.go#L113
// Helper methods for application#test