Cosmos-Server/src/proxy/routerGen.go

150 lines
4.3 KiB
Go
Raw Normal View History

2023-02-26 22:26:09 +00:00
package proxy
import (
"net/http"
"regexp"
"strconv"
2023-03-10 20:59:56 +00:00
"time"
2023-03-25 20:15:00 +00:00
"github.com/azukaar/cosmos-server/src/user"
"github.com/azukaar/cosmos-server/src/utils"
2023-03-10 20:59:56 +00:00
"github.com/go-chi/httprate"
"github.com/gorilla/mux"
2023-02-26 22:26:09 +00:00
)
2023-05-01 11:59:46 +00:00
func tokenMiddleware(enabled bool, adminOnly bool) func(next http.Handler) http.Handler {
2023-03-18 19:59:32 +00:00
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.Header.Del("x-cosmos-user")
r.Header.Del("x-cosmos-role")
r.Header.Del("x-cosmos-mfa")
2023-03-18 19:59:32 +00:00
u, err := user.RefreshUserToken(w, r)
2023-03-18 19:59:32 +00:00
if err != nil {
return
}
2023-03-18 19:59:32 +00:00
r.Header.Set("x-cosmos-user", u.Nickname)
r.Header.Set("x-cosmos-role", strconv.Itoa((int)(u.Role)))
r.Header.Set("x-cosmos-mfa", strconv.Itoa((int)(u.MFAState)))
2023-03-18 19:59:32 +00:00
ogcookies := r.Header.Get("Cookie")
cookieRemoveRegex := regexp.MustCompile(`jwttoken=[^;]*;`)
cookies := cookieRemoveRegex.ReplaceAllString(ogcookies, "")
r.Header.Set("Cookie", cookies)
// Replace the token with a application speicfic one
r.Header.Set("x-cosmos-token", "1234567890")
2023-05-01 11:59:46 +00:00
if enabled && adminOnly {
2023-05-01 12:07:01 +00:00
if errT := utils.AdminOnlyWithRedirect(w, r); errT != nil {
return
}
2023-05-01 11:59:46 +00:00
} else if enabled {
2023-05-01 12:07:01 +00:00
if errT := utils.LoggedInOnlyWithRedirect(w, r); errT != nil {
return
}
2023-03-18 19:59:32 +00:00
}
next.ServeHTTP(w, r)
})
}
}
2023-03-31 19:19:38 +00:00
func RouterGen(route utils.ProxyRouteConfig, router *mux.Router, destination http.Handler) *mux.Route {
2023-06-17 17:08:26 +00:00
origin := router.NewRoute()
2023-02-26 22:26:09 +00:00
if route.UseHost {
2023-02-26 22:26:09 +00:00
origin = origin.Host(route.Host)
}
if route.UsePathPrefix {
if route.PathPrefix != "" && route.PathPrefix[0] != '/' {
2023-03-31 19:19:38 +00:00
utils.Error("PathPrefix must start with a /", nil)
}
2023-02-26 22:26:09 +00:00
origin = origin.PathPrefix(route.PathPrefix)
2023-03-12 18:17:28 +00:00
}
if route.UsePathPrefix && route.StripPathPrefix {
if route.PathPrefix != "" && route.PathPrefix[0] != '/' {
2023-03-31 19:19:38 +00:00
utils.Error("PathPrefix must start with a /", nil)
}
destination = http.StripPrefix(route.PathPrefix, destination)
2023-02-26 22:26:09 +00:00
}
2023-07-19 10:27:48 +00:00
for filter := range route.AddionalFilters {
if route.AddionalFilters[filter].Type == "header" {
origin = origin.Headers(route.AddionalFilters[filter].Name, route.AddionalFilters[filter].Value)
} else if route.AddionalFilters[filter].Type == "query" {
origin = origin.Queries(route.AddionalFilters[filter].Name, route.AddionalFilters[filter].Value)
} else if route.AddionalFilters[filter].Type == "method" {
origin = origin.Methods(route.AddionalFilters[filter].Value)
} else {
utils.Error("Unknown filter type: "+route.AddionalFilters[filter].Type, nil)
}
}
destination = SmartShieldMiddleware(route.SmartShield)(destination)
2023-03-10 20:59:56 +00:00
originCORS := route.CORSOrigin
if originCORS == "" {
if route.UseHost {
originCORS = route.Host
} else {
originCORS = utils.GetMainConfig().HTTPConfig.Hostname
}
}
if route.UsePathPrefix && !route.StripPathPrefix && (route.Mode == "STATIC" || route.Mode == "SPA") {
2023-03-31 19:19:38 +00:00
utils.Warn("PathPrefix is used, but StripPathPrefix is false. The route mode is " + (string)(route.Mode) + ". This will likely cause issues with the route. Ignore this warning if you know what you are doing.")
}
timeout := route.Timeout
2023-05-10 17:17:11 +00:00
if(!utils.GetMainConfig().HTTPConfig.AcceptAllInsecureHostname) {
destination = utils.EnsureHostname(destination)
}
if timeout > 0 {
destination = utils.MiddlewareTimeout(timeout * time.Millisecond)(destination)
}
2023-03-31 19:19:38 +00:00
throttlePerMinute := route.ThrottlePerMinute
if throttlePerMinute > 0 {
throtthleTime := time.Minute
destination = httprate.Limit(throttlePerMinute, throtthleTime,
2023-03-10 20:59:56 +00:00
httprate.WithKeyFuncs(httprate.KeyByIP),
httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
utils.Error("Too many requests. Throttling", nil)
utils.HTTPError(w, "Too many requests",
2023-03-10 20:59:56 +00:00
http.StatusTooManyRequests, "HTTP003")
return
2023-03-10 20:59:56 +00:00
}),
)(destination)
}
if route.MaxBandwith > 0 {
destination = utils.BandwithLimiterMiddleware(route.MaxBandwith)(destination)
}
if route.BlockCommonBots {
destination = BotDetectionMiddleware(destination)
}
if route.BlockAPIAbuse {
destination = utils.BlockPostWithoutReferer(destination)
}
2023-05-01 11:59:46 +00:00
destination = tokenMiddleware(route.AuthEnabled, route.AdminOnly)(utils.CORSHeader(originCORS)((destination)))
origin.Handler(destination)
2023-03-31 19:19:38 +00:00
utils.Log("Added route: [" + (string)(route.Mode) + "] " + route.Host + route.PathPrefix + " to " + route.Target + "")
2023-02-26 22:26:09 +00:00
return origin
}