Skip to content

Commit

Permalink
Redirect-short-links (httpjamesm#50)
Browse files Browse the repository at this point in the history
* feat: redirect shortened URLs

* feat: accept shortened URLs in converter

* fix: tell resty not to follow redirect

* fix: remove log
  • Loading branch information
httpjamesm authored Aug 21, 2023
1 parent 4760681 commit 2ef7e05
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
docker-compose.yml
.DS_Store
*bin
/tmp
/tmp
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ 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")))
Expand Down
8 changes: 6 additions & 2 deletions src/routes/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ 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 {
if !isStackExchange && !isStackOverflow && !isShortenedStackOverflow {
c.HTML(400, "home.html", gin.H{
"errorMessage": "Invalid stack overflow/exchange URL",
"theme": c.MustGet("theme").(string),
Expand All @@ -47,7 +51,7 @@ func PostHome(c *gin.Context) {
}

// if stack overflow, trim https://stackoverflow.com
if isStackOverflow {
if isStackOverflow || isShortenedStackOverflow {
c.Redirect(302, strings.TrimPrefix(soLink, "https://stackoverflow.com"))
return
}
Expand Down
44 changes: 44 additions & 0 deletions src/routes/shortened.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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))
}

0 comments on commit 2ef7e05

Please sign in to comment.