// ___ ____ ___ ___ // \ \ / / | _ | __| \ \ / / || | __ || || _ | // \ \/ / |___ | |__ \ \/ / || |___ || ||___| // \ / | _ | _ | \ / || __ | || ||\\ // \/ |___ |___ | \/ || ____| || || \\ // // Copyright (c) 2021 Piotr Biernat. https://pbiernat.dev. MIT License // Repo: https://git.pbiernat.dev/golang/vegvisir package server import ( "fmt" "regexp" "strings" "vegvisir/pkg/cache" "vegvisir/pkg/config" ) type Router struct { config *config.Config rcm cache.RouteCacheManager // Redis cache rCache map[string]cache.RouteCache // Internal route cache - TMP? } type Route struct { SourceUrl string TargetUrl string } func NewRouter(conf *config.Config, cacheDS cache.CacheDatastore, ttl int) *Router { return &Router{ config: conf, rcm: cache.NewRouteCacheManager(cacheDS, ttl), rCache: make(map[string]cache.RouteCache), } } func (r *Router) FindByRequestURL(url []byte) (bool, Route) { var sUrl string = string(url) for bId := range r.config.Backends { bck := r.config.Backends[bId] if !strings.Contains(sUrl, bck.PrefixUrl) { continue } for rId := range bck.Routes { routeCfg := &bck.Routes[rId] // if ok, cRoute := s.rCacheManager.Load(sUri); ok { // return true, cRoute // } if cRoute, ok := r.rCache[sUrl]; ok { route := Route{ SourceUrl: cRoute.SourceUrl, TargetUrl: cRoute.TargetUrl, } return true, route } rgxp := regexp.MustCompile(fmt.Sprintf("%s%s", bck.PrefixUrl, routeCfg.Pattern)) if rgxp.Match(url) { targetUrl := bck.BackendAddress + rgxp.ReplaceAllString(sUrl, routeCfg.Target) route := Route{ SourceUrl: sUrl, TargetUrl: targetUrl, } // s.rCacheManager.Save(sUri, cRoute) r.rCache[sUrl] = cache.RouteCache{ SourceUrl: route.SourceUrl, TargetUrl: route.TargetUrl, } return true, route } } } return false, Route{} }