Skip to content

Commit a29d65e

Browse files
committed
fixes #3038
🐞 [Bug]: v3 Flash Message with redirect is not working #3038
1 parent c9b7b1a commit a29d65e

3 files changed

Lines changed: 93 additions & 46 deletions

File tree

redirect.go

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ func (r *Redirect) To(location string) error {
182182
r.c.setCanonical(HeaderLocation, location)
183183
r.c.Status(r.status)
184184

185+
r.processFlashMessages()
186+
185187
return nil
186188
}
187189

@@ -200,38 +202,6 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error {
200202
return err
201203
}
202204

203-
// Flash messages
204-
if len(r.messages) > 0 || len(r.oldInput) > 0 {
205-
messageText := bytebufferpool.Get()
206-
defer bytebufferpool.Put(messageText)
207-
208-
// flash messages
209-
for i, message := range r.messages {
210-
messageText.WriteString(message)
211-
// when there are more messages or oldInput -> add a comma
212-
if len(r.messages)-1 != i || (len(r.messages)-1 == i && len(r.oldInput) > 0) {
213-
messageText.WriteString(CookieDataSeparator)
214-
}
215-
}
216-
r.messages = r.messages[:0]
217-
218-
// old input data
219-
i := 1
220-
for k, v := range r.oldInput {
221-
messageText.WriteString(OldInputDataPrefix + k + CookieDataAssigner + v)
222-
if len(r.oldInput) != i {
223-
messageText.WriteString(CookieDataSeparator)
224-
}
225-
i++
226-
}
227-
228-
r.c.Cookie(&Cookie{
229-
Name: FlashCookieName,
230-
Value: r.c.app.getString(messageText.Bytes()),
231-
SessionOnly: true,
232-
})
233-
}
234-
235205
// Check queries
236206
if len(cfg.Queries) > 0 {
237207
queryText := bytebufferpool.Get()
@@ -270,8 +240,8 @@ func (r *Redirect) Back(fallback ...string) error {
270240
return r.To(location)
271241
}
272242

273-
// setFlash is a method to get flash messages before removing them
274-
func (r *Redirect) setFlash() {
243+
// parseAndClearFlashMessages is a method to get flash messages before removing them
244+
func (r *Redirect) parseAndClearFlashMessages() {
275245
// parse flash messages
276246
cookieValue := r.c.Cookies(FlashCookieName)
277247

@@ -289,6 +259,42 @@ func (r *Redirect) setFlash() {
289259
r.c.ClearCookie(FlashCookieName)
290260
}
291261

262+
// processFlashMessages is a helper function to process flash messages and old input data
263+
// and set them as cookies
264+
func (r *Redirect) processFlashMessages() {
265+
// Flash messages
266+
if len(r.messages) > 0 || len(r.oldInput) > 0 {
267+
messageText := bytebufferpool.Get()
268+
defer bytebufferpool.Put(messageText)
269+
270+
// flash messages
271+
for i, message := range r.messages {
272+
messageText.WriteString(message)
273+
// when there are more messages or oldInput -> add a comma
274+
if len(r.messages)-1 != i || (len(r.messages)-1 == i && len(r.oldInput) > 0) {
275+
messageText.WriteString(CookieDataSeparator)
276+
}
277+
}
278+
r.messages = r.messages[:0]
279+
280+
// old input data
281+
i := 1
282+
for k, v := range r.oldInput {
283+
messageText.WriteString(OldInputDataPrefix + k + CookieDataAssigner + v)
284+
if len(r.oldInput) != i {
285+
messageText.WriteString(CookieDataSeparator)
286+
}
287+
i++
288+
}
289+
290+
r.c.Cookie(&Cookie{
291+
Name: FlashCookieName,
292+
Value: r.c.app.getString(messageText.Bytes()),
293+
SessionOnly: true,
294+
})
295+
}
296+
}
297+
292298
// parseMessage is a helper function to parse flash messages and old input data
293299
func parseMessage(raw string) (string, string) { //nolint: revive // not necessary
294300
if i := findNextNonEscapedCharsetPosition(raw, []byte(CookieDataAssigner)); i != -1 {

redirect_test.go

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@ func Test_Redirect_To(t *testing.T) {
3434
require.Equal(t, "http://example.com", string(c.Response().Header.Peek(HeaderLocation)))
3535
}
3636

37+
// go test -run Test_Redirect_To_WithFlashMessages
38+
func Test_Redirect_To_WithFlashMessages(t *testing.T) {
39+
t.Parallel()
40+
app := New()
41+
c := app.AcquireCtx(&fasthttp.RequestCtx{})
42+
43+
err := c.Redirect().With("success", "1").With("message", "test").To("http://example.com")
44+
require.NoError(t, err)
45+
require.Equal(t, 302, c.Response().StatusCode())
46+
require.Equal(t, "http://example.com", string(c.Response().Header.Peek(HeaderLocation)))
47+
48+
equal := c.GetRespHeader(HeaderSetCookie) == "fiber_flash=success:1,message:test; path=/; SameSite=Lax" || c.GetRespHeader(HeaderSetCookie) == "fiber_flash=message:test,success:1; path=/; SameSite=Lax"
49+
require.True(t, equal)
50+
51+
c.Redirect().parseAndClearFlashMessages()
52+
require.Equal(t, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
53+
}
54+
3755
// go test -run Test_Redirect_Route_WithParams
3856
func Test_Redirect_Route_WithParams(t *testing.T) {
3957
t.Parallel()
@@ -149,6 +167,29 @@ func Test_Redirect_Back(t *testing.T) {
149167
require.ErrorAs(t, err, &ErrRedirectBackNoFallback)
150168
}
151169

170+
// go test -run Test_Redirect_Back_WithFlashMessages
171+
func Test_Redirect_Back_WithFlashMessages(t *testing.T) {
172+
t.Parallel()
173+
174+
app := New()
175+
app.Get("/user", func(c Ctx) error {
176+
return c.SendString("user")
177+
}).Name("user")
178+
179+
c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
180+
181+
err := c.Redirect().With("success", "1").With("message", "test").Back("/")
182+
require.NoError(t, err)
183+
require.Equal(t, 302, c.Response().StatusCode())
184+
require.Equal(t, "/", string(c.Response().Header.Peek(HeaderLocation)))
185+
186+
equal := c.GetRespHeader(HeaderSetCookie) == "fiber_flash=success:1,message:test; path=/; SameSite=Lax" || c.GetRespHeader(HeaderSetCookie) == "fiber_flash=message:test,success:1; path=/; SameSite=Lax"
187+
require.True(t, equal)
188+
189+
c.Redirect().parseAndClearFlashMessages()
190+
require.Equal(t, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
191+
}
192+
152193
// go test -run Test_Redirect_Back_WithReferer
153194
func Test_Redirect_Back_WithReferer(t *testing.T) {
154195
t.Parallel()
@@ -188,7 +229,7 @@ func Test_Redirect_Route_WithFlashMessages(t *testing.T) {
188229
equal := c.GetRespHeader(HeaderSetCookie) == "fiber_flash=success:1,message:test; path=/; SameSite=Lax" || c.GetRespHeader(HeaderSetCookie) == "fiber_flash=message:test,success:1; path=/; SameSite=Lax"
189230
require.True(t, equal)
190231

191-
c.Redirect().setFlash()
232+
c.Redirect().parseAndClearFlashMessages()
192233
require.Equal(t, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
193234
}
194235

@@ -216,12 +257,12 @@ func Test_Redirect_Route_WithOldInput(t *testing.T) {
216257
require.Contains(t, c.GetRespHeader(HeaderSetCookie), ",old_input_data_id:1")
217258
require.Contains(t, c.GetRespHeader(HeaderSetCookie), ",old_input_data_name:tom")
218259

219-
c.Redirect().setFlash()
260+
c.Redirect().parseAndClearFlashMessages()
220261
require.Equal(t, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
221262
}
222263

223-
// go test -run Test_Redirect_setFlash
224-
func Test_Redirect_setFlash(t *testing.T) {
264+
// go test -run Test_Redirect_parseAndClearFlashMessages
265+
func Test_Redirect_parseAndClearFlashMessages(t *testing.T) {
225266
t.Parallel()
226267

227268
app := New()
@@ -233,7 +274,7 @@ func Test_Redirect_setFlash(t *testing.T) {
233274

234275
c.Request().Header.Set(HeaderCookie, "fiber_flash=success:1,message:test,old_input_data_name:tom,old_input_data_id:1")
235276

236-
c.Redirect().setFlash()
277+
c.Redirect().parseAndClearFlashMessages()
237278

238279
require.Equal(t, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
239280

@@ -416,7 +457,7 @@ func Benchmark_Redirect_Route_WithFlashMessages(b *testing.B) {
416457
equal := c.GetRespHeader(HeaderSetCookie) == "fiber_flash=success:1,message:test; path=/; SameSite=Lax" || c.GetRespHeader(HeaderSetCookie) == "fiber_flash=message:test,success:1; path=/; SameSite=Lax"
417458
require.True(b, equal)
418459

419-
c.Redirect().setFlash()
460+
c.Redirect().parseAndClearFlashMessages()
420461
require.Equal(b, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
421462
}
422463

@@ -435,7 +476,7 @@ func Benchmark_Redirect_setFlash(b *testing.B) {
435476
b.ResetTimer()
436477

437478
for n := 0; n < b.N; n++ {
438-
c.Redirect().setFlash()
479+
c.Redirect().parseAndClearFlashMessages()
439480
}
440481

441482
require.Equal(b, "fiber_flash=; expires=Tue, 10 Nov 2009 23:00:00 GMT", c.GetRespHeader(HeaderSetCookie))
@@ -459,7 +500,7 @@ func Benchmark_Redirect_Messages(b *testing.B) {
459500
c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
460501

461502
c.Request().Header.Set(HeaderCookie, "fiber_flash=success:1,message:test,old_input_data_name:tom,old_input_data_id:1")
462-
c.Redirect().setFlash()
503+
c.Redirect().parseAndClearFlashMessages()
463504

464505
var msgs map[string]string
465506

@@ -484,7 +525,7 @@ func Benchmark_Redirect_OldInputs(b *testing.B) {
484525
c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
485526

486527
c.Request().Header.Set(HeaderCookie, "fiber_flash=success:1,message:test,old_input_data_name:tom,old_input_data_id:1")
487-
c.Redirect().setFlash()
528+
c.Redirect().parseAndClearFlashMessages()
488529

489530
var oldInputs map[string]string
490531

@@ -509,7 +550,7 @@ func Benchmark_Redirect_Message(b *testing.B) {
509550
c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
510551

511552
c.Request().Header.Set(HeaderCookie, "fiber_flash=success:1,message:test,old_input_data_name:tom,old_input_data_id:1")
512-
c.Redirect().setFlash()
553+
c.Redirect().parseAndClearFlashMessages()
513554

514555
var msg string
515556

@@ -534,7 +575,7 @@ func Benchmark_Redirect_OldInput(b *testing.B) {
534575
c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
535576

536577
c.Request().Header.Set(HeaderCookie, "fiber_flash=success:1,message:test,old_input_data_name:tom,old_input_data_id:1")
537-
c.Redirect().setFlash()
578+
c.Redirect().parseAndClearFlashMessages()
538579

539580
var input string
540581

router.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
225225

226226
// check flash messages
227227
if strings.Contains(utils.UnsafeString(c.Request().Header.RawHeaders()), FlashCookieName) {
228-
c.Redirect().setFlash()
228+
c.Redirect().parseAndClearFlashMessages()
229229
}
230230

231231
// Find match in stack

0 commit comments

Comments
 (0)