فهرست منبع

Allow setting a custom image proxy URL

Nicole 3 سال پیش
والد
کامیت
bbc087d2ad
5فایلهای تغییر یافته به همراه57 افزوده شده و 1 حذف شده
  1. 9 0
      config/options.go
  2. 2 0
      config/parser.go
  3. 5 0
      miniflux.1
  4. 24 0
      proxy/image_proxy_test.go
  5. 17 1
      proxy/proxy.go

+ 9 - 0
config/options.go

@@ -46,6 +46,7 @@ const (
 	defaultCleanupArchiveBatchSize            = 10000
 	defaultCleanupRemoveSessionsDays          = 30
 	defaultProxyImages                        = "http-only"
+	defaultProxyImageUrl                      = ""
 	defaultFetchYouTubeWatchTime              = false
 	defaultCreateAdmin                        = false
 	defaultAdminUsername                      = ""
@@ -116,6 +117,7 @@ type Options struct {
 	adminUsername                      string
 	adminPassword                      string
 	proxyImages                        string
+	proxyImageUrl                      string
 	fetchYouTubeWatchTime              bool
 	oauth2UserCreationAllowed          bool
 	oauth2ClientID                     string
@@ -175,6 +177,7 @@ func NewOptions() *Options {
 		workerPoolSize:                     defaultWorkerPoolSize,
 		createAdmin:                        defaultCreateAdmin,
 		proxyImages:                        defaultProxyImages,
+		proxyImageUrl:                      defaultProxyImageUrl,
 		fetchYouTubeWatchTime:              defaultFetchYouTubeWatchTime,
 		oauth2UserCreationAllowed:          defaultOAuth2UserCreation,
 		oauth2ClientID:                     defaultOAuth2ClientID,
@@ -410,6 +413,11 @@ func (o *Options) ProxyImages() string {
 	return o.proxyImages
 }
 
+// ProxyImageUrl returns a string of a URL to use to proxy image requests
+func (o *Options) ProxyImageUrl() string {
+	return o.proxyImageUrl
+}
+
 // HasHTTPService returns true if the HTTP service is enabled.
 func (o *Options) HasHTTPService() bool {
 	return o.httpService
@@ -543,6 +551,7 @@ func (o *Options) SortedOptions(redactSecret bool) []*Option {
 		"POLLING_PARSING_ERROR_LIMIT":            o.pollingParsingErrorLimit,
 		"POLLING_SCHEDULER":                      o.pollingScheduler,
 		"PROXY_IMAGES":                           o.proxyImages,
+		"PROXY_IMAGE_URL":                        o.proxyImageUrl,
 		"ROOT_URL":                               o.rootURL,
 		"RUN_MIGRATIONS":                         o.runMigrations,
 		"SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL": o.schedulerEntryFrequencyMaxInterval,

+ 2 - 0
config/parser.go

@@ -139,6 +139,8 @@ func (p *Parser) parseLines(lines []string) (err error) {
 			p.opts.pollingParsingErrorLimit = parseInt(value, defaultPollingParsingErrorLimit)
 		case "PROXY_IMAGES":
 			p.opts.proxyImages = parseString(value, defaultProxyImages)
+		case "PROXY_IMAGE_URL":
+			p.opts.proxyImageUrl = parseString(value, defaultProxyImageUrl)
 		case "CREATE_ADMIN":
 			p.opts.createAdmin = parseBool(value, defaultCreateAdmin)
 		case "ADMIN_USERNAME":

+ 5 - 0
miniflux.1

@@ -370,6 +370,11 @@ Avoids mixed content warnings for external images: http-only, all, or none\&.
 .br
 Default is http-only\&.
 .TP
+.B PROXY_IMAGE_URL
+Sets a server to proxy images through\&.
+.br
+Default is empty, miniflux does the proxying\&.
+.TP
 .B HTTP_CLIENT_TIMEOUT
 Time limit in seconds before the HTTP client cancel the request\&.
 .br

+ 24 - 0
proxy/image_proxy_test.go

@@ -151,6 +151,30 @@ func TestProxyFilterWithHttpsAlways(t *testing.T) {
 	}
 }
 
+func TestProxyFilterWithHttpsAlwaysAndCustomProxyServer(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("PROXY_IMAGES", "all")
+	os.Setenv("PROXY_IMAGE_URL", "https://proxy-example/proxy")
+
+	var err error
+	parser := config.NewParser()
+	config.Opts, err = parser.ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
+	r := mux.NewRouter()
+	r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy")
+
+	input := `<p><img src="https://website/folder/image.png" alt="Test"/></p>`
+	output := ImageProxyRewriter(r, input)
+	expected := `<p><img src="https://proxy-example/proxy/aHR0cHM6Ly93ZWJzaXRlL2ZvbGRlci9pbWFnZS5wbmc=" alt="Test"/></p>`
+
+	if expected != output {
+		t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected)
+	}
+}
+
 func TestProxyFilterWithHttpInvalid(t *testing.T) {
 	os.Clearenv()
 	os.Setenv("PROXY_IMAGES", "invalid")

+ 17 - 1
proxy/proxy.go

@@ -6,16 +6,32 @@ package proxy // import "miniflux.app/proxy"
 
 import (
 	"encoding/base64"
+	"net/url"
+	"path"
 
 	"miniflux.app/http/route"
 
 	"github.com/gorilla/mux"
+
+	"miniflux.app/config"
 )
 
 // ProxifyURL generates an URL for a proxified resource.
 func ProxifyURL(router *mux.Router, link string) string {
 	if link != "" {
-		return route.Path(router, "proxy", "encodedURL", base64.URLEncoding.EncodeToString([]byte(link)))
+		proxyImageUrl := config.Opts.ProxyImageUrl()
+
+		if proxyImageUrl == "" {
+			return route.Path(router, "proxy", "encodedURL", base64.URLEncoding.EncodeToString([]byte(link)))
+		}
+
+		proxyUrl, err := url.Parse(proxyImageUrl)
+		if err != nil {
+			return ""
+		}
+
+		proxyUrl.Path = path.Join(proxyUrl.Path, base64.URLEncoding.EncodeToString([]byte(link)))
+		return proxyUrl.String()
 	}
 	return ""
 }