1
0
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:
DarthSim 2021-11-11 15:30:16 +06:00
parent 475e67640b
commit d8bedfd930
4 changed files with 86 additions and 58 deletions

View File

@ -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.

View File

@ -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
View 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
}

View File

@ -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 {