Skip to content

Commit

Permalink
withinput, parsing flash message
Browse files Browse the repository at this point in the history
  • Loading branch information
efectn committed Aug 17, 2022
1 parent 19df0cb commit 8dd2e6a
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 16 deletions.
34 changes: 28 additions & 6 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ type DefaultCtx struct {
viewBindMap *dictpool.Dict // Default view map to bind template engine
bind *Bind // Default bind reference
redirect *Redirect // Default redirect reference
flashMessages string // flash messages sent by redirection cookie
flashMessages map[string]string // flash messages sent by redirection cookie
oldInput map[string]string // old input data sent by redirection cookie
}

// Range data for c.Range
Expand Down Expand Up @@ -1296,12 +1297,33 @@ func (c *DefaultCtx) Bind() *Bind {
return c.bind
}

// setFlash is a method to get flash messages before removing them
func (c *DefaultCtx) setFlash() {
c.flashMessages = c.Cookies("fiber_flash")
// parse flash messages
if c.Cookies("fiber_flash") != "" {
messages := strings.Split(c.Cookies("fiber_flash"), ",k:")
c.flashMessages = make(map[string]string, len(messages))

c.ClearCookie("fiber_flash")
}
for _, msg := range messages {
msg = strings.Replace(msg, "k:", "", 1)
k, v := strings.Split(msg, ":")[0], strings.Split(msg, ":")[1]

c.flashMessages[k] = v
}
}

// parse old input data
if c.Cookies("fiber_flash_old_input") != "" {
messages := strings.Split(c.Cookies("fiber_flash_old_input"), ",k:")
c.oldInput = make(map[string]string, len(messages))

for _, msg := range messages {
msg = strings.Replace(msg, "k:", "", 1)
k, v := strings.Split(msg, ":")[0], strings.Split(msg, ":")[1]

c.oldInput[k] = v
}
}

func (c *DefaultCtx) GetFlash() error {
return c.SendString(c.flashMessages)
c.ClearCookie("fiber_flash", "fiber_flash_old_input")
}
6 changes: 3 additions & 3 deletions ctx_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,8 @@ type Ctx interface {
// Replacement of: BodyParser, ParamsParser, GetReqHeaders, GetRespHeaders, AllParams, QueryParser, ReqHeaderParser
Bind() *Bind

// setFlashes is a method to get flash messages before removing them
// setFlash is a method to get flash messages before removing them
setFlash()
GetFlash() error

// SetReq resets fields of context that is relating to request.
setReq(fctx *fasthttp.RequestCtx)
Expand Down Expand Up @@ -429,7 +428,8 @@ func (c *DefaultCtx) release() {
c.fasthttp = nil
c.bind = nil
c.redirect = nil
c.flashMessages = ""
c.flashMessages = nil
c.oldInput = nil
if c.viewBindMap != nil {
dictpool.ReleaseDict(c.viewBindMap)
}
Expand Down
81 changes: 77 additions & 4 deletions redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ package fiber
import (
"fmt"

"github.com/gofiber/fiber/v3/binder"
"github.com/gofiber/fiber/v3/utils"
"github.com/valyala/bytebufferpool"
)

// Redirect is a struct to use it with Ctx.
type Redirect struct {
c *DefaultCtx // Embed ctx
status int // Status code of redirection. Default: StatusFound
messages Map // Flash messages
c *DefaultCtx // Embed ctx
status int // Status code of redirection. Default: StatusFound
messages Map // Flash messages
oldInput map[string]string // Old input data
}

// A config to use with Redirect().Route()
Expand All @@ -31,6 +34,7 @@ func newRedirect(c *DefaultCtx) *Redirect {
c: c,
status: StatusFound,
messages: make(Map, 0),
oldInput: make(map[string]string, 0),
}
}

Expand All @@ -44,12 +48,55 @@ func (r *Redirect) Status(code int) *Redirect {

// You can send flash messages by using With().
// They will be sent as a cookie.
// You can get them by using: Redirect().Messages(), Redirect().Message()
func (r *Redirect) With(key string, value any) *Redirect {
r.messages[key] = value

return r
}

// You can send input data by using WithInput().
// They will be sent as a cookie.
// This method can send form, multipart form, query data to redirected route.
// You can get them by using: Redirect().Olds(), Redirect().Old()
func (r *Redirect) WithInput() *Redirect {
// Get content-type
ctype := utils.ToLower(utils.UnsafeString(r.c.Context().Request.Header.ContentType()))
ctype = binder.FilterFlags(utils.ParseVendorSpecificContentType(ctype))

// TODO: Maybe better implementation.
switch ctype {
case MIMEApplicationForm:
r.c.Bind().Form(r.oldInput)
case MIMEMultipartForm:
r.c.Bind().MultipartForm(r.oldInput)
default:
r.c.Bind().Query(r.oldInput)
}

return r
}

// Get flash messages.
func (r *Redirect) Messages() map[string]string {
return r.c.flashMessages
}

// Get flash message by key.
func (r *Redirect) Message(key string) string {
return r.c.flashMessages[key]
}

// Get old input data.
func (r *Redirect) Olds() map[string]string {
return r.c.oldInput
}

// Get old input data by key.
func (r *Redirect) Old(key string) string {
return r.c.oldInput[key]
}

// Redirect to the URL derived from the specified path, with specified status.
func (r *Redirect) To(location string) error {
r.c.setCanonical(HeaderLocation, location)
Expand Down Expand Up @@ -78,8 +125,13 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error {
messageText := bytebufferpool.Get()
defer bytebufferpool.Put(messageText)

i := 1
for k, v := range r.messages {
messageText.WriteString("k:" + k + ":" + fmt.Sprint(v) + ",")
messageText.WriteString("k:" + k + ":" + fmt.Sprint(v))
if len(r.messages) != i {
messageText.WriteString(",")
}
i++
}

r.c.Cookie(&Cookie{
Expand All @@ -89,6 +141,27 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error {
})
}

// Old input data
if len(r.oldInput) > 0 {
inputText := bytebufferpool.Get()
defer bytebufferpool.Put(inputText)

i := 1
for k, v := range r.oldInput {
inputText.WriteString("k:" + k + ":" + v)
if len(r.oldInput) != i {
inputText.WriteString(",")
}
i++
}

r.c.Cookie(&Cookie{
Name: "fiber_flash_old_input",
Value: inputText.String(),
SessionOnly: true,
})
}

// Check queries
if len(cfg.Queries) > 0 {
queryText := bytebufferpool.Get()
Expand Down
4 changes: 1 addition & 3 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,7 @@ func (app *App) handler(rctx *fasthttp.RequestCtx) {
c.Reset(rctx)

// check flash messages
if c.Cookies("fiber_flash") != "" {
c.setFlash()
}
c.setFlash()

// handle invalid http method directly
if methodInt(c.Method()) == -1 {
Expand Down

1 comment on commit 8dd2e6a

@ReneWerner87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 8dd2e6a Previous: 19df0cb Ratio
Benchmark_Ctx_MultipartForm 1634 ns/op 40 B/op 3 allocs/op 557.7 ns/op 40 B/op 3 allocs/op 2.93
Benchmark_App_MethodNotAllowed 1918 ns/op 72 B/op 2 allocs/op 839.8 ns/op 72 B/op 2 allocs/op 2.28
Benchmark_Router_NotFound 1917 ns/op 72 B/op 2 allocs/op 807.5 ns/op 72 B/op 2 allocs/op 2.37
Benchmark_Router_Handler 1123 ns/op 0 B/op 0 allocs/op 259.4 ns/op 0 B/op 0 allocs/op 4.33
Benchmark_Router_Handler_Strict_Case 1105 ns/op 0 B/op 0 allocs/op 248.2 ns/op 0 B/op 0 allocs/op 4.45
Benchmark_Router_Chain 1810 ns/op 40 B/op 2 allocs/op 707.4 ns/op 40 B/op 2 allocs/op 2.56
Benchmark_Router_WithCompression 1786 ns/op 40 B/op 2 allocs/op 701.8 ns/op 40 B/op 2 allocs/op 2.54
Benchmark_Router_Handler_CaseSensitive 1116 ns/op 0 B/op 0 allocs/op 248 ns/op 0 B/op 0 allocs/op 4.50
Benchmark_Router_Handler_Unescape 1204 ns/op 0 B/op 0 allocs/op 274.1 ns/op 0 B/op 0 allocs/op 4.39
Benchmark_Router_Handler_StrictRouting 1102 ns/op 0 B/op 0 allocs/op 246.4 ns/op 0 B/op 0 allocs/op 4.47
Benchmark_Middleware_BasicAuth 1468 ns/op 80 B/op 5 allocs/op 536.4 ns/op 80 B/op 5 allocs/op 2.74
Benchmark_Cache_AdditionalHeaders 2458 ns/op 672 B/op 11 allocs/op 1217 ns/op 592 B/op 9 allocs/op 2.02
Benchmark_Etag 1031 ns/op 0 B/op 0 allocs/op 230.2 ns/op 0 B/op 0 allocs/op 4.48
Benchmark_Middleware_Favicon 1009 ns/op 3 B/op 1 allocs/op 180.3 ns/op 3 B/op 1 allocs/op 5.60
Benchmark_Limiter_Custom_Store 1565 ns/op 72 B/op 2 allocs/op 674 ns/op 72 B/op 2 allocs/op 2.32
Benchmark_Limiter 1576 ns/op 72 B/op 2 allocs/op 680.2 ns/op 72 B/op 2 allocs/op 2.32
Benchmark_Logger 1203 ns/op 0 B/op 0 allocs/op 336.6 ns/op 0 B/op 0 allocs/op 3.57

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.