This commit is contained in:
Tomas Dvorak
2025-10-28 22:38:27 +01:00
parent 3d621e2187
commit 823fabee02
106 changed files with 9011 additions and 3930 deletions
@@ -12,8 +12,11 @@ import (
"strings"
"time"
"fotbal-club/internal/config"
"github.com/disintegration/imaging"
"github.com/gin-gonic/gin"
_ "golang.org/x/image/webp"
)
type ImageProcessingController struct{}
@@ -143,9 +146,20 @@ func (ctrl *ImageProcessingController) ProcessImage(c *gin.Context) {
return
}
// Return the new URL
scheme := "http"
if c.Request.TLS != nil || strings.EqualFold(c.Request.Header.Get("X-Forwarded-Proto"), "https") {
scheme = "https"
}
host := c.Request.Host
if xf := strings.TrimSpace(c.Request.Header.Get("X-Forwarded-Host")); xf != "" {
xfl := strings.ToLower(xf)
if !strings.Contains(xfl, ":3000") && !strings.HasPrefix(xfl, "localhost:") && !strings.HasPrefix(xfl, "127.0.0.1:") {
host = xf
}
}
absolute := scheme + "://" + host + outputPath
c.JSON(http.StatusOK, gin.H{
"url": outputPath,
"url": absolute,
"format": format,
})
}
@@ -154,8 +168,14 @@ func (ctrl *ImageProcessingController) ProcessImage(c *gin.Context) {
func (ctrl *ImageProcessingController) loadImage(imageURL string) (image.Image, string, error) {
// Check if it's a local file path
if strings.HasPrefix(imageURL, "/uploads/") || strings.HasPrefix(imageURL, "uploads/") {
// Local file
localPath := filepath.Join(".", imageURL)
// Local file under configured uploads dir
base := config.AppConfig.UploadDir
if strings.TrimSpace(base) == "" {
base = "./uploads"
}
rel := strings.TrimPrefix(imageURL, "/")
rel = strings.TrimPrefix(rel, "uploads/")
localPath := filepath.Join(base, filepath.FromSlash(rel))
file, err := os.Open(localPath)
if err != nil {
return nil, "", fmt.Errorf("failed to open local file: %w", err)
@@ -169,14 +189,27 @@ func (ctrl *ImageProcessingController) loadImage(imageURL string) (image.Image,
return img, format, nil
}
// HTTP URL
resp, err := http.Get(imageURL)
// HTTP URL - use custom client and headers, some CDNs block default Go UA
client := &http.Client{Timeout: 20 * time.Second}
req, err := http.NewRequest("GET", imageURL, nil)
if err != nil {
return nil, "", fmt.Errorf("failed to create request: %w", err)
}
// Set a recognizable UA; align with other proxy endpoints
req.Header.Set("User-Agent", "fotbal-club/1.0")
req.Header.Set("Accept", "image/*")
// Some providers (e.g. Zonerama) may require a referer
if strings.Contains(strings.ToLower(imageURL), "zonerama.com") {
req.Header.Set("Referer", "https://zonerama.com/")
}
resp, err := client.Do(req)
if err != nil {
return nil, "", fmt.Errorf("failed to fetch image: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, "", fmt.Errorf("failed to fetch image: status %d", resp.StatusCode)
}
@@ -190,8 +223,11 @@ func (ctrl *ImageProcessingController) loadImage(imageURL string) (image.Image,
// saveProcessedImage saves the processed image and returns the path
func (ctrl *ImageProcessingController) saveProcessedImage(img image.Image, format string, quality int) (string, error) {
// Create uploads directory if it doesn't exist
uploadsDir := "./uploads"
// Create uploads directory if it doesn't exist (use configured UploadDir)
uploadsDir := config.AppConfig.UploadDir
if strings.TrimSpace(uploadsDir) == "" {
uploadsDir = "./uploads"
}
if err := os.MkdirAll(uploadsDir, 0755); err != nil {
return "", fmt.Errorf("failed to create uploads directory: %w", err)
}
@@ -297,8 +333,20 @@ func (ctrl *ImageProcessingController) CropAndUpload(c *gin.Context) {
return
}
scheme := "http"
if c.Request.TLS != nil || strings.EqualFold(c.Request.Header.Get("X-Forwarded-Proto"), "https") {
scheme = "https"
}
host := c.Request.Host
if xf := strings.TrimSpace(c.Request.Header.Get("X-Forwarded-Host")); xf != "" {
xfl := strings.ToLower(xf)
if !strings.Contains(xfl, ":3000") && !strings.HasPrefix(xfl, "localhost:") && !strings.HasPrefix(xfl, "127.0.0.1:") {
host = xf
}
}
absolute := scheme + "://" + host + outputPath
c.JSON(http.StatusOK, gin.H{
"url": outputPath,
"url": absolute,
})
}