aboutsummaryrefslogtreecommitdiff
path: root/cmd/monfront/server.go
diff options
context:
space:
mode:
authorGibheer <gibheer+git@zero-knowledge.org>2023-08-17 22:02:52 +0200
committerGibheer <gibheer+git@zero-knowledge.org>2023-08-17 22:02:52 +0200
commit10f7eb53f4370cab6c1ff390773772389d500e59 (patch)
tree8c7d81f6428f182bec3162274d88fe4e486be9e1 /cmd/monfront/server.go
parenta4a8c642296560ddb88ee43199d43520250b9828 (diff)
prepare switch to log/slog
This commit prepares the switch from log to log/slog, which was introduced in Go 1.21. slog provides some useful facilities to add metadata to log entries, which should be helpful for debugging problems. This commit also adds a small transaction ID generator. It provides a common identifier between log messages, so that multiple errors can be viewed together in their order.
Diffstat (limited to 'cmd/monfront/server.go')
-rw-r--r--cmd/monfront/server.go45
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
+}