all repos

rss-tools @ 610059f

get rss feed from sources that(i need and) dont provide one

rss-tools/app/http.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
add auth middleware (at the moment only fixed token), 1 month ago
1
package app
2
3
import (
4
	"log/slog"
5
	"net/http"
6
	"strings"
7
	"time"
8
)
9
10
func (a *App) recoverMiddleware(next http.Handler) http.Handler {
11
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
12
		defer func() {
13
			if err := recover(); err != nil {
14
				a.Logger.Error("recover middleware", "err", err)
15
				w.WriteHeader(http.StatusInternalServerError)
16
			}
17
		}()
18
		next.ServeHTTP(w, r)
19
	})
20
}
21
22
func (a *App) loggingMiddleware(next http.Handler) http.Handler {
23
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24
		start := time.Now()
25
		wrapped := wrapResponseWriter(w)
26
		next.ServeHTTP(wrapped, r)
27
		slog.Info("http request",
28
			"method", r.Method,
29
			"status", wrapped.status,
30
			"path", r.URL.Path,
31
			"latency", time.Since(start).String(),
32
			"ua", r.UserAgent(),
33
		)
34
	})
35
}
36
37
func (a *App) authMiddleware(next http.Handler) http.Handler {
38
	if a.Config == nil || strings.TrimSpace(a.Config.AuthToken) == "" {
39
		return next
40
	}
41
42
	expected := strings.TrimSpace(a.Config.AuthToken)
43
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44
		queryToken := strings.TrimSpace(r.URL.Query().Get("token"))
45
		headerToken := strings.TrimSpace(r.Header.Get("Authorization"))
46
		if queryToken == expected || headerToken == expected {
47
			next.ServeHTTP(w, r)
48
			return
49
		}
50
51
		http.Error(w, "unauthorized", http.StatusUnauthorized)
52
	})
53
}
54
55
type responseWriter struct {
56
	http.ResponseWriter
57
	status      int
58
	wroteHeader bool
59
}
60
61
func wrapResponseWriter(w http.ResponseWriter) *responseWriter {
62
	return &responseWriter{ResponseWriter: w}
63
}
64
65
func (rw *responseWriter) Status() int {
66
	return rw.status
67
}
68
69
func (rw *responseWriter) WriteHeader(code int) {
70
	if rw.wroteHeader {
71
		return
72
	}
73
74
	rw.status = code
75
	rw.ResponseWriter.WriteHeader(code)
76
	rw.wroteHeader = true
77
}
78
79
func (rw *responseWriter) Flush() {
80
	if f, ok := rw.ResponseWriter.(http.Flusher); ok {
81
		f.Flush()
82
	}
83
}