diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 00000000..4c395efb Binary files /dev/null and b/logo.jpg differ diff --git a/router.go b/router.go index e9512fb8..b391c9be 100644 --- a/router.go +++ b/router.go @@ -291,296 +291,3 @@ func (r *Fiber) Listen(port int) { panic(err) } } -package fiber - -import ( - "fmt" - "regexp" - "time" - - "github.com/valyala/fasthttp" -) - -type route struct { - method string - path string - anyPath bool - regex *regexp.Regexp - params []string - handler func(*Context) -} - -// Settings : -type Settings struct { - TLSEnable bool - CertKey string - CertFile string - Name string - Concurrency int - DisableKeepAlive bool - ReadBufferSize int - WriteBufferSize int - WriteTimeout time.Duration - IdleTimeout time.Duration - MaxConnsPerIP int - MaxRequestsPerConn int - TCPKeepalive bool - TCPKeepalivePeriod time.Duration - MaxRequestBodySize int - ReduceMemoryUsage bool - GetOnly bool - DisableHeaderNamesNormalizing bool - SleepWhenConcurrencyLimitsExceeded time.Duration - NoDefaultServerHeader bool - NoDefaultContentType bool - KeepHijackedConns bool -} - -// Fiber : -type Fiber struct { - routes []*route - methods []string - Settings *Settings -} - -// New : -func New() *Fiber { - return &Fiber{ - methods: []string{"GET", "PUT", "POST", "DELETE", "HEAD", "PATCH", "OPTIONS", "TRACE", "CONNECT"}, - Settings: &Settings{ - TLSEnable: false, - CertKey: "", - CertFile: "", - Name: "", - Concurrency: 256 * 1024, - DisableKeepAlive: false, - ReadBufferSize: 4096, - WriteBufferSize: 4096, - WriteTimeout: 0, - IdleTimeout: 0, - MaxConnsPerIP: 0, - MaxRequestsPerConn: 0, - TCPKeepalive: false, - TCPKeepalivePeriod: 0, - MaxRequestBodySize: 4 * 1024 * 1024, - ReduceMemoryUsage: false, - GetOnly: false, - DisableHeaderNamesNormalizing: false, - SleepWhenConcurrencyLimitsExceeded: 0, - NoDefaultServerHeader: true, - NoDefaultContentType: false, - KeepHijackedConns: false, - }, - } -} - -// Get : -func (r *Fiber) Get(args ...interface{}) { - r.register("GET", args...) -} - -// Put : -func (r *Fiber) Put(args ...interface{}) { - r.register("PUT", args...) -} - -// Post : -func (r *Fiber) Post(args ...interface{}) { - r.register("POST", args...) -} - -// Delete : -func (r *Fiber) Delete(args ...interface{}) { - r.register("DELETE", args...) -} - -// Head : -func (r *Fiber) Head(args ...interface{}) { - r.register("HEAD", args...) -} - -// Patch : -func (r *Fiber) Patch(args ...interface{}) { - r.register("PATCH", args...) -} - -// Options : -func (r *Fiber) Options(args ...interface{}) { - r.register("OPTIONS", args...) -} - -// Trace : -func (r *Fiber) Trace(args ...interface{}) { - r.register("TRACE", args...) -} - -// Connect : -func (r *Fiber) Connect(args ...interface{}) { - r.register("CONNECT", args...) -} - -// All : -func (r *Fiber) All(args ...interface{}) { - r.register("*", args...) - // for _, method := range r.methods { - // r.register(method, args...) - // } -} - -// Use : -func (r *Fiber) Use(args ...interface{}) { - r.register("*", args...) - // for _, method := range r.methods { - // r.register(method, args...) - // } -} - -// register : -func (r *Fiber) register(method string, args ...interface{}) { - // Pre-set variables for interface assertion - var ok bool - var path string - var handler func(*Context) - // Register only handler: app.Get(handler) - if len(args) == 1 { - // Convert interface to func(*Context) - handler, ok = args[0].(func(*Context)) - if !ok { - panic("Invalid handler must be func(*express.Context)") - } - } - // Register path and handler: app.Get(path, handler) - if len(args) == 2 { - // Convert interface to path string - path, ok = args[0].(string) - if !ok { - panic("Invalid path") - } - // Panic if first char does not begins with / or * - if path[0] != '/' && path[0] != '*' { - panic("Invalid path, must begin with slash '/' or wildcard '*'") - } - // Convert interface to func(*Context) - handler, ok = args[1].(func(*Context)) - if !ok { - panic("Invalid handler, must be func(*express.Context)") - } - } - // If its a simple wildcard ( aka match anything ) - if path == "" || path == "*" || path == "/*" { - r.routes = append(r.routes, &route{method, path, true, nil, nil, handler}) - return - } - // Get params from path - params := getParams(path) - // If path has no params, we dont need regex - if len(params) == 0 { - r.routes = append(r.routes, &route{method, path, false, nil, nil, handler}) - return - } - - // Compile regix from path - regex, err := getRegex(path) - if err != nil { - panic("Invalid url pattern: " + path) - } - r.routes = append(r.routes, &route{method, path, false, regex, params, handler}) -} - -// handler : -func (r *Fiber) handler(fctx *fasthttp.RequestCtx) { - // get custom context from sync pool - ctx := acquireCtx(fctx) - // get path and method from main context - path := ctx.Path() - method := ctx.Method() - // loop trough routes - for _, route := range r.routes { - // Skip route if method is not allowed - if route.method != "*" && route.method != method { - continue - } - // First check if we match a static path or wildcard - if route.anyPath || (route.path == path && route.params == nil) { - // If * always set the path to the wildcard parameter - if route.anyPath { - ctx.params = &[]string{"*"} - ctx.values = []string{path} - } - // Execute handler with context - route.handler(ctx) - // if next is not set, leave loop and release ctx - if !ctx.next { - break - } - // set next to false for next iteration - ctx.next = false - // continue to go to the next route - continue - } - // Skip route if regex does not match - if route.regex == nil || !route.regex.MatchString(path) { - continue - } - // If we have parameters, lets find the matches - if route.params != nil && len(route.params) > 0 { - matches := route.regex.FindAllStringSubmatch(path, -1) - // If we have matches, add params and values to context - if len(matches) > 0 && len(matches[0]) > 1 { - ctx.params = &route.params - ctx.values = matches[0][1:len(matches[0])] - } - } - // Execute handler with context - route.handler(ctx) - // if next is not set, leave loop and release ctx - if !ctx.next { - break - } - // set next to false for next iteration - ctx.next = false - } - // release context back into sync pool - releaseCtx(ctx) -} - -// Listen : -func (r *Fiber) Listen(port int) { - // Disable server header if server name is not given - if r.Settings.Name != "" { - r.Settings.NoDefaultServerHeader = false - } - server := &fasthttp.Server{ - // Express custom handler - Handler: r.handler, - // Server settings - Name: r.Settings.Name, - Concurrency: r.Settings.Concurrency, - DisableKeepalive: r.Settings.DisableKeepAlive, - ReadBufferSize: r.Settings.ReadBufferSize, - WriteBufferSize: r.Settings.WriteBufferSize, - WriteTimeout: r.Settings.WriteTimeout, - IdleTimeout: r.Settings.IdleTimeout, - MaxConnsPerIP: r.Settings.MaxConnsPerIP, - MaxRequestsPerConn: r.Settings.MaxRequestsPerConn, - TCPKeepalive: r.Settings.TCPKeepalive, - TCPKeepalivePeriod: r.Settings.TCPKeepalivePeriod, - MaxRequestBodySize: r.Settings.MaxRequestBodySize, - ReduceMemoryUsage: r.Settings.ReduceMemoryUsage, - GetOnly: r.Settings.GetOnly, - DisableHeaderNamesNormalizing: r.Settings.DisableHeaderNamesNormalizing, - SleepWhenConcurrencyLimitsExceeded: r.Settings.SleepWhenConcurrencyLimitsExceeded, - NoDefaultServerHeader: r.Settings.NoDefaultServerHeader, - NoDefaultContentType: r.Settings.NoDefaultContentType, - KeepHijackedConns: r.Settings.KeepHijackedConns, - } - if r.Settings.TLSEnable { - if err := server.ListenAndServeTLS(fmt.Sprintf(":%v", port), r.Settings.CertFile, r.Settings.CertKey); err != nil { - panic(err) - } - return - } - if err := server.ListenAndServe(fmt.Sprintf(":%v", port)); err != nil { - panic(err) - } -}