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

+ + + + + + + + + + + + <%= for (r) in routes { %> + + + + + + + <% } %> + + +
METHODPATHNAMEHANDLER
+ <%= r.Method %> + + <%= if (r.Method !="GET" || r.Path ~="{" ) { %> + <%= r.Path %> + <% } else { %> + + <%= r.Path %> + + <% } %> + + <%= r.PathName %> + <%= r.HandlerName %>
+
+
+
Powered by gobuffalo.io
+
+ + + \ 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

- - - - - - - - - - - - <%= for (r) in routes { %> - - - - - - - <% } %> - - -
METHODPATHNAMEHANDLER
- <%= r.Method %> - - <%= if (r.Method != "GET" || r.Path ~= "{") { %> - <%= r.Path %> - <% } else { %> - <%= r.Path %> - <% } %> - - <%= r.PathName %> - <%= r.HandlerName %>
-
-
-
Powered by gobuffalo.io
-
- - -` -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") +}