1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2024-11-24 08:12:38 +02:00

Implement fallback images in a similar fashion to watermarks. (#374)

* 220. Implement fallback images in a similar fashion to watermarks.

* 220. Fix error formatting.

* 220. Fixes based on @darthsim's feedback.
This commit is contained in:
Ewan Higgs 2020-04-08 16:32:45 +02:00 committed by GitHub
parent cf6f481d83
commit 21b990d895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 11 deletions

View File

@ -224,6 +224,10 @@ type config struct {
WatermarkURL string
WatermarkOpacity float64
FallbackImageData string
FallbackImagePath string
FallbackImageURL string
NewRelicAppName string
NewRelicKey string
@ -377,6 +381,10 @@ func configure() error {
strEnvConfig(&conf.WatermarkURL, "IMGPROXY_WATERMARK_URL")
floatEnvConfig(&conf.WatermarkOpacity, "IMGPROXY_WATERMARK_OPACITY")
strEnvConfig(&conf.FallbackImageData, "IMGPROXY_FALLBACK_IMAGE_DATA")
strEnvConfig(&conf.FallbackImagePath, "IMGPROXY_FALLBACK_IMAGE_PATH")
strEnvConfig(&conf.FallbackImageURL, "IMGPROXY_FALLBACK_IMAGE_URL")
strEnvConfig(&conf.NewRelicAppName, "IMGPROXY_NEW_RELIC_APP_NAME")
strEnvConfig(&conf.NewRelicKey, "IMGPROXY_NEW_RELIC_KEY")

View File

@ -9,35 +9,51 @@ import (
func getWatermarkData() (*imageData, error) {
if len(conf.WatermarkData) > 0 {
return base64WatermarkData(conf.WatermarkData)
return base64ImageData(conf.WatermarkData)
}
if len(conf.WatermarkPath) > 0 {
return fileWatermarkData(conf.WatermarkPath)
return fileImageData(conf.WatermarkPath)
}
if len(conf.WatermarkURL) > 0 {
return remoteWatermarkData(conf.WatermarkURL)
return remoteImageData(conf.WatermarkURL)
}
return nil, nil
}
func base64WatermarkData(encoded string) (*imageData, error) {
func getFallbackImageData() (*imageData, error) {
if len(conf.FallbackImageData) > 0 {
return base64ImageData(conf.FallbackImageData)
}
if len(conf.FallbackImagePath) > 0 {
return fileImageData(conf.FallbackImagePath)
}
if len(conf.FallbackImageURL) > 0 {
return remoteImageData(conf.FallbackImageURL)
}
return nil, nil
}
func base64ImageData(encoded string) (*imageData, error) {
data, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
return nil, fmt.Errorf("Can't decode watermark data: %s", err)
return nil, fmt.Errorf("Can't decode image data: %s", err)
}
imgtype, err := checkTypeAndDimensions(bytes.NewReader(data))
if err != nil {
return nil, fmt.Errorf("Can't decode watermark: %s", err)
return nil, fmt.Errorf("Can't decode image: %s", err)
}
return &imageData{Data: data, Type: imgtype}, nil
}
func fileWatermarkData(path string) (*imageData, error) {
func fileImageData(path string) (*imageData, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("Can't read watermark: %s", err)
@ -56,18 +72,18 @@ func fileWatermarkData(path string) (*imageData, error) {
return imgdata, err
}
func remoteWatermarkData(imageURL string) (*imageData, error) {
func remoteImageData(imageURL string) (*imageData, error) {
res, err := requestImage(imageURL)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return nil, fmt.Errorf("Can't download watermark: %s", err)
return nil, fmt.Errorf("Can't download image: %s", err)
}
imgdata, err := readAndCheckImage(res.Body, int(res.ContentLength))
if err != nil {
return nil, fmt.Errorf("Can't download watermark: %s", err)
return nil, fmt.Errorf("Can't download image: %s", err)
}
return imgdata, err

View File

@ -16,6 +16,7 @@ var (
processingSem chan struct{}
headerVaryValue string
fallback *imageData
)
func initProcessingHandler() error {
@ -45,6 +46,10 @@ func initProcessingHandler() error {
headerVaryValue = strings.Join(vary, ", ")
if err := loadFallback(); err != nil {
return err
}
return nil
}
@ -153,7 +158,12 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
if prometheusEnabled {
incrementPrometheusErrorsTotal("download")
}
panic(err)
if fallback != nil {
logError("Could not load image. Using fallback image: %s", err.Error())
ctx = context.WithValue(ctx, imageDataCtxKey, fallback)
} else {
panic(err)
}
}
checkTimeout(ctx)
@ -186,3 +196,11 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
respondWithImage(ctx, reqID, r, rw, imageData)
}
func loadFallback() (err error) {
fallback, err = getFallbackImageData()
if err != nil {
logError("Could not load fallback data. Fallback images will not be available: %s", err.Error())
}
return err
}