pull/6/head
Fenny 2020-01-16 00:24:58 +01:00
parent 8d790b5cf0
commit 9b6630cc9e
9 changed files with 82 additions and 59 deletions

View File

@ -2,7 +2,7 @@
// 📌 Don't use in production until version 1.0.0
// 🖥 https://github.com/fenny/fiber
// 🦸 Not all heroes wear capes, thank you +1000
// 🦸 Not all heroes wear capes, thank you to some amazing people
// 💖 @valyala, @dgrr, @erikdubbelboer, @savsgio, @julienschmidt
package fiber

View File

@ -8,8 +8,6 @@ app := fiber.New()
// Optional fiber settings
// Sends the "Server" header, disabled by default
app.Server = ""
// Clears console when launched, disabled by default
app.ClearConsole = false
// Hides fiber banner, enabled by default
app.NoBanner = false
```

View File

@ -49,16 +49,16 @@ Route definition takes the following structures:
```go
// Function signature
app.Method(path string, static string)
app.Method(path string, Static(root string))
app.Method(path string, func(*fiber.Ctx))
app.Method(static string)
app.Method(Static(root string))
app.Method(func(*fiber.Ctx))
```
* **app** is an instance of **[Fiber](#hello-world)**.
* **Method** is an [HTTP request method](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods), in capitalization: Get, Put, Post etc
* **path string** is a path or prefix (for static files) on the server.
* **static string** is a file path or directory.
* **Static(root string)** is a file path or directory.
* **func(*fiber.Ctx)** is a function executed when the route is matched.
This tutorial assumes that an instance of fiber named app is created and the server is running. If you are not familiar with creating an app and starting it, see the [Hello world](#hello-world) example.
@ -90,13 +90,13 @@ app.Delete("/user", func(c *fiber.Ctx) {
To serve static files such as images, CSS files, and JavaScript files, replace your function handler with a file or directory string.
```go
// Function signature
app.Method(static string)
app.Method(path string, static string)
app.Method(Static(root string))
app.Method(path string, Static(root string))
```
For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public:
```go
app.Get("./public")
app.Get(fiber.Static("./public"))
```
Now, you can load the files that are in the public directory:
```shell
@ -108,14 +108,14 @@ http://localhost:8080/hello.html
```
To use multiple static assets directories, call the express.static middleware function multiple times:
```go
app.Get("./public")
app.Get("./files")
app.Get(fiber.Static("./public"))
app.Get(fiber.Static("./files"))
```
?>For best results, use a reverse proxy cache like [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) to improve performance of serving static assets.
To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below:
```go
app.Get("/static", "./public")
app.Get("/static", fiber.Static("./public"))
```
Now, you can load the files that are in the public directory from the /static path prefix.
```shell

View File

@ -18,7 +18,7 @@
<script>
window.$docsify = {
name: 'Fiber v0.6.2',
name: 'Fiber v0.6.9',
repo: 'fenny/fiber',
loadSidebar: "sidebar.md",
homepage: 'getting_started.md',

View File

@ -6,8 +6,8 @@ import (
"github.com/fenny/fiber"
)
// Cors :
// Cors : Enable cross-origin resource sharing (CORS) with various options.
func Cors(c *fiber.Ctx) {
fmt.Println("LoL")
fmt.Println("Cors is still under development, disable until v1.0.0")
c.Next()
}

13
middleware/helmet.go Normal file
View File

@ -0,0 +1,13 @@
package middleware
import (
"fmt"
"github.com/fenny/fiber"
)
// Helmet : Helps secure your apps by setting various HTTP headers.
func Helmet(c *fiber.Ctx) {
fmt.Println("Helmet is still under development, disable until v1.0.0")
c.Next()
}

View File

@ -2,19 +2,15 @@
// 📌 Don't use in production until version 1.0.0
// 🖥 https://github.com/fenny/fiber
// 🦸 Not all heroes wear capes, thank you +1000
// 🦸 Not all heroes wear capes, thank you to some amazing people
// 💖 @valyala, @dgrr, @erikdubbelboer, @savsgio, @julienschmidt
package fiber
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
"runtime"
"strconv"
"strings"
"time"
@ -26,7 +22,7 @@ import (
const (
// Version for debugging
Version = `0.6.2`
Version = `0.6.9`
// Port and Version are printed with the banner
banner = `%s _____ _ _
%s| __|_| |_ ___ ___
@ -60,8 +56,6 @@ type Fiber struct {
CertFile string
// Disable the fiber banner on launch
NoBanner bool
// Clears terminal on launch
ClearTerminal bool
}
type route struct {
@ -112,8 +106,6 @@ func New() *Fiber {
CertFile: "",
// Fiber banner is printed by default
NoBanner: false,
// Terminal is not cleared by default
ClearTerminal: false,
Fasthttp: &Fasthttp{
// Default fasthttp settings
// https://github.com/valyala/fasthttp/blob/master/server.go#L150
@ -202,93 +194,124 @@ func (r *Fiber) Use(args ...interface{}) {
r.All(args...)
}
type staticHandler struct {
root string
}
// Static :
func Static(root string) staticHandler {
return staticHandler{
root: root,
}
}
// Function to add a route correctly
func (r *Fiber) register(method string, args ...interface{}) {
// Options
var path string
var static string
var handler func(*Ctx)
// app.Get(handler)
// Prepare possible variables
var path string // We could have a path/prefix
var static staticHandler // We could have a static handler
var handler func(*Ctx) // We could have a ctx handler
// Only 1 argument, so no path/prefix
if len(args) == 1 {
// Is it a static or ctx handler?
switch arg := args[0].(type) {
case string:
static = arg
case func(*Ctx):
handler = arg
case staticHandler:
static = arg
}
}
// app.Get(path, handler)
if len(args) == 2 {
// More than 1 argument, we have a path/prefix + static/ctx handler
if len(args) > 1 {
// Lets get the path/prefix first
path = args[0].(string)
// Path must start with a / or *
if path[0] != '/' && path[0] != '*' {
panic("Invalid path, must begin with slash '/' or wildcard '*'")
}
// Is the second argument a static or ctx handler?
switch arg := args[1].(type) {
case string:
static = arg
case func(*Ctx):
handler = arg
case staticHandler:
static = arg
}
}
// Is this a static file handler?
if static != "" {
// static file route!!
// Let's see what we go to call the correct register function
// If the static handler contains a root string
if static.root != "" {
// Register the static handler
r.registerStatic(method, path, static)
} else if handler != nil {
// function route!!
// Register the default ctx handler
r.registerHandler(method, path, handler)
} else {
fmt.Println(reflect.TypeOf(handler))
// No static nor ctx handler provided :()
panic("Every route needs to contain either a dir/file path or callback function")
}
}
func (r *Fiber) registerStatic(method, prefix, root string) {
func (r *Fiber) registerStatic(method, prefix string, static staticHandler) {
// Lets see if this route needs to match all
// This only applies to single files, cant serve multiple on one route
var wildcard bool
if prefix == "*" || prefix == "/*" {
wildcard = true
}
// If no prefix is given, default is / => /file.txt
if prefix == "" {
prefix = "/"
}
files, _, err := walkDir(root)
// Lets get all files from path / di
files, _, err := walkDir(static.root)
if err != nil {
panic(err)
}
mount := filepath.Clean(root)
// ./static/compiled => static/compiled
mount := filepath.Clean(static.root)
// Loop over all files
for _, file := range files {
// Ignore the .gzipped files by fasthttp
if strings.Contains(file, ".fasthttp.gz") {
continue
}
// Time to create a fake path for the route match
// static/index.html => /index.html
path := filepath.Join(prefix, strings.Replace(file, mount, "", 1))
// Store original file path to use in ctx handler
filePath := file
// If the file is an index.html, bind the prefix to index.html directly
if filepath.Base(filePath) == "index.html" {
r.routes = append(r.routes, &route{method, prefix, wildcard, nil, nil, func(c *Ctx) {
c.SendFile(filePath)
}})
}
// Add the route + SendFile(filepath) to routes
r.routes = append(r.routes, &route{method, path, wildcard, nil, nil, func(c *Ctx) {
c.SendFile(filePath)
}})
}
}
func (r *Fiber) registerHandler(method, path string, handler func(*Ctx)) {
// If the route needs to match any path
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 path has no params (simple path), 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
// We have parametes, so we need to compile regix from the path
regex, err := getRegex(path)
if err != nil {
panic("Invalid url pattern: " + path)
}
// Add regex + params to route
r.routes = append(r.routes, &route{method, path, false, regex, params, handler})
}
@ -402,17 +425,6 @@ func (r *Fiber) Listen(port int, addr ...string) {
NoDefaultContentType: r.Fasthttp.NoDefaultContentType,
KeepHijackedConns: r.Fasthttp.KeepHijackedConns,
}
if r.ClearTerminal {
if runtime.GOOS == "linux" {
cmd := exec.Command("clear")
cmd.Stdout = os.Stdout
cmd.Run()
} else if runtime.GOOS == "windows" {
cmd := exec.Command("cmd", "/c", "cls")
cmd.Stdout = os.Stdout
cmd.Run()
}
}
if !r.NoBanner {
fmt.Printf(banner, cGreen, cGreen, cGreen, cGreen,
cBlack+Version,

View File

@ -2,7 +2,7 @@
// 📌 Don't use in production until version 1.0.0
// 🖥 https://github.com/fenny/fiber
// 🦸 Not all heroes wear capes, thank you +1000
// 🦸 Not all heroes wear capes, thank you to some amazing people
// 💖 @valyala, @dgrr, @erikdubbelboer, @savsgio, @julienschmidt
package fiber

View File

@ -2,7 +2,7 @@
// 📌 Don't use in production until version 1.0.0
// 🖥 https://github.com/fenny/fiber
// 🦸 Not all heroes wear capes, thank you +1000
// 🦸 Not all heroes wear capes, thank you to some amazing people
// 💖 @valyala, @dgrr, @erikdubbelboer, @savsgio, @julienschmidt
package fiber