38 lines
1003 B
Go
38 lines
1003 B
Go
package httpx
|
||
|
||
import (
|
||
"crypto/sha256"
|
||
"crypto/subtle"
|
||
"net/http"
|
||
"strings"
|
||
)
|
||
|
||
// MetricsGate 实现 DEVELOPMENT 4.3 节 /metrics 访问规则(共用端口)。
|
||
// token 为空返回 404;Authorization Bearer 不匹配返回 401;匹配则交给 next。
|
||
// 后台单独监听时不要包这层,直接挂 metrics Handler。
|
||
func MetricsGate(token string, next http.Handler) http.Handler {
|
||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
if token == "" {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
auth := r.Header.Get("Authorization")
|
||
const prefix = "Bearer "
|
||
if !strings.HasPrefix(auth, prefix) || !tokenEqual(auth[len(prefix):], token) {
|
||
w.WriteHeader(http.StatusUnauthorized)
|
||
return
|
||
}
|
||
if next == nil {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
next.ServeHTTP(w, r)
|
||
})
|
||
}
|
||
|
||
func tokenEqual(got, want string) bool {
|
||
sumGot := sha256.Sum256([]byte(got))
|
||
sumWant := sha256.Sum256([]byte(want))
|
||
return subtle.ConstantTimeCompare(sumGot[:], sumWant[:]) == 1
|
||
}
|