|
@@ -6,39 +6,44 @@ import (
|
|
"net/http/cookiejar"
|
|
"net/http/cookiejar"
|
|
"net/url"
|
|
"net/url"
|
|
"strings"
|
|
"strings"
|
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gin-gonic/gin"
|
|
|
|
+ "github.com/patrickmn/go-cache"
|
|
"golang.org/x/net/publicsuffix"
|
|
"golang.org/x/net/publicsuffix"
|
|
)
|
|
)
|
|
|
|
|
|
// TODO: does tihs need to be a configuration thing? How would i handle doing rewrite rules?
|
|
// TODO: does tihs need to be a configuration thing? How would i handle doing rewrite rules?
|
|
-var staticRoutes = [...]string{
|
|
|
|
- "/siteaudit/i18n/messages_en",
|
|
|
|
- "/siteaudit/index/",
|
|
|
|
- "/siteaudit/review/",
|
|
|
|
- "/seo-dashboard/release/",
|
|
|
|
- "/competitive-list-widget/",
|
|
|
|
- "/backlink-audit/landing/",
|
|
|
|
- "/link-building-tool/landing/",
|
|
|
|
- "/keyword-overview/",
|
|
|
|
- "/keyword-gap/",
|
|
|
|
- "/oti/prod/organic_traffic_insights/",
|
|
|
|
- "/oti/prod/organic-traffic-insights",
|
|
|
|
- "/ajst/",
|
|
|
|
- "/listing-management/landings/",
|
|
|
|
- "/listing-management/landing-reviews/",
|
|
|
|
- "/messaging/apps/",
|
|
|
|
- "/domain-overview/",
|
|
|
|
- "/traffic-analytics/",
|
|
|
|
- "/organic-research/",
|
|
|
|
- "/keyword-magic/kmt_",
|
|
|
|
- "/keyword-manager-assets/",
|
|
|
|
- "/position-tracking/landing/",
|
|
|
|
|
|
+// TODO: make these routes cached on the proxy, so that when a client requests them, they arent being tunneled through to the actual site
|
|
|
|
+var staticRoutes = map[string]struct{}{
|
|
|
|
+ "/siteaudit/i18n": struct{}{},
|
|
|
|
+ "/siteaudit/index": struct{}{},
|
|
|
|
+ "/siteaudit/review": struct{}{},
|
|
|
|
+ "/seo-dashboard/release": struct{}{},
|
|
|
|
+ "/competitive-list-widget": struct{}{},
|
|
|
|
+ "/backlink-audit/landing": struct{}{},
|
|
|
|
+ "/link-building-tool/landing": struct{}{},
|
|
|
|
+ "/keyword-overview": struct{}{},
|
|
|
|
+ "/keyword-gap": struct{}{},
|
|
|
|
+ "/oti/prod/organic_traffic_insights": struct{}{},
|
|
|
|
+ "/oti/prod/organic-traffic-insights": struct{}{},
|
|
|
|
+ "/ajst": struct{}{},
|
|
|
|
+ "/listing-management/landings": struct{}{},
|
|
|
|
+ "/listing-management/landing-reviews": struct{}{},
|
|
|
|
+ "/messaging/apps/": struct{}{},
|
|
|
|
+ "/domain-overview": struct{}{},
|
|
|
|
+ "/traffic-analytics": struct{}{},
|
|
|
|
+ "/organic-research": struct{}{},
|
|
|
|
+ "/keyword-magic/kmt_": struct{}{},
|
|
|
|
+ "/keyword-manager-assets": struct{}{},
|
|
|
|
+ "/position-tracking/landing": struct{}{},
|
|
}
|
|
}
|
|
|
|
|
|
-var apiRoutes = [...]string{
|
|
|
|
- "/projects/api/",
|
|
|
|
- "/siteaudit/api/",
|
|
|
|
|
|
+var apiRoutes = map[string]struct{}{
|
|
|
|
+ "/siteaudit/api/campaigns/seolist": struct{}{},
|
|
|
|
+ "/siteaudit/api/system-status": struct{}{},
|
|
|
|
+ "/siteaudit/api/limits": struct{}{},
|
|
|
|
+ "/projects/api/limits": struct{}{},
|
|
}
|
|
}
|
|
|
|
|
|
// Implementing a 'set'
|
|
// Implementing a 'set'
|
|
@@ -52,9 +57,11 @@ var NonmutableHeaders = map[string]struct{}{
|
|
}
|
|
}
|
|
|
|
|
|
type Controller struct {
|
|
type Controller struct {
|
|
- Config *HttpServerConfig
|
|
|
|
- Client *http.Client
|
|
|
|
- SiteUrl *url.URL
|
|
|
|
|
|
+ Config *HttpServerConfig
|
|
|
|
+ RouteMaps map[string]*RouteMapping
|
|
|
|
+ Client *http.Client
|
|
|
|
+ SiteUrl *url.URL
|
|
|
|
+ cache *cache.Cache
|
|
}
|
|
}
|
|
|
|
|
|
type ProxyCookies struct {
|
|
type ProxyCookies struct {
|
|
@@ -66,7 +73,8 @@ Returns a new Controller struct to register routes to the gin router
|
|
|
|
|
|
:param cfg: A pointer to an HttpServerConfig struct
|
|
:param cfg: A pointer to an HttpServerConfig struct
|
|
*/
|
|
*/
|
|
-func NewController(cfg *HttpServerConfig) *Controller {
|
|
|
|
|
|
+func NewController(cfg *HttpServerConfig, routeMapping map[string]*RouteMapping) *Controller {
|
|
|
|
+
|
|
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
|
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
|
if err != nil {
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
log.Fatal(err)
|
|
@@ -78,8 +86,9 @@ func NewController(cfg *HttpServerConfig) *Controller {
|
|
log.Fatal(err)
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
jar.SetCookies(domain, sessCookies)
|
|
jar.SetCookies(domain, sessCookies)
|
|
|
|
+ cache := cache.New(24*time.Hour, 10*time.Minute)
|
|
|
|
|
|
- return &Controller{Config: cfg, Client: &http.Client{Jar: jar}, SiteUrl: domain}
|
|
|
|
|
|
+ return &Controller{Config: cfg, Client: &http.Client{Jar: jar}, SiteUrl: domain, cache: cache, RouteMaps: routeMapping}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -87,28 +96,39 @@ This handler will be responsible for proxying out the GET requests that the serv
|
|
*/
|
|
*/
|
|
func (c *Controller) Get(ctx *gin.Context) {
|
|
func (c *Controller) Get(ctx *gin.Context) {
|
|
incomingPath := ctx.Param("ProxiedPath")
|
|
incomingPath := ctx.Param("ProxiedPath")
|
|
- for idx := range staticRoutes {
|
|
|
|
- if strings.Contains(incomingPath, staticRoutes[idx]) {
|
|
|
|
|
|
+ routeSplit := strings.Split(incomingPath, "/")
|
|
|
|
+ if len(routeSplit) > 2 {
|
|
|
|
+ baseRoute := strings.Join(routeSplit[:len(routeSplit)-1], "/")
|
|
|
|
+
|
|
|
|
+ _, ok := c.RouteMaps[c.Config.AltAllowedDomain].RouteSet[baseRoute]
|
|
|
|
+ if ok {
|
|
data, ctype, rcode, err := c.RetrieveStaticResource(ctx.Request.Method, incomingPath, ctx)
|
|
data, ctype, rcode, err := c.RetrieveStaticResource(ctx.Request.Method, incomingPath, ctx)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Fatal(err, "reroute to the static domain")
|
|
|
|
|
|
+ log.Fatal(err, " failed to reroute to the static domain")
|
|
}
|
|
}
|
|
ctx.Data(rcode, ctype, data)
|
|
ctx.Data(rcode, ctype, data)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- for idx := range apiRoutes {
|
|
|
|
- if strings.Contains(incomingPath, apiRoutes[idx]) {
|
|
|
|
- data, ctype, err := c.SiteauditApiCall(ctx.Request.Method, incomingPath, ctx.Request.URL.RawQuery, ctx.Request.Body, ctx)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Fatal(err, "failed to route to the root domain")
|
|
|
|
- }
|
|
|
|
- ctx.Data(200, ctype, data)
|
|
|
|
- return
|
|
|
|
|
|
+ _, ok := c.RouteMaps[c.Config.AltAllowedDomain].RouteSet[incomingPath]
|
|
|
|
+ if ok {
|
|
|
|
+ data, ctype, rcode, err := c.RetrieveStaticResource(ctx.Request.Method, incomingPath, ctx)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err, " failed to reroute to the static domain")
|
|
}
|
|
}
|
|
|
|
+ ctx.Data(rcode, ctype, data)
|
|
|
|
+ return
|
|
}
|
|
}
|
|
-
|
|
|
|
- data, ctype, rcode, err := c.SemrushGeneric(ctx.Request.Method, incomingPath, ctx.Request.Body, ctx)
|
|
|
|
|
|
+ _, ok = c.RouteMaps[c.Config.AllowedDomain].RouteSet[incomingPath]
|
|
|
|
+ if ok {
|
|
|
|
+ data, ctype, rcode, err := c.SiteauditApiCall(ctx.Request.Method, incomingPath, ctx.Request.URL.RawQuery, ctx.Request.Body, ctx)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err, " failed to route to the root domain")
|
|
|
|
+ }
|
|
|
|
+ ctx.Data(rcode, ctype, data)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ data, ctype, rcode, err := c.SemrushGeneric(ctx)
|
|
if err != nil {
|
|
if err != nil {
|
|
ctx.JSON(rcode, map[string]string{
|
|
ctx.JSON(rcode, map[string]string{
|
|
"Error": err.Error(),
|
|
"Error": err.Error(),
|