diff options
Diffstat (limited to 'cmd/monfront/server.go')
-rw-r--r-- | cmd/monfront/server.go | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/cmd/monfront/server.go b/cmd/monfront/server.go index 8e53c64..06afe11 100644 --- a/cmd/monfront/server.go +++ b/cmd/monfront/server.go @@ -2,12 +2,15 @@ package main import ( "compress/gzip" + "crypto/rand" "database/sql" "encoding/json" "fmt" "html/template" "io" "log" + "log/slog" + "math/big" "net" "net/http" "strings" @@ -19,6 +22,7 @@ type ( listen net.Listener db *sql.DB h *http.ServeMux + log *slog.Logger tmpl *template.Template auth func(c *Context) error // authentication autho func(c *Context) error // authorization @@ -32,6 +36,7 @@ type ( r *http.Request tmpl *template.Template db *sql.DB + log *slog.Logger User string `json:"-"` Filter *filter `json:"-"` @@ -51,7 +56,7 @@ type ( } ) -func newServer(l net.Listener, db *sql.DB, tmpl *template.Template, auth func(c *Context) error, autho func(c *Context) error) *server { +func newServer(l net.Listener, db *sql.DB, log *slog.Logger, tmpl *template.Template, auth func(c *Context) error, autho func(c *Context) error) *server { s := &server{ listen: l, db: db, @@ -59,6 +64,7 @@ func newServer(l net.Listener, db *sql.DB, tmpl *template.Template, auth func(c h: http.NewServeMux(), auth: auth, autho: autho, + log: log, } return s } @@ -70,11 +76,19 @@ func (s *server) ListenAndServe() error { func (s *server) Handle(path string, fun handleFunc) { s.h.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + txid, err := newTxId() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(`internal error occured`)) + s.log.Error("could not create txid", "error", err) + return + } c := &Context{ w: w, r: r, tmpl: s.tmpl, db: s.db, + log: s.log.With("path", path, "txid", txid), } if err := s.auth(c); err != nil { return @@ -153,3 +167,32 @@ func (c *Context) SetCookie(name, val string, expire time.Time) { http.SetCookie(c.w, &cook) return } + +// Alphabet are the available characters used to generate the txids. The more +// characters available the more bits can be represented with shorter IDs. +const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_" + +// alphalen is the number of available characters in the alphabet. +var alphalen = big.NewInt(int64(len(alphabet))) + +// txlen is the length of the generated transaction IDs +const txlen = 15 + +// generate a new transaction ID +// +// This function generates a unique ID using the above parameters. If the IDs +// generated are not unique enough to track a transaction, the txlen should +// be raised. +func newTxId() (string, error) { + s := make([]byte, txlen) + var err error + var num *big.Int + for i := 0; i < txlen; i++ { + num, err = rand.Int(rand.Reader, alphalen) + if err != nil { + return "", err + } + s[i] = alphabet[num.Int64()] + } + return string(s), nil +} |