1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-09-16 09:36:18 +02:00

IMGPROXY_CACHE_CONTROL_PASSTHROUGH config

This commit is contained in:
DarthSim
2020-02-04 15:23:41 +06:00
parent 45306adc23
commit 372faba5c1
6 changed files with 46 additions and 7 deletions

View File

@@ -3,6 +3,7 @@
## [Unreleased]
### Added
- `IMGPROXY_NETWORK` config. Allows to bind on Unix socket.
- `IMGPROXY_CACHE_CONTROL_PASSTHROUGH` config.
### Fixed
- Fix detection of SVG starting with a comment.

View File

@@ -153,8 +153,11 @@ type config struct {
DownloadTimeout int
Concurrency int
MaxClients int
TTL int
SoReuseport bool
TTL int
CacheControlPassthrough bool
SoReuseport bool
MaxSrcDimension int
MaxSrcResolution int
@@ -284,6 +287,7 @@ func configure() {
intEnvConfig(&conf.MaxClients, "IMGPROXY_MAX_CLIENTS")
intEnvConfig(&conf.TTL, "IMGPROXY_TTL")
boolEnvConfig(&conf.CacheControlPassthrough, "IMGPROXY_CACHE_CONTROL_PASSTHROUGH")
boolEnvConfig(&conf.SoReuseport, "IMGPROXY_SO_REUSEPORT")

View File

@@ -35,6 +35,7 @@ echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
* `IMGPROXY_CONCURRENCY`: the maximum number of image requests to be processed simultaneously. Default: number of CPU cores times two;
* `IMGPROXY_MAX_CLIENTS`: the maximum number of simultaneous active connections. Default: `IMGPROXY_CONCURRENCY * 10`;
* `IMGPROXY_TTL`: duration (in seconds) sent in `Expires` and `Cache-Control: max-age` HTTP headers. Default: `3600` (1 hour);
* `IMGPROXY_CACHE_CONTROL_PASSTHROUGH`: when `true` and source image response contains `Expires` or `Cache-Control` headers, reuse those headers. Default: false;
* `IMGPROXY_SO_REUSEPORT`: when `true`, enables `SO_REUSEPORT` socket option (currently on linux and darwin only);
* `IMGPROXY_USER_AGENT`: User-Agent header that will be sent with source image request. Default: `imgproxy/%current_version`;
* `IMGPROXY_USE_ETAG`: when `true`, enables using [ETag](https://en.wikipedia.org/wiki/HTTP_ETag) HTTP header for HTTP cache control. Default: false;

View File

@@ -14,8 +14,11 @@ import (
)
var (
downloadClient *http.Client
imageDataCtxKey = ctxKey("imageData")
downloadClient *http.Client
imageDataCtxKey = ctxKey("imageData")
cacheControlHeaderCtxKey = ctxKey("cacheControlHeader")
expiresHeaderCtxKey = ctxKey("expiresHeader")
errSourceDimensionsTooBig = newError(422, "Source image dimensions are too big", "Invalid source image")
errSourceResolutionTooBig = newError(422, "Source image resolution is too big", "Invalid source image")
@@ -196,6 +199,8 @@ func downloadImage(ctx context.Context) (context.Context, context.CancelFunc, er
}
ctx = context.WithValue(ctx, imageDataCtxKey, imgdata)
ctx = context.WithValue(ctx, cacheControlHeaderCtxKey, res.Header.Get("Cache-Control"))
ctx = context.WithValue(ctx, expiresHeaderCtxKey, res.Header.Get("Expires"))
return ctx, imgdata.Close, err
}
@@ -203,3 +208,11 @@ func downloadImage(ctx context.Context) (context.Context, context.CancelFunc, er
func getImageData(ctx context.Context) *imageData {
return ctx.Value(imageDataCtxKey).(*imageData)
}
func getCacheControlHeader(ctx context.Context) string {
return ctx.Value(cacheControlHeaderCtxKey).(string)
}
func getExpiresHeader(ctx context.Context) string {
return ctx.Value(expiresHeaderCtxKey).(string)
}

View File

@@ -47,13 +47,16 @@ func (t gcsTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, err
}
header := make(http.Header)
header.Set("Cache-Control", reader.Attrs.CacheControl)
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Header: make(http.Header),
Header: header,
ContentLength: reader.Attrs.Size,
Body: reader,
Close: true,

View File

@@ -53,11 +53,28 @@ func respondWithImage(ctx context.Context, reqID string, r *http.Request, rw htt
contentDisposition = po.Format.ContentDispositionFromURL(getImageURL(ctx))
}
rw.Header().Set("Expires", time.Now().Add(time.Second*time.Duration(conf.TTL)).Format(http.TimeFormat))
rw.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d, public", conf.TTL))
rw.Header().Set("Content-Type", po.Format.Mime())
rw.Header().Set("Content-Disposition", contentDisposition)
var cacheControl, expires string
if conf.CacheControlPassthrough {
cacheControl = getCacheControlHeader(ctx)
expires = getExpiresHeader(ctx)
}
if len(cacheControl) == 0 && len(expires) == 0 {
cacheControl = fmt.Sprintf("max-age=%d, public", conf.TTL)
expires = time.Now().Add(time.Second * time.Duration(conf.TTL)).Format(http.TimeFormat)
}
if len(cacheControl) > 0 {
rw.Header().Set("Cache-Control", cacheControl)
}
if len(expires) > 0 {
rw.Header().Set("Expires", expires)
}
if len(headerVaryValue) > 0 {
rw.Header().Set("Vary", headerVaryValue)
}