Added 7 new functions, see doc

pull/6/head
Fenny 2020-01-10 03:09:43 +01:00
parent d38cea2f89
commit a4f86dbd1e
3 changed files with 200 additions and 47 deletions

View File

@ -130,32 +130,31 @@ func (ctx *Ctx) Body(args ...interface{}) string {
return ""
}
// Cookie :
func (ctx *Ctx) Cookie(name, value string, options ...interface{}) {
cook := &fasthttp.Cookie{}
if len(options) > 0 {
// options
}
cook.SetKey(name)
cook.SetValue(value)
ctx.Fasthttp.Response.Header.SetCookie(cook)
}
// Cookies :
func (ctx *Ctx) Cookies(args ...interface{}) string {
if len(args) == 0 {
return ctx.Get("Cookie")
}
if len(args) == 1 {
switch arg := args[0].(type) {
case string:
return ctx.Get(arg)
case func(string, string):
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
arg(b2s(k), b2s(v))
})
default:
panic("Argument must be a string or func(string, string)")
}
}
if len(args) > 1 {
cook := &fasthttp.Cookie{}
cook.SetKey(args[0].(string))
cook.SetValue(args[1].(string))
if len(args) > 2 {
// Do something with cookie options (args[2])
// Dont forget to finish this
}
ctx.Fasthttp.Response.Header.SetCookie(cook)
switch arg := args[0].(type) {
case string:
return b2s(ctx.Fasthttp.Request.Header.Cookie(arg))
case func(string, string):
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
arg(b2s(k), b2s(v))
})
default:
panic("Argument must be a string or func(string, string)")
}
return ""
}
@ -174,6 +173,7 @@ func (ctx *Ctx) ClearCookies(args ...string) {
// Send :
func (ctx *Ctx) Send(args ...interface{}) {
// https://github.com/valyala/fasthttp/blob/master/http.go#L490
if len(args) != 1 {
panic("To many arguments!")
@ -190,6 +190,16 @@ func (ctx *Ctx) Send(args ...interface{}) {
}
}
// SendString internal use
func (ctx *Ctx) SendString(body string) {
ctx.Fasthttp.Response.SetBodyString(body)
}
// SendByte internal use
func (ctx *Ctx) SendByte(body []byte) {
ctx.Fasthttp.Response.SetBodyString(b2s(body))
}
// Write :
func (ctx *Ctx) Write(args ...interface{}) {
if len(args) != 1 {
@ -226,8 +236,8 @@ func (ctx *Ctx) Json(v interface{}) error {
return err
}
ctx.Set("Content-Type", "application/json")
ctx.Send(b2s(raw))
return err
ctx.SendByte(raw)
return nil
}
// Redirect :
@ -263,8 +273,8 @@ func (ctx *Ctx) Hostname() string {
return b2s(ctx.Fasthttp.URI().Host())
}
// OriginalURL :
func (ctx *Ctx) OriginalURL() string {
// OriginalUrl :
func (ctx *Ctx) OriginalUrl() string {
return b2s(ctx.Fasthttp.Request.Header.RequestURI())
}
@ -281,8 +291,8 @@ func (ctx *Ctx) Secure() bool {
return ctx.Fasthttp.IsTLS()
}
// IP :
func (ctx *Ctx) IP() string {
// Ip :
func (ctx *Ctx) Ip() string {
return ctx.Fasthttp.RemoteIP().String()
}
@ -344,3 +354,81 @@ func (ctx *Ctx) SendFile(file string) {
func (ctx *Ctx) Location(path string) {
ctx.Set("Location", path)
}
// Subdomains :
func (ctx *Ctx) Subdomains() (subs []string) {
subs = strings.Split(ctx.Hostname(), ".")
subs = subs[:len(subs)-2]
return subs
}
// Ips https://expressjs.com/en/4x/api.html#req.ips
func (ctx *Ctx) Ips() []string {
ips := strings.Split(ctx.Get("X-Forwarded-For"), " ")
return ips
}
// Jsonp TODO https://expressjs.com/en/4x/api.html#res.jsonp
func (ctx *Ctx) Jsonp(args ...interface{}) error {
jsonp := "callback("
if len(args) == 1 {
raw, err := json.Marshal(&args[0])
if err != nil {
return err
}
jsonp += b2s(raw) + ");"
} else if len(args) == 2 {
jsonp = args[0].(string) + "("
raw, err := json.Marshal(&args[0])
if err != nil {
return err
}
jsonp += b2s(raw) + ");"
} else {
panic("Missing interface{}")
}
ctx.Set("X-Content-Type-Options", "nosniff")
ctx.Set("Content-Type", "text/javascript")
ctx.SendString(jsonp)
return nil
}
// Vary TODO https://expressjs.com/en/4x/api.html#res.vary
func (ctx *Ctx) Vary() {
}
// Links TODO https://expressjs.com/en/4x/api.html#res.links
func (ctx *Ctx) Links() {
}
// Append TODO https://expressjs.com/en/4x/api.html#res.append
func (ctx *Ctx) Append(field, val string) {
prev := ctx.Get(field)
value := val
if prev != "" {
value = prev + "; " + val
}
ctx.Set(field, value)
}
// Accepts TODO https://expressjs.com/en/4x/api.html#req.accepts
func (ctx *Ctx) Accepts() bool {
return true
}
// Range TODO https://expressjs.com/en/4x/api.html#req.range
func (ctx *Ctx) Range() bool {
return true
}
// Fresh TODO https://expressjs.com/en/4x/api.html#req.fresh
func (ctx *Ctx) Fresh() bool {
return true
}
// Stale TODO https://expressjs.com/en/4x/api.html#req.fresh
func (ctx *Ctx) Stale() bool {
return true
}

View File

@ -4,6 +4,28 @@ The ctx object represents the HTTP request and response and has methods for the
## Accepts
!> Planned for V2
## Append
Appends the specified value to the HTTP response header field. If the header is not already set, it creates the header with the specified value. The value parameter must be a string.
```go
// Function signature
c.Append(field, value string)
// Example
app.Get("/", func(c *fiber.Ctx) {
// Let's see if the Link header exist
c.Get("Link")
// => ""
// Lets append some values to the link header
c.Append("Link", "http://localhost")
// => Link: http://localhost
c.Append("Link", "http://google.com")
// => Link: http://localhost; http://google.com
})
```
## Attachment
Sets the HTTP response [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header field to “attachment”. If a filename is given, then it sets the Content-Type based on the extension name via (Type)[#type], and sets the Content-Disposition “filename=” parameter.
```go
@ -53,7 +75,7 @@ The following example shows how to use the body function.
// Function signature
c.Body() string
c.Body(key string) string
c.Body(func(key string, value string)) func(string, string)
c.Body(func(key value string)) func(string, string)
// Example
// curl -X POST http://localhost:8080 -d user=john
@ -91,31 +113,41 @@ app.Get("/", func(c *fiber.Ctx) {
})
```
## Cookie
Sets cookie name to value, the third options parameter is not implemented yet.
```go
c.Cookie(name, value string)
//c.Cookie(name, value string, options...)
// Example
app.Get("/", func(c *fiber.Ctx) {
// Set cookie
c.Cookie("name", "john")
// => Cookie: name=john;
})
```
## Cookies
Get and set cookies
```go
// Function signature
c.Cookies() string
c.Cookies(key string) string
c.Cookies(key string, value string) string
c.Cookies(func(key string, value string))
c.Cookies(func(key, value string)) string
// Example
app.Get("/", func(c *fiber.Ctx) {
// Create cookie with key, value
c.Cookies("name", "john")
// => Cookie: name=john
// Get raw cookie header
c.Cookies()
// => name=john;
// Get cookie by key
c.Cookies("name")
// => "john"
// Get raw cookie header
c.Cookies()
// => name=john;
// Show all cookies
c.Cookies(func(key string, val string) {
c.Cookies(func(key, val string) {
fmt.Println(key, val)
// => "name", "john"
})
@ -127,7 +159,7 @@ Transfers the file at path as an “attachment”. Typically, browsers will prom
```go
// Function signature
c.Download(path string)
c.Download(path string, filename string)
c.Download(path, filename string)
// Example
app.Get("/", func(c *fiber.Ctx) {
@ -223,15 +255,15 @@ app.Get("/", func(c *fiber.Ctx) {
})
```
## IP
## Ip
Contains the remote IP address of the request.
```go
// Function signature
c.IP() string
c.Ip() string
// Example
app.Get("/", func(c *fiber.Ctx) {
c.IP()
c.Ip()
// => "127.0.0.1"
})
```
@ -288,7 +320,33 @@ app.Listen(8080)
```
## Jsonp
!> Planned for V2
Sends a JSON response with JSONP support. This method is identical to [Json()](#json), except that it opts-in to JSONP callback support.
By default, the JSONP callback name is simply callback. Override this by passing a named string in the function.
```go
// Function signature
c.Jsonp(json interface{}) error
c.Jsonp(callback string, v interface{}) error
// Example
type JsonStruct struct {
name string
age uint8
}
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
data := JsonStruct{
name: "Grame",
age: 20,
}
c.Jsonp(data)
// => callback({"name": "Grame", "age": 20})
c.Jsonp("customFunc", data)
// => customFunc({"name": "Grame", "age": 20})
})
app.Listen(8080)
```
## Method
Contains a string corresponding to the HTTP method of the request: GET, POST, PUT, and so on.
@ -359,16 +417,16 @@ app.Get("/", func(c *fiber.Ctx) {
})
```
## OriginalURL
## OriginalUrl
Contains the original request URL.
```go
// Function signature
c.OriginalURL() string
c.OriginalUrl() string
// Example
app.Get("/", func(c *fiber.Ctx) {
// GET /search?q=something
c.OriginalURL()
c.OriginalUrl()
// => '/search?q=something'
})
```
@ -488,7 +546,7 @@ app.Get("/not-found", func(c *fiber.Ctx) {
Sets the responses HTTP header field to value. To set multiple fields at once, pass an object as the parameter.
```go
// Function signature
c.Set(key string, value string)
c.Set(key, value string)
// Example
app.Get("/", func(c *fiber.Ctx) {

View File

@ -245,6 +245,7 @@ func (r *Fiber) registerHandler(method, path string, handler func(*Ctx)) {
// handler :
func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
found := false
// get custom context from sync pool
ctx := acquireCtx(fctx)
// get path and method from main context
@ -263,6 +264,7 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
ctx.params = &[]string{"*"}
ctx.values = []string{path}
}
found = true
// Execute handler with context
route.handler(ctx)
// if next is not set, leave loop and release ctx
@ -287,6 +289,7 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
ctx.values = matches[0][1:len(matches[0])]
}
}
found = true
// Execute handler with context
route.handler(ctx)
// if next is not set, leave loop and release ctx
@ -296,6 +299,10 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
// set next to false for next iteration
ctx.next = false
}
if !found {
// No routes found
ctx.Status(404).Send("Not Found")
}
// release context back into sync pool
releaseCtx(ctx)
}