internal/httpd/flash.go
62 lines · 1923 bytes
1package httpd
2
3import (
4 "net/http"
5 "net/url"
6)
7
8// A form action that fails redirects back to the page it came from with
9// the reason. The reason used to ride the URL as ?e=, so it survived a
10// reload and landed in history and bookmarks. It rides a one-shot cookie
11// now: set on the redirect, read and cleared by the page that renders it
12// (#119).
13const flashCookie = "gitbay_notice"
14
15// setFlash queues msg for the next page render. An empty msg sets
16// nothing.
17func (s *Server) setFlash(w http.ResponseWriter, msg string) {
18 if msg == "" {
19 return
20 }
21 if len(msg) > 300 {
22 msg = msg[:300]
23 }
24 http.SetCookie(w, &http.Cookie{
25 Name: flashCookie, Value: url.QueryEscape(msg), Path: "/",
26 HttpOnly: true, SameSite: http.SameSiteLaxMode,
27 Secure: s.cfg.HTTP.TLS != "off",
28 MaxAge: 60,
29 })
30}
31
32// takeFlash returns the queued message, if any, and clears it.
33func (s *Server) takeFlash(w http.ResponseWriter, r *http.Request) string {
34 c, err := r.Cookie(flashCookie)
35 if err != nil || c.Value == "" {
36 return ""
37 }
38 http.SetCookie(w, s.clearCookie(flashCookie, http.SameSiteLaxMode))
39 msg, err := url.QueryUnescape(c.Value)
40 if err != nil {
41 return ""
42 }
43 return msg
44}
45
46// clearCookie is the expiring twin of a Set-Cookie, carrying the same
47// attributes the setting call used.
48//
49// Deletion works without them — a cookie is identified by name, domain
50// and path, not by its flags — so this is consistency rather than a live
51// bug. It is worth having because a reviewer comparing the set and clear
52// paths should not have to work out whether the difference is deliberate,
53// and because a scanner will otherwise flag the bare form every time
54// (go:S2092, go:S3330, #153).
55func (s *Server) clearCookie(name string, sameSite http.SameSite) *http.Cookie {
56 return &http.Cookie{
57 Name: name, Value: "", Path: "/",
58 HttpOnly: true, SameSite: sameSite,
59 Secure: s.cfg.HTTP.TLS != "off",
60 MaxAge: -1,
61 }
62}