diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index aad738c7e..3cb687a35 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,8 +4,14 @@ updates:
directory: "/"
schedule:
interval: "daily"
+ target-branch: "development"
+ labels:
+ - "gomod"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+ target-branch: "development"
+ labels:
+ - "github-actions"
diff --git a/app.go b/app.go
index aec94b3a6..804061e43 100644
--- a/app.go
+++ b/app.go
@@ -75,7 +75,6 @@ func New(opts Options) *App {
}
a.Use(a.PanicHandler)
a.Use(RequestLogger)
- a.Use(sessionSaver)
return a
}
diff --git a/default_context.go b/default_context.go
index e648948a0..0aad92404 100644
--- a/default_context.go
+++ b/default_context.go
@@ -139,6 +139,9 @@ func (d *DefaultContext) Render(status int, rr render.Renderer) error {
if d.Session() != nil {
d.Flash().Clear()
d.Flash().persist(d.Session())
+ if err := d.Session().Save(); err != nil {
+ return HTTPError{Status: http.StatusInternalServerError, Cause: err}
+ }
}
d.Response().Header().Set("Content-Type", rr.ContentType())
@@ -191,7 +194,13 @@ var mapType = reflect.ValueOf(map[string]interface{}{}).Type()
// Redirect a request with the given status to the given URL.
func (d *DefaultContext) Redirect(status int, url string, args ...interface{}) error {
- d.Flash().persist(d.Session())
+ if d.Session() != nil {
+ d.Flash().Clear()
+ d.Flash().persist(d.Session())
+ if err := d.Session().Save(); err != nil {
+ return HTTPError{Status: http.StatusInternalServerError, Cause: err}
+ }
+ }
if strings.HasSuffix(url, "Path()") {
if len(args) > 1 {
diff --git a/error.dev.html b/error.dev.html
new file mode 100644
index 000000000..8629916e7
--- /dev/null
+++ b/error.dev.html
@@ -0,0 +1,647 @@
+
+
+
+
+
+
+
+
+ <%= status %> - ERROR!
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= status %> - ERROR!
+
+
+
+
+
+
+
+
+
+
Error Trace
+
<%= error %>
+
+
Context
+
<%= inspect(context) %>
+
+
Parameters
+
<%= inspect(params) %>
+
+
Headers
+
<%= inspect(headers) %>
+
+
Form
+
<%= inspect(posted_form) %>
+
+
Routes
+
+
+
+ METHOD |
+ PATH |
+ NAME |
+ HANDLER |
+
+
+
+
+ <%= for (r) in routes { %>
+
+
+ <%= r.Method %>
+ |
+
+ <%= if (r.Method !="GET" || r.Path ~="{" ) { %>
+ <%= r.Path %>
+ <% } else { %>
+
+ <%= r.Path %>
+
+ <% } %>
+ |
+
+ <%= r.PathName %>
+ |
+ <%= r.HandlerName %> |
+
+ <% } %>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/error.prod.html b/error.prod.html
new file mode 100644
index 000000000..091a176ee
--- /dev/null
+++ b/error.prod.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
We're Sorry!
+
+
It looks like something went wrong! Don't worry, we are aware of the problem and are looking into it.
+
Sorry if this has caused you any problems. Please check back again later.
+
+
+
powered by gobuffalo.io
+
+
+
+
\ No newline at end of file
diff --git a/error_templates.go b/error_templates.go
index 63f82b878..2fb4d13d9 100644
--- a/error_templates.go
+++ b/error_templates.go
@@ -1,125 +1,16 @@
package buffalo
-var devErrorTmpl = `
-
-
- <%= status %> - ERROR!
-
-
+import (
+ _ "embed"
+)
-
-
-
-
-
-
-
-
-
- <%= status %> - ERROR!
-
-
-
-
-
+var (
+ //go:embed error.dev.html
+ devErrorTmpl string
-
-
-
-
Error Trace
-
<%= error %>
+ //go:embed error.prod.html
+ prodErrorTmpl string
-
Context
-
<%= inspect(context) %>
-
-
Parameters
-
<%= inspect(params) %>
-
-
Headers
-
<%= inspect(headers) %>
-
-
Form
-
<%= inspect(posted_form) %>
-
-
Routes
-
-
-
- METHOD |
- PATH |
- NAME |
- HANDLER |
-
-
-
-
- <%= for (r) in routes { %>
-
-
- <%= r.Method %>
- |
-
- <%= if (r.Method != "GET" || r.Path ~= "{") { %>
- <%= r.Path %>
- <% } else { %>
- <%= r.Path %>
- <% } %>
- |
-
- <%= r.PathName %>
- |
- <%= r.HandlerName %> |
-
- <% } %>
-
-
-
-
-
-
-
-
-
-`
-var prodErrorTmpl = `
-
-
-
-
-
-
-
-
-
We're Sorry!
-
-
It looks like something went wrong! Don't worry, we are aware of the problem and are looking into it.
-
Sorry if this has caused you any problems. Please check back again later.
-
-
-
powered by gobuffalo.io
-
-
-
-`
-
-var prodNotFoundTmpl = `
-
-
-
-
-
-
-
-
-
Not Found
-
-
The page you're looking for does not exist, you may have mistyped the address or the page may have been moved.
-
-
-
powered by gobuffalo.io
-
-
-
-`
+ //go:embed notfound.prod.html
+ prodNotFoundTmpl string
+)
diff --git a/flash.go b/flash.go
index 7e5a773c9..ecf08d176 100644
--- a/flash.go
+++ b/flash.go
@@ -39,7 +39,6 @@ func (f Flash) Add(key, value string) {
func (f Flash) persist(session *Session) {
b, _ := json.Marshal(f.data)
session.Set(flashKey, b)
- session.Save()
}
//newFlash creates a new Flash and loads the session data inside its data.
diff --git a/notfound.prod.html b/notfound.prod.html
new file mode 100644
index 000000000..3c1ab654c
--- /dev/null
+++ b/notfound.prod.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
Not Found
+
+
The page you're looking for does not exist, you may have mistyped the address or the page may have been
+ moved.
+
+
+
powered by gobuffalo.io
+
+
+
+
\ No newline at end of file
diff --git a/options.go b/options.go
index 3b180bdc4..ebaa963c6 100644
--- a/options.go
+++ b/options.go
@@ -57,7 +57,7 @@ type Options struct {
// PreHandlers are http.Handlers that are called between the http.Server
// and the buffalo Application.
PreHandlers []http.Handler `json:"-"`
- // PreWare takes an http.Handler and returns and http.Handler
+ // PreWare takes an http.Handler and returns an http.Handler
// and acts as a pseudo-middleware between the http.Server and
// a Buffalo application.
PreWares []PreWare `json:"-"`
@@ -73,7 +73,7 @@ type Options struct {
cancel context.CancelFunc
}
-// PreWare takes an http.Handler and returns and http.Handler
+// PreWare takes an http.Handler and returns an http.Handler
// and acts as a pseudo-middleware between the http.Server and
// a Buffalo application.
type PreWare func(http.Handler) http.Handler
diff --git a/request_logger.go b/request_logger.go
index 0ceaf786e..17f2be188 100644
--- a/request_logger.go
+++ b/request_logger.go
@@ -42,7 +42,6 @@ func RequestLoggerFunc(h Handler) Handler {
}
irid = rs
c.Session().Set("requestor_id", irid)
- c.Session().Save()
}
rid := irid.(string) + "-" + rs
diff --git a/route_info.go b/route_info.go
index 8bb849ce0..b5e20d512 100644
--- a/route_info.go
+++ b/route_info.go
@@ -103,7 +103,6 @@ func (ri RouteInfo) ServeHTTP(res http.ResponseWriter, req *http.Request) {
events.EmitPayload(EvtRouteStarted, payload)
err := a.Middleware.handler(ri)(c)
- c.Flash().persist(c.Session())
if err != nil {
status := http.StatusInternalServerError
diff --git a/router_test.go b/router_test.go
index 1e3fa5254..ff3584fa5 100644
--- a/router_test.go
+++ b/router_test.go
@@ -311,15 +311,15 @@ func Test_Router_Group_Middleware(t *testing.T) {
a := testApp()
a.Use(func(h Handler) Handler { return h })
- r.Len(a.Middleware.stack, 5)
+ r.Len(a.Middleware.stack, 4)
g := a.Group("/api/v1")
- r.Len(a.Middleware.stack, 5)
- r.Len(g.Middleware.stack, 5)
+ r.Len(a.Middleware.stack, 4)
+ r.Len(g.Middleware.stack, 4)
g.Use(func(h Handler) Handler { return h })
- r.Len(a.Middleware.stack, 5)
- r.Len(g.Middleware.stack, 6)
+ r.Len(a.Middleware.stack, 4)
+ r.Len(g.Middleware.stack, 5)
}
func Test_Router_Redirect(t *testing.T) {
diff --git a/runtime/version.go b/runtime/version.go
index c6eafa101..4bf2cc5c1 100644
--- a/runtime/version.go
+++ b/runtime/version.go
@@ -1,4 +1,4 @@
package runtime
// Version is the current version of the buffalo binary
-var Version = "v0.18.2"
+var Version = "v0.18.3"
diff --git a/session.go b/session.go
index 9bfec880a..f49ea60bf 100644
--- a/session.go
+++ b/session.go
@@ -63,13 +63,3 @@ func (a *App) getSession(r *http.Request, w http.ResponseWriter) *Session {
res: w,
}
}
-
-func sessionSaver(next Handler) Handler {
- return func(c Context) error {
- err := next(c)
- if err != nil {
- return err
- }
- return c.Session().Save()
- }
-}
diff --git a/session_test.go b/session_test.go
new file mode 100644
index 000000000..b69d241a4
--- /dev/null
+++ b/session_test.go
@@ -0,0 +1,64 @@
+package buffalo
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+ "testing"
+
+ "github.com/gobuffalo/buffalo/render"
+ "github.com/gobuffalo/httptest"
+
+ "github.com/stretchr/testify/require"
+)
+
+func Test_Session_SingleCookie(t *testing.T) {
+ r := require.New(t)
+
+ sessionName := "_test_session"
+ a := New(Options{SessionName: sessionName})
+ rr := render.New(render.Options{})
+
+ a.GET("/", func(c Context) error {
+ return c.Render(http.StatusCreated, rr.String(""))
+ })
+
+ w := httptest.New(a)
+ res := w.HTML("/").Get()
+
+ var sessionCookies []string
+ for _, c := range res.Header().Values("Set-Cookie") {
+ if strings.HasPrefix(c, sessionName) {
+ sessionCookies = append(sessionCookies, c)
+ }
+ }
+
+ r.Equal(1, len(sessionCookies))
+}
+
+func Test_Session_CustomValue(t *testing.T) {
+ r := require.New(t)
+
+ a := New(Options{})
+ rr := render.New(render.Options{})
+
+ // Root path sets a custom session value
+ a.GET("/", func(c Context) error {
+ c.Session().Set("example", "test")
+ return c.Render(http.StatusCreated, rr.String(""))
+ })
+ // /session path prints custom session value as response
+ a.GET("/session", func(c Context) error {
+ sessionValue := c.Session().Get("example")
+ return c.Render(http.StatusCreated, rr.String(fmt.Sprintf("%s", sessionValue)))
+ })
+
+ w := httptest.New(a)
+ _ = w.HTML("/").Get()
+
+ // Create second request that should contain the cookie from the first response
+ reqGetSession := w.HTML("/session")
+ resGetSession := reqGetSession.Get()
+
+ r.Equal(resGetSession.Body.String(), "test")
+}