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) }