123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- package httpserver
- import (
- "fmt"
- "io"
- "net/http"
- "strings"
- "github.com/gin-gonic/gin"
- )
- /*
- Retrieve the site audit config file from Semrush
- returns a byte array of the body, the content type of the resp, and an error
- */
- func (c *Controller) RetrieveStaticResource(method string, path string, ctx *gin.Context) ([]byte, string, int, error) {
- cacheResp := c.GetResource(path)
- if cacheResp != nil {
- return cacheResp.Data, cacheResp.Ctype, cacheResp.Rcode, nil
- }
- url := fmt.Sprintf("%s%s", c.Config.FullAltAllowedDomain, path)
- req, err := http.NewRequest(method, url, nil)
- if err != nil {
- return nil, "", 500, err
- }
- c.setHeaders(req, ctx)
- resp, err := c.Client.Do(req)
- if err != nil {
- return nil, "", 500, err
- }
- defer resp.Body.Close()
- b, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, "", 500, err
- }
- if resp.StatusCode == 200 {
- c.CacheResource(path, NewCachedResource(b, resp.Header.Get("content-type"), resp.StatusCode))
- }
- return c.pageMod(b), resp.Header.Get("content-type"), resp.StatusCode, nil
- }
- /*
- Perform a call against the siteaudit api
- :param path: the URI path with the query
- :param query: the query to add to the request
- :param body: an io.Reader to push into the request body
- :returns a byte array of the response, the content type and an error
- */
- func (c *Controller) SiteauditApiCall(method string, path string, query string, body io.Reader, ctx *gin.Context) ([]byte, string, int, error) {
- query = strings.ReplaceAll(query, c.Config.FullProxyDomain, c.Config.FullDomain)
- url := fmt.Sprintf("%s%s?%s", c.Config.FullDomain, path, query)
- req, err := http.NewRequest(method, url, body)
- if err != nil {
- return nil, "", 500, err
- }
- c.setHeaders(req, ctx)
- resp, err := c.Client.Do(req)
- if err != nil {
- return nil, "", 500, err
- }
- defer resp.Body.Close()
- b, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, "", 500, err
- }
- return c.pageMod(b), resp.Header.Get("content-type"), resp.StatusCode, nil
- }
- /*
- Generic site call to the semrush site
- */
- func (c *Controller) SemrushGeneric(ctx *gin.Context) ([]byte, string, int, error) {
- path := ctx.Param("ProxiedPath")
- method := ctx.Request.Method
- query := ctx.Request.URL.RawQuery
- body := ctx.Request.Body
- var reqUrl string
- if query != "" {
- reqUrl = fmt.Sprintf("%s%s?%s", c.Config.FullDomain, path, query)
- } else {
- reqUrl = fmt.Sprintf("%s%s", c.Config.FullDomain, path)
- }
- cacheResp := c.GetResource(path)
- if cacheResp != nil {
- return cacheResp.Data, cacheResp.Ctype, cacheResp.Rcode, nil
- }
- req, err := http.NewRequest(method, reqUrl, body)
- if err != nil {
- return nil, "", 500, err
- }
- c.setHeaders(req, ctx)
- resp, err := c.Client.Do(req)
- if err != nil {
- return nil, "", 500, err
- }
- defer resp.Body.Close()
- b, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, "", 500, err
- }
- for k, v := range resp.Header {
- _, ok := NonmutableHeaders[k]
- if !ok {
- ctx.Header(k, v[0])
- }
- }
- if resp.StatusCode == 200 {
- if query == "" {
- if method == "GET" {
- c.CacheResource(path, NewCachedResource(b, resp.Header.Get("content-type"), resp.StatusCode))
- }
- }
- }
- return c.pageMod(b), resp.Header.Get("content-type"), resp.StatusCode, nil
- }
- /*
- Sets the request headers to whatever is defined in this private method
- :param req: a pointer to an HTTP request
- */
- func (c *Controller) setHeaders(req *http.Request, ctx *gin.Context) {
- req.AddCookie(c.Config.PhpSession)
- req.AddCookie(c.Config.SsoToken)
- req.Header.Set("User-Agent", c.Config.UserAgent)
- req.Header.Set("Referer", c.Config.FullDomain)
- req.Header.Set("Origin", c.Config.FullDomain)
- for k, v := range ctx.Request.Header {
- _, ok := NonmutableHeaders[k]
- if !ok {
- req.Header.Add(k, v[0])
- }
- }
- }
- /*
- Rewrite all occurences of these values into the response body
- */
- func (c *Controller) pageMod(data []byte) []byte {
- newBody := strings.ReplaceAll(string(data), "\"srf-browser-unhappy\"", "\"srf-browser-unhappy\" style=\"display:none;\"")
- newBody = strings.ReplaceAll(newBody, "\"srf-navbar__right\"", "\"srf-navbar__right\" style=\"display:none;\"")
- newBody = strings.ReplaceAll(newBody, "<footer", "<footer style=\"display:none;\"")
- newBody = strings.ReplaceAll(newBody, "\"srf-report-sidebar-extras\"", "\"srf-report-sidebar-extra\" style=\"display:none;\"")
- newBody = strings.ReplaceAll(newBody, c.Config.AllowedDomain, c.Config.ProxyAddr)
- newBody = strings.ReplaceAll(newBody, c.Config.AltAllowedDomain, c.Config.ProxyAddr)
- return []byte(newBody)
- }
|