first commit
This commit is contained in:
93
internal/handlers/links.go
Normal file
93
internal/handlers/links.go
Normal file
@@ -0,0 +1,93 @@
|
||||
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
|
||||
}
|
||||
11
internal/handlers/ping.go
Normal file
11
internal/handlers/ping.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Ping(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"status": "success"})
|
||||
}
|
||||
Reference in New Issue
Block a user