2023-03-10 20:59:56 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
2023-04-18 15:50:12 +00:00
|
|
|
"github.com/mxk/go-flowrate/flowrate"
|
2023-03-10 20:59:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// https://github.com/go-chi/chi/blob/master/middleware/timeout.go
|
|
|
|
|
|
|
|
func MiddlewareTimeout(timeout time.Duration) func(next http.Handler) http.Handler {
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), timeout)
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
if ctx.Err() == context.DeadlineExceeded {
|
|
|
|
Error("Request Timeout. Cancelling.", ctx.Err())
|
|
|
|
HTTPError(w, "Gateway Timeout",
|
|
|
|
http.StatusGatewayTimeout, "HTTP002")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2023-04-04 20:54:35 +00:00
|
|
|
w.Header().Set("X-Timeout-Duration", timeout.String())
|
|
|
|
|
2023-03-10 20:59:56 +00:00
|
|
|
r = r.WithContext(ctx)
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
return http.HandlerFunc(fn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-18 15:50:12 +00:00
|
|
|
type responseWriter struct {
|
|
|
|
http.ResponseWriter
|
|
|
|
*flowrate.Writer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *responseWriter) Write(b []byte) (int, error) {
|
|
|
|
return w.Writer.Write(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func BandwithLimiterMiddleware(max int64) func(next http.Handler) http.Handler {
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if(max > 0) {
|
|
|
|
fw := flowrate.NewWriter(w, max)
|
|
|
|
w = &responseWriter{w, fw}
|
|
|
|
}
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-10 20:59:56 +00:00
|
|
|
func SetSecurityHeaders(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if(IsHTTPS) {
|
|
|
|
// TODO: Add preload if we have a valid certificate
|
|
|
|
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
|
|
w.Header().Set("X-Frame-Options", "DENY")
|
|
|
|
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
2023-03-18 19:59:32 +00:00
|
|
|
w.Header().Set("X-Served-By-Cosmos", "1")
|
|
|
|
w.Header().Set("Referrer-Policy", "no-referrer")
|
2023-03-10 20:59:56 +00:00
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func CORSHeader(origin string) func(next http.Handler) http.Handler {
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2023-03-18 19:59:32 +00:00
|
|
|
|
2023-03-10 20:59:56 +00:00
|
|
|
w.Header().Set("Access-Control-Allow-Origin", origin)
|
|
|
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
|
|
|
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
|
|
|
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func AcceptHeader(accept string) func(next http.Handler) http.Handler {
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.Header().Set("Content-Type", accept)
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|