2023-02-26 22:26:09 +00:00
package proxy
import (
"net/http"
"github.com/gorilla/mux"
2023-03-10 20:59:56 +00:00
"time"
2023-03-25 20:15:00 +00:00
"github.com/azukaar/cosmos-server/src/utils"
"github.com/azukaar/cosmos-server/src/user"
2023-03-18 19:59:32 +00:00
"strconv"
2023-03-10 20:59:56 +00:00
"github.com/go-chi/httprate"
2023-03-18 19:59:32 +00:00
"regexp"
2023-02-26 22:26:09 +00:00
)
2023-03-18 19:59:32 +00:00
func tokenMiddleware ( enabled bool ) func ( next http . Handler ) http . Handler {
return func ( next http . Handler ) http . Handler {
return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
r . Header . Set ( "x-cosmos-user" , "" )
r . Header . Set ( "x-cosmos-role" , "" )
u , err := user . RefreshUserToken ( w , r )
if err != nil {
return
}
r . Header . Set ( "x-cosmos-user" , u . Nickname )
r . Header . Set ( "x-cosmos-role" , strconv . Itoa ( ( int ) ( u . Role ) ) )
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" )
if ( enabled ) {
utils . LoggedInOnlyWithRedirect ( w , r ) ;
}
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-02-26 22:26:09 +00:00
origin := router . Methods ( "GET" , "POST" , "PUT" , "DELETE" , "PATCH" , "OPTIONS" , "HEAD" )
if ( route . UseHost ) {
origin = origin . Host ( route . Host )
}
if ( route . UsePathPrefix ) {
2023-03-31 19:19:38 +00:00
if ( route . PathPrefix != "" && route . PathPrefix [ 0 ] != '/' ) {
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 ) {
2023-03-31 19:19:38 +00:00
if ( route . PathPrefix != "" && route . PathPrefix [ 0 ] != '/' ) {
utils . Error ( "PathPrefix must start with a /" , nil )
}
destination = http . StripPrefix ( route . PathPrefix , destination )
2023-02-26 22:26:09 +00:00
}
2023-03-10 20:59:56 +00:00
timeout := route . Timeout
if ( timeout == 0 ) {
timeout = 10000
}
throttlePerMinute := route . ThrottlePerMinute
if ( throttlePerMinute == 0 ) {
throttlePerMinute = 60
}
originCORS := route . CORSOrigin
if originCORS == "" {
if route . UseHost {
originCORS = route . Host
} else {
originCORS = utils . GetMainConfig ( ) . HTTPConfig . Hostname
}
}
2023-03-31 19:19:38 +00:00
if ( route . UsePathPrefix && ! route . StripPathPrefix && ( route . Mode == "STATIC" || route . Mode == "SPA" ) ) {
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." )
}
2023-03-10 20:59:56 +00:00
origin . Handler (
2023-03-18 19:59:32 +00:00
tokenMiddleware ( route . AuthEnabled ) (
2023-03-10 20:59:56 +00:00
utils . CORSHeader ( originCORS ) (
utils . MiddlewareTimeout ( timeout * time . Millisecond ) (
httprate . Limit ( throttlePerMinute , 1 * time . Minute ,
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" ,
http . StatusTooManyRequests , "HTTP003" )
return
} ) ,
2023-03-31 19:19:38 +00:00
) ( destination ) ) ) ) )
utils . Log ( "Added route: [" + ( string ) ( route . Mode ) + "] " + route . Host + route . PathPrefix + " to " + route . Target + "" )
2023-02-26 22:26:09 +00:00
return origin
}