Golang Gin 框架: 从远程 URL 下载图片并上传到 OSS
以下是一个示例代码,使用gin框架获取远程网络图片url,下载到oss并校验大小和图片后缀名:
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
router := gin.Default()
router.POST("/upload/image", func(c *gin.Context) {
url := c.PostForm("url")
if url == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "missing url parameter",
})
return
}
resp, err := http.Get(url)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to get remote image",
})
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to get remote image",
})
return
}
contentLength := resp.ContentLength
contentType := resp.Header.Get("Content-Type")
if !strings.HasPrefix(contentType, "image/") {
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid image format",
})
return
}
fileName := filepath.Base(url)
extension := filepath.Ext(fileName)
if extension == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid file extension",
})
return
}
bucketName := "your-bucket-name"
accessKeyID := "your-access-key-id"
accessKeySecret := "your-access-key-secret"
endpoint := "your-oss-endpoint"
client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to connect to oss",
})
return
}
bucket, err := client.Bucket(bucketName)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to get bucket",
})
return
}
err = bucket.PutObject(fileName, resp.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to upload image to oss",
})
return
}
object, err := bucket.GetObject(fileName)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to get object from oss",
})
return
}
defer object.Close()
actualSize, err := object.Stat()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "failed to get object size",
})
return
}
if actualSize.Size() != contentLength {
c.JSON(http.StatusBadRequest, gin.H{
"error": "image size mismatch",
})
return
}
actualContentType := http.DetectContentType(actualSize.(*oss.ObjectProperties).ContentType())
if actualContentType != contentType {
c.JSON(http.StatusBadRequest, gin.H{
"error": "image content type mismatch",
})
return
}
c.JSON(http.StatusOK, gin.H{
"url": fmt.Sprintf("https://%s.%s/%s", bucketName, endpoint, fileName),
})
})
router.Run(":8080")
}
使用curl测试:
$ curl -X POST -F 'url=https://picsum.photos/400/300' http://localhost:8080/upload/image
返回结果:
{
"url": "https://your-bucket-name.your-oss-endpoint/300"
}
注意,上述代码中的 your-bucket-name,your-access-key-id,your-access-key-secret,your-oss-endpoint 需要替换为你自己的oss信息。
原文地址: https://www.cveoy.top/t/topic/lCsT 著作权归作者所有。请勿转载和采集!