all repos

rss-tools @ 01ec2af

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
http: setup auth middleware only when token is provided, 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
	expected := strings.TrimSpace(a.Config.AuthToken)
39
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
40
		queryToken := strings.TrimSpace(r.URL.Query().Get("token"))
41
		headerToken := strings.TrimSpace(r.Header.Get("Authorization"))
42
		if queryToken == expected || headerToken == expected {
43
			next.ServeHTTP(w, r)
44
			return
45
		}
46
47
		http.Error(w, "unauthorized", http.StatusUnauthorized)
48
	})
49
}
50
51
type responseWriter struct {
52
	http.ResponseWriter
53
	status      int
54
	wroteHeader bool
55
}
56
57
func wrapResponseWriter(w http.ResponseWriter) *responseWriter {
58
	return &responseWriter{ResponseWriter: w}
59
}
60
61
func (rw *responseWriter) Status() int {
62
	return rw.status
63
}
64
65
func (rw *responseWriter) WriteHeader(code int) {
66
	if rw.wroteHeader {
67
		return
68
	}
69
70
	rw.status = code
71
	rw.ResponseWriter.WriteHeader(code)
72
	rw.wroteHeader = true
73
}
74
75
func (rw *responseWriter) Flush() {
76
	if f, ok := rw.ResponseWriter.(http.Flusher); ok {
77
		f.Flush()
78
	}
79
}