2018-06-09 15:22:25 +00:00
|
|
|
package routes
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha512"
|
|
|
|
"encoding/base64"
|
|
|
|
"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))
|
|
|
|
base := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
|
2018-06-09 16:26:21 +00:00
|
|
|
i := 2
|
2018-06-09 15:22:25 +00:00
|
|
|
for {
|
|
|
|
database.Db.Model(&database.URL{}).Where("short = ?", base[0:i]).Count(&count)
|
|
|
|
if count > 0 && i < len(base) {
|
|
|
|
i = i + 1
|
|
|
|
} else if count > 0 {
|
|
|
|
c.AbortWithStatus(http.StatusConflict)
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
URL.Short.String = base[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)
|
|
|
|
}
|