Compare commits

..

3 Commits

Author SHA1 Message Date
httpjamesm 72a7392142 Merge branch 'main' into concurrency-improvements 2023-08-21 01:08:06 -04:00
httpjamesm 1f77bf4ed6 Merge branch 'main' into concurrency-improvements 2023-08-21 01:07:02 -04:00
httpjamesm 50fc162b47 refactor: concurrently proxy img tags 2023-08-21 01:04:11 -04:00
5 changed files with 19 additions and 60 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
docker-compose.yml
.DS_Store
*bin
/tmp
/tmp
-2
View File
@@ -50,8 +50,6 @@ func main() {
r.GET("/", routes.GetHome)
r.POST("/", routes.PostHome)
r.GET("/a/:id", routes.RedirectShortenedOverflowURL)
r.GET("/questions/:id", func(c *gin.Context) {
// redirect user to the question with the title
c.Redirect(302, fmt.Sprintf("/questions/%s/placeholder", c.Param("id")))
+2 -6
View File
@@ -35,14 +35,10 @@ func PostHome(c *gin.Context) {
soLink := body.URL
// remove the www.
soLink = strings.ReplaceAll(soLink, "www.", "")
// validate URL
isStackOverflow := strings.HasPrefix(soLink, "https://stackoverflow.com/questions/")
isShortenedStackOverflow := strings.HasPrefix(soLink, "https://stackoverflow.com/a/")
isStackExchange := stackExchangeRegex.MatchString(soLink)
if !isStackExchange && !isStackOverflow && !isShortenedStackOverflow {
if !isStackExchange && !isStackOverflow {
c.HTML(400, "home.html", gin.H{
"errorMessage": "Invalid stack overflow/exchange URL",
"theme": c.MustGet("theme").(string),
@@ -51,7 +47,7 @@ func PostHome(c *gin.Context) {
}
// if stack overflow, trim https://stackoverflow.com
if isStackOverflow || isShortenedStackOverflow {
if isStackOverflow {
c.Redirect(302, strings.TrimPrefix(soLink, "https://stackoverflow.com"))
return
}
-44
View File
@@ -1,44 +0,0 @@
package routes
import (
"fmt"
"net/http"
"os"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
)
func RedirectShortenedOverflowURL(c *gin.Context) {
id := c.Param("id")
// fetch the stack overflow URL
client := resty.New()
client.SetRedirectPolicy(
resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}),
)
resp, err := client.R().Get(fmt.Sprintf("https://www.stackoverflow.com/a/%s", id))
if err != nil {
c.HTML(400, "home.html", gin.H{
"errorMessage": "Unable to fetch stack overflow URL",
"theme": c.MustGet("theme").(string),
})
return
}
if resp.StatusCode() != 302 {
c.HTML(400, "home.html", gin.H{
"errorMessage": fmt.Sprintf("Unexpected HTTP status from origin: %d", resp.StatusCode()),
"theme": c.MustGet("theme").(string),
})
return
}
// get the redirect URL
location := resp.Header().Get("Location")
c.Redirect(302, fmt.Sprintf("%s%s", os.Getenv("APP_URL"), location))
}
+16 -7
View File
@@ -6,6 +6,7 @@ import (
"os"
"regexp"
"strings"
"sync"
"time"
"github.com/golang-jwt/jwt/v4"
@@ -14,20 +15,28 @@ import (
var imgTagRegex = regexp.MustCompile(`<img[^>]*\s+src\s*=\s*"(.*?)"[^>]*>`)
func ReplaceImgTags(inHtml string) string {
// find all img tags
imgTags := imgTagRegex.FindAllString(inHtml, -1)
var wg sync.WaitGroup
var mu sync.Mutex
for _, imgTag := range imgTags {
// parse the src="" attribute
srcRegex := regexp.MustCompile(`src\s*=\s*"(.*?)"`)
src := srcRegex.FindStringSubmatch(imgTag)[1]
wg.Add(1)
go func(imgTag string) {
defer wg.Done()
srcRegex := regexp.MustCompile(`src\s*=\s*"(.*?)"`)
src := srcRegex.FindStringSubmatch(imgTag)[1]
authToken, _ := generateImageProxyAuth(src)
authToken, _ := generateImageProxyAuth(src)
// replace the img tag with a proxied url
inHtml = strings.Replace(inHtml, imgTag, fmt.Sprintf(`<img src="%s/proxy?auth=%s">`, os.Getenv("APP_URL"), authToken), 1)
mu.Lock()
defer mu.Unlock()
inHtml = strings.Replace(inHtml, imgTag, fmt.Sprintf(`<img src="%s/proxy?auth=%s">`, os.Getenv("APP_URL"), authToken), 1)
}(imgTag)
}
wg.Wait()
return inHtml
}