1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2024-11-24 08:12:38 +02:00
imgproxy/imagedata/image_data.go
dcanob f37d027f4f
add config fallback ttl to avoid default ttl when fallback response (#818)
* add config fallback ttl to avoid default ttl when fallback response

* Update docs/configuration.md

Co-authored-by: Sergey Alexandrovich <DarthSim@users.noreply.github.com>

* move FallbackTTL to loadFallbackImage

* rewrite ifelse

* Update imagedata/image_data.go

don't use config.FallbackTTL on header to get TTL on the response

Co-authored-by: Sergey Alexandrovich <DarthSim@users.noreply.github.com>

* Update processing_handler.go

don't use config.FallbackTTL on header to get TTL on the response

Co-authored-by: Sergey Alexandrovich <DarthSim@users.noreply.github.com>

* rename FallbackTTL to FallbackImageTTL

* Update processing_handler.go

* Fix linter errors

Co-authored-by: Sergey Alexandrovich <DarthSim@users.noreply.github.com>
2022-03-31 13:36:13 +06:00

146 lines
3.0 KiB
Go

package imagedata
import (
"context"
"encoding/base64"
"fmt"
"net/http"
"net/http/cookiejar"
"os"
"strings"
"sync"
"github.com/imgproxy/imgproxy/v3/config"
"github.com/imgproxy/imgproxy/v3/ierrors"
"github.com/imgproxy/imgproxy/v3/imagetype"
)
var (
Watermark *ImageData
FallbackImage *ImageData
)
type ImageData struct {
Type imagetype.Type
Data []byte
Headers map[string]string
cancel context.CancelFunc
cancelOnce sync.Once
}
func (d *ImageData) Close() {
d.cancelOnce.Do(func() {
if d.cancel != nil {
d.cancel()
}
})
}
func (d *ImageData) SetCancel(cancel context.CancelFunc) {
d.cancel = cancel
}
func Init() error {
initRead()
if err := initDownloading(); err != nil {
return err
}
if err := loadWatermark(); err != nil {
return err
}
if err := loadFallbackImage(); err != nil {
return err
}
return nil
}
func loadWatermark() (err error) {
if len(config.WatermarkData) > 0 {
Watermark, err = FromBase64(config.WatermarkData, "watermark")
return
}
if len(config.WatermarkPath) > 0 {
Watermark, err = FromFile(config.WatermarkPath, "watermark")
return
}
if len(config.WatermarkURL) > 0 {
Watermark, err = Download(config.WatermarkURL, "watermark", nil, nil)
return
}
return nil
}
func loadFallbackImage() (err error) {
switch {
case len(config.FallbackImageData) > 0:
FallbackImage, err = FromBase64(config.FallbackImageData, "fallback image")
case len(config.FallbackImagePath) > 0:
FallbackImage, err = FromFile(config.FallbackImagePath, "fallback image")
case len(config.FallbackImageURL) > 0:
FallbackImage, err = Download(config.FallbackImageURL, "fallback image", nil, nil)
default:
FallbackImage, err = nil, nil
}
if FallbackImage != nil && err == nil && config.FallbackImageTTL > 0 {
if FallbackImage.Headers == nil {
FallbackImage.Headers = make(map[string]string)
}
FallbackImage.Headers["Fallback-Image"] = "1"
}
return err
}
func FromBase64(encoded, desc string) (*ImageData, error) {
dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encoded))
size := 4 * (len(encoded)/3 + 1)
imgdata, err := readAndCheckImage(dec, size)
if err != nil {
return nil, fmt.Errorf("Can't decode %s: %s", desc, err)
}
return imgdata, nil
}
func FromFile(path, desc string) (*ImageData, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("Can't read %s: %s", desc, err)
}
fi, err := f.Stat()
if err != nil {
return nil, fmt.Errorf("Can't read %s: %s", desc, err)
}
imgdata, err := readAndCheckImage(f, int(fi.Size()))
if err != nil {
return nil, fmt.Errorf("Can't read %s: %s", desc, err)
}
return imgdata, nil
}
func Download(imageURL, desc string, header http.Header, jar *cookiejar.Jar) (*ImageData, error) {
imgdata, err := download(imageURL, header, jar)
if err != nil {
if nmErr, ok := err.(*ErrorNotModified); ok {
nmErr.Message = fmt.Sprintf("Can't download %s: %s", desc, nmErr.Message)
return nil, nmErr
}
return nil, ierrors.WrapWithPrefix(err, 1, fmt.Sprintf("Can't download %s", desc))
}
return imgdata, nil
}