mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-18 16:31:44 +02:00
Polish cookies passthrough
This commit is contained in:
parent
475e67640b
commit
d8bedfd930
@ -3,6 +3,7 @@
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Add `X-Origin-Width` and `X-Origin-Height` to debug headers.
|
||||
- Add `IMGPROXY_COOKIE_PASSTHROUGH` and `IMGPROXY_COOKIE_BASE_URL` configs.
|
||||
|
||||
### Change
|
||||
- `dpr` processing option doesn't enlarge image unless `enlarge` is true.
|
||||
|
@ -27,7 +27,6 @@ var (
|
||||
|
||||
TTL int
|
||||
CacheControlPassthrough bool
|
||||
CookiePassthrough bool
|
||||
SetCanonicalHeader bool
|
||||
|
||||
SoReuseport bool
|
||||
@ -74,7 +73,11 @@ var (
|
||||
IgnoreSslVerification bool
|
||||
DevelopmentErrorsMode bool
|
||||
|
||||
AllowedSources []*regexp.Regexp
|
||||
AllowedSources []*regexp.Regexp
|
||||
|
||||
CookiePassthrough bool
|
||||
CookieBaseURL string
|
||||
|
||||
LocalFileSystemRoot string
|
||||
S3Enabled bool
|
||||
S3Region string
|
||||
@ -88,8 +91,7 @@ var (
|
||||
|
||||
ETagEnabled bool
|
||||
|
||||
BaseURL string
|
||||
CookieBaseURL string
|
||||
BaseURL string
|
||||
|
||||
Presets []string
|
||||
OnlyPresets bool
|
||||
@ -157,7 +159,6 @@ func Reset() {
|
||||
|
||||
TTL = 3600
|
||||
CacheControlPassthrough = false
|
||||
CookiePassthrough = false
|
||||
SetCanonicalHeader = false
|
||||
|
||||
SoReuseport = false
|
||||
@ -205,6 +206,10 @@ func Reset() {
|
||||
DevelopmentErrorsMode = false
|
||||
|
||||
AllowedSources = make([]*regexp.Regexp, 0)
|
||||
|
||||
CookiePassthrough = false
|
||||
CookieBaseURL = ""
|
||||
|
||||
LocalFileSystemRoot = ""
|
||||
S3Enabled = false
|
||||
S3Region = ""
|
||||
@ -219,7 +224,6 @@ func Reset() {
|
||||
ETagEnabled = false
|
||||
|
||||
BaseURL = ""
|
||||
CookieBaseURL = ""
|
||||
|
||||
Presets = make([]string, 0)
|
||||
OnlyPresets = false
|
||||
@ -283,7 +287,6 @@ func Configure() error {
|
||||
|
||||
configurators.Int(&TTL, "IMGPROXY_TTL")
|
||||
configurators.Bool(&CacheControlPassthrough, "IMGPROXY_CACHE_CONTROL_PASSTHROUGH")
|
||||
configurators.Bool(&CookiePassthrough, "IMGPROXY_COOKIE_PASSTHROUGH")
|
||||
configurators.Bool(&SetCanonicalHeader, "IMGPROXY_SET_CANONICAL_HEADER")
|
||||
|
||||
configurators.Bool(&SoReuseport, "IMGPROXY_SO_REUSEPORT")
|
||||
@ -348,6 +351,9 @@ func Configure() error {
|
||||
configurators.Bool(&IgnoreSslVerification, "IMGPROXY_IGNORE_SSL_VERIFICATION")
|
||||
configurators.Bool(&DevelopmentErrorsMode, "IMGPROXY_DEVELOPMENT_ERRORS_MODE")
|
||||
|
||||
configurators.Bool(&CookiePassthrough, "IMGPROXY_COOKIE_PASSTHROUGH")
|
||||
configurators.String(&CookieBaseURL, "IMGPROXY_COOKIE_BASE_URL")
|
||||
|
||||
configurators.String(&LocalFileSystemRoot, "IMGPROXY_LOCAL_FILESYSTEM_ROOT")
|
||||
|
||||
configurators.Bool(&S3Enabled, "IMGPROXY_USE_S3")
|
||||
@ -365,7 +371,6 @@ func Configure() error {
|
||||
configurators.Bool(&ETagEnabled, "IMGPROXY_USE_ETAG")
|
||||
|
||||
configurators.String(&BaseURL, "IMGPROXY_BASE_URL")
|
||||
configurators.String(&CookieBaseURL, "IMGPROXY_COOKIE_BASE_URL")
|
||||
|
||||
configurators.StringSlice(&Presets, "IMGPROXY_PRESETS")
|
||||
if err := configurators.StringSliceFile(&Presets, *presetsPath); err != nil {
|
||||
|
61
cookies/cookies.go
Normal file
61
cookies/cookies.go
Normal file
@ -0,0 +1,61 @@
|
||||
package cookies
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
"github.com/imgproxy/imgproxy/v3/config"
|
||||
)
|
||||
|
||||
func JarFromRequest(r *http.Request) (*cookiejar.Jar, error) {
|
||||
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
return jar, nil
|
||||
}
|
||||
|
||||
var cookieBase *url.URL
|
||||
|
||||
if len(config.CookieBaseURL) > 0 {
|
||||
if cookieBase, err = url.Parse(config.CookieBaseURL); err != nil {
|
||||
return nil, fmt.Errorf("can't parse cookie base URL: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if cookieBase == nil {
|
||||
scheme := r.Header.Get("X-Forwarded-Proto")
|
||||
if len(scheme) == 0 {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
host := r.Header.Get("X-Forwarded-Host")
|
||||
if len(host) == 0 {
|
||||
host = r.Header.Get("Host")
|
||||
}
|
||||
|
||||
if len(host) == 0 {
|
||||
return jar, nil
|
||||
}
|
||||
|
||||
port := r.Header.Get("X-Forwarded-Port")
|
||||
if len(port) > 0 {
|
||||
host = host + ":" + port
|
||||
}
|
||||
|
||||
cookieBase = &url.URL{
|
||||
Scheme: scheme,
|
||||
Host: host,
|
||||
}
|
||||
}
|
||||
|
||||
jar.SetCookies(cookieBase, r.Cookies())
|
||||
|
||||
return jar, nil
|
||||
}
|
@ -3,10 +3,8 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -14,6 +12,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/imgproxy/imgproxy/v3/config"
|
||||
"github.com/imgproxy/imgproxy/v3/cookies"
|
||||
"github.com/imgproxy/imgproxy/v3/errorreport"
|
||||
"github.com/imgproxy/imgproxy/v3/etag"
|
||||
"github.com/imgproxy/imgproxy/v3/ierrors"
|
||||
@ -138,48 +137,6 @@ func respondWithNotModified(reqID string, r *http.Request, rw http.ResponseWrite
|
||||
)
|
||||
}
|
||||
|
||||
func cookieJarFromRequest(r *http.Request) (*cookiejar.Jar, error) {
|
||||
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.CookiePassthrough && r != nil {
|
||||
cookieBase := config.CookieBaseURL
|
||||
|
||||
if len(cookieBase) == 0 {
|
||||
scheme := r.Header.Get("X-Forwarded-Proto")
|
||||
if len(scheme) == 0 {
|
||||
scheme = "http"
|
||||
}
|
||||
host := r.Header.Get("X-Forwarded-Host")
|
||||
if len(host) == 0 {
|
||||
host = r.Header.Get("Host")
|
||||
}
|
||||
if len(host) == 0 {
|
||||
cookieBase = ""
|
||||
} else {
|
||||
port := r.Header.Get("X-Forwarded-Port")
|
||||
if len(port) > 0 {
|
||||
host = host + ":" + port
|
||||
}
|
||||
cookieBase = scheme + "://" + host + "/"
|
||||
}
|
||||
}
|
||||
|
||||
if len(cookieBase) > 0 {
|
||||
cookieBaseURL, err := url.Parse(cookieBase)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jar.SetCookies(cookieBaseURL, r.Cookies())
|
||||
}
|
||||
}
|
||||
return jar, nil
|
||||
}
|
||||
|
||||
func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, timeoutCancel := context.WithTimeout(r.Context(), time.Duration(config.WriteTimeout)*time.Second)
|
||||
defer timeoutCancel()
|
||||
@ -220,11 +177,6 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
panic(ierrors.New(404, fmt.Sprintf("Source URL is not allowed: %s", imageURL), "Invalid source"))
|
||||
}
|
||||
|
||||
jar, err := cookieJarFromRequest(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// SVG is a special case. Though saving to svg is not supported, SVG->SVG is.
|
||||
if !vips.SupportsSave(po.Format) && po.Format != imagetype.Unknown && po.Format != imagetype.SVG {
|
||||
panic(ierrors.New(
|
||||
@ -263,7 +215,16 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
originData, err := func() (*imagedata.ImageData, error) {
|
||||
defer metrics.StartDownloadingSegment(ctx)()
|
||||
return imagedata.Download(imageURL, "source image", imgRequestHeader, jar)
|
||||
|
||||
var cookieJar *cookiejar.Jar
|
||||
|
||||
if config.CookiePassthrough {
|
||||
if cookieJar, err = cookies.JarFromRequest(r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return imagedata.Download(imageURL, "source image", imgRequestHeader, cookieJar)
|
||||
}()
|
||||
|
||||
if err == nil {
|
||||
|
Loading…
Reference in New Issue
Block a user