Finished changing structure to modules:

- ntfy
- keyserver
- webhook
- webserver
functional modules.
This commit is contained in:
Fabian Gasper
2026-07-21 09:45:56 +02:00
parent 641df9eaab
commit 9b0b6b1ecf
10 changed files with 383 additions and 199 deletions
+52
View File
@@ -0,0 +1,52 @@
package middleware
import (
"log"
"net/http"
"strings"
"golang.org/x/time/rate"
)
func SecurityHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
next.ServeHTTP(w, req)
})
}
func NoListing(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if strings.HasSuffix(req.URL.Path, "/") {
http.NotFound(w, req)
return
}
next.ServeHTTP(w, req)
})
}
func WKDHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Access-Control-Allow-Origin", "*")
next.ServeHTTP(w, req)
})
}
// RateLimit is parameterized by the limiter instance, so each module
// that needs rate limiting owns its own limiter rather than sharing
// a package-level global.
func RateLimit(limiter *rate.Limiter) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if !limiter.Allow() {
log.Println("rate limit exceeded")
w.WriteHeader(http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, req)
})
}
}
+45
View File
@@ -0,0 +1,45 @@
package ntfy
import (
"bytes"
"fmt"
"log"
"net/http"
"time"
)
type Config struct {
URL string
Topic string
}
// Notify sends a failure notification. Silently does nothing if
// URL or Topic are unset, so callers don't need to check first.
func Notify(cfg Config, context string, err error) {
if cfg.URL == "" || cfg.Topic == "" {
return
}
msg := fmt.Sprintf("%s: %v", context, err)
url := fmt.Sprintf("%s/%s", cfg.URL, cfg.Topic)
req, reqErr := http.NewRequest("POST", url, bytes.NewBufferString(msg))
if reqErr != nil {
log.Printf("ntfy request build failed: %v", reqErr)
return
}
req.Header.Set("Title", "Varde Notification")
req.Header.Set("Priority", "high")
client := &http.Client{Timeout: 5 * time.Second}
resp, sendErr := client.Do(req)
if sendErr != nil {
log.Printf("ntfy notification failed: %v", sendErr)
return
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
log.Printf("ntfy notification returned status %d", resp.StatusCode)
}
}