ShortDragon/routes/routes.go

110 lines
2.9 KiB
Go

package routes
import (
"crypto/sha512"
"encoding/hex"
"net/http"
"git.1750studios.com/ToddShepard/ShortDragon/database"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"github.com/spf13/viper"
)
// Redirect redirects a user to the long URL specified by the short URL
func Redirect(c *gin.Context) {
var URL database.URL
short := c.Param("short")
err := database.Db.First(&URL, "short = ?", short).Error
if err != nil {
c.Redirect(http.StatusFound, viper.GetString("DefaultURL"))
return
}
if !URL.Long.Valid {
c.Redirect(http.StatusFound, viper.GetString("DefaultURL"))
return
}
if URL.Hits.Valid && !(c.Request.Header.Get("DNT") == "1") {
URL.Hits.Int64 = URL.Hits.Int64 + 1
database.Db.Save(&URL)
}
c.Redirect(http.StatusFound, URL.Long.String)
return
}
// Encode encodes a long URL and returns the short one
func Encode(c *gin.Context) {
var URL database.URL
var count uint
URL.Long.String = c.PostForm("LongURL")
URL.Long.Valid = true
database.Db.Where("long = ?", URL.Long.String).FirstOrInit(&URL)
if URL.Short.Valid {
c.Data(http.StatusOK, "text/plain", []byte(viper.GetString("ShortURL")+"/"+URL.Short.String))
return
}
URL.Short.String = c.DefaultPostForm("ShortURL", "")
if URL.Short.String == "" {
hasher := sha512.New()
hasher.Write([]byte(URL.Long.String))
hash := hex.EncodeToString(hasher.Sum(nil))
i := 2
for {
database.Db.Model(&database.URL{}).Where("short = ?", hash[0:i]).Count(&count)
if count > 0 && i < len(hash) {
i = i + 1
} else if count > 0 {
c.AbortWithStatus(http.StatusConflict)
return
} else {
URL.Short.String = hash[0:i]
break
}
}
}
URL.Short.Valid = true
URL.Hits.Int64 = 0
if c.DefaultPostForm("track", "true") == "true" {
URL.Hits.Valid = true
} else {
URL.Hits.Valid = false
}
err := database.Db.Create(&URL).Error
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
c.Data(http.StatusCreated, "text/plain", []byte(viper.GetString("ShortURL")+"/"+URL.Short.String))
return
}
// Decode decodes a short URL and returns the long one
func Decode(c *gin.Context) {
var URL database.URL
short := c.Param("short")
err := database.Db.Where("short = ?", short).Find(&URL).Error
if err != nil && err == gorm.ErrRecordNotFound {
c.Data(http.StatusNotFound, "text/plain", []byte("Record not found"))
return
} else if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.Data(http.StatusOK, "text/plain", []byte(URL.Long.String))
}
// Info decodes a short URL and returns the database content
func Info(c *gin.Context) {
var URL database.URL
short := c.Param("short")
err := database.Db.Where("short = ?", short).Find(&URL).Error
if err != nil && err == gorm.ErrRecordNotFound {
c.Data(http.StatusNotFound, "text/plain", []byte("Record not found"))
return
} else if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.JSON(http.StatusOK, URL)
}