add shortlink generator and handlers
This commit is contained in:
parent
233c5cb057
commit
10805ef2d5
9
main.go
9
main.go
@ -90,6 +90,11 @@ func main() {
|
||||
ActionTokenRepo: actionTokenRepo,
|
||||
},
|
||||
)
|
||||
linkService := services.NewShortlinkSevice(
|
||||
services.NewShortlinkServiceParams{
|
||||
Cache: repo.NewCacheInmem[string, string](7 * 24 * 60 * 60),
|
||||
},
|
||||
)
|
||||
|
||||
if !debugMode {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
@ -99,6 +104,10 @@ func main() {
|
||||
r.Use(middleware.NewRequestLogMiddleware(logger))
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
linkGroup := r.Group("/s")
|
||||
linkGroup.POST("/new", handlers.NewShortlinkCreateHandler(linkService))
|
||||
linkGroup.GET("/:linkId", handlers.NewShortlinkResolveHandler(linkService))
|
||||
|
||||
userGroup := r.Group("/user")
|
||||
userGroup.POST("/create", handlers.NewUserCreateHandler(userService))
|
||||
userGroup.POST("/login", handlers.NewUserLoginHandler(userService))
|
||||
|
||||
61
src/handlers/shortlink_handlers.go
Normal file
61
src/handlers/shortlink_handlers.go
Normal file
@ -0,0 +1,61 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"backend/src/services"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type shortlinkCreateOutput struct {
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
func NewShortlinkCreateHandler(shortlinkService services.ShortlinkService) gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
rawUrl := ctx.Query("url")
|
||||
if rawUrl == "" {
|
||||
ctx.AbortWithError(400, fmt.Errorf("no url param"))
|
||||
return
|
||||
}
|
||||
|
||||
u, err := url.Parse(rawUrl)
|
||||
if err != nil {
|
||||
ctx.Data(500, "plain/text", []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
u.Scheme = "https"
|
||||
|
||||
linkId, err := shortlinkService.CreateLink(u.String())
|
||||
if err != nil {
|
||||
ctx.Data(500, "plain/text", []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
resultBody, err := json.Marshal(shortlinkCreateOutput{
|
||||
Link: "https:/nucrea.ru/s/" + linkId,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data(200, "application/json", resultBody)
|
||||
}
|
||||
}
|
||||
|
||||
func NewShortlinkResolveHandler(shortlinkService services.ShortlinkService) gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
linkId := ctx.Param("linkId")
|
||||
|
||||
linkUrl, err := shortlinkService.GetLink(linkId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(301, linkUrl)
|
||||
}
|
||||
}
|
||||
60
src/services/shortlink_service.go
Normal file
60
src/services/shortlink_service.go
Normal file
@ -0,0 +1,60 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"backend/src/repo"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ShortlinkService interface {
|
||||
CreateLink(in string) (string, error)
|
||||
GetLink(id string) (string, error)
|
||||
}
|
||||
|
||||
type NewShortlinkServiceParams struct {
|
||||
Endpoint string
|
||||
Cache repo.Cache[string, string]
|
||||
}
|
||||
|
||||
func NewShortlinkSevice(params NewShortlinkServiceParams) ShortlinkService {
|
||||
return &shortlinkService{
|
||||
cache: params.Cache,
|
||||
}
|
||||
}
|
||||
|
||||
type shortlinkService struct {
|
||||
cache repo.Cache[string, string]
|
||||
}
|
||||
|
||||
func (s *shortlinkService) randomStr() string {
|
||||
src := rand.NewSource(time.Now().UnixMicro())
|
||||
randGen := rand.New(src)
|
||||
|
||||
builder := strings.Builder{}
|
||||
for i := 0; i < 9; i++ {
|
||||
offset := 0x41
|
||||
if randGen.Int()%2 == 1 {
|
||||
offset = 0x61
|
||||
}
|
||||
|
||||
byte := offset + (randGen.Int() % 26)
|
||||
builder.WriteRune(rune(byte))
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func (s *shortlinkService) CreateLink(in string) (string, error) {
|
||||
str := s.randomStr()
|
||||
s.cache.Set(str, in, 7*24*60*60)
|
||||
return str, nil
|
||||
}
|
||||
|
||||
func (s *shortlinkService) GetLink(id string) (string, error) {
|
||||
val, ok := s.cache.Get(id)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("link does not exist or expired")
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user