94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"example.com/m/internal/services"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type LinksHandler struct {
|
|
service *services.LinksService
|
|
host string
|
|
port string
|
|
}
|
|
|
|
type CreateLinkResponse struct {
|
|
Status string `json:"status"`
|
|
ShortLink string `json:"short_link"`
|
|
OriginalLink string `json:"original_link"`
|
|
ExpiresIn string `json:"expires_in"`
|
|
}
|
|
|
|
func NewLinksHandler(service *services.LinksService, host string, port string) *LinksHandler {
|
|
return &LinksHandler{service: service, host: host, port: port}
|
|
}
|
|
|
|
func (h *LinksHandler) CreateLink(c *gin.Context) {
|
|
link := c.Param("link")
|
|
link = strings.TrimPrefix(link, "/")
|
|
if c.Request.URL.RawQuery != "" {
|
|
link += "?" + c.Request.URL.RawQuery
|
|
}
|
|
|
|
link, err := NormalizeURL(link)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "failed", "message": "invalid link"})
|
|
return
|
|
}
|
|
|
|
id, err := h.service.CreateLink(link)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed", "message": "failed to create link"})
|
|
return
|
|
}
|
|
|
|
address := fmt.Sprintf("http://%v:%s/r/%v", h.host, h.port, id)
|
|
|
|
response := CreateLinkResponse{
|
|
Status: "success",
|
|
ShortLink: address,
|
|
OriginalLink: link,
|
|
ExpiresIn: "30d",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
func (h *LinksHandler) Redirect(c *gin.Context) {
|
|
id := c.Param("id")
|
|
original, err := h.service.GetLink(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "failed", "message": "link not found"})
|
|
return
|
|
}
|
|
|
|
c.Redirect(http.StatusFound, original)
|
|
}
|
|
|
|
func NormalizeURL(raw string) (string, error) {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" {
|
|
return "", errors.New("empty URL")
|
|
}
|
|
|
|
if !strings.HasPrefix(raw, "http://") && !strings.HasPrefix(raw, "https://") {
|
|
raw = "https://" + raw
|
|
}
|
|
|
|
u, err := url.Parse(raw)
|
|
if err != nil {
|
|
return "", errors.New("invalid URL")
|
|
}
|
|
|
|
if u.Host == "" {
|
|
return "", errors.New("invalid host in URL")
|
|
}
|
|
|
|
return u.String(), nil
|
|
}
|