瀏覽代碼

Polish cookies passthrough

DarthSim 3 年之前
父節點
當前提交
d8bedfd930
共有 4 個文件被更改,包括 86 次插入58 次删除
  1. 1 0
      CHANGELOG.md
  2. 13 8
      config/config.go
  3. 61 0
      cookies/cookies.go
  4. 11 50
      processing_handler.go

+ 1 - 0
CHANGELOG.md

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

+ 13 - 8
config/config.go

@@ -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 - 0
cookies/cookies.go

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

+ 11 - 50
processing_handler.go

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