Config: Add option to set a proxy for outgoing connections #3132
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
41774fcec9
commit
6dd55170fe
@ -12,10 +12,11 @@ import (
|
||||
|
||||
// ShowFlagsCommand configures the command name, flags, and action.
|
||||
var ShowFlagsCommand = cli.Command{
|
||||
Name: "flags",
|
||||
Usage: "Displays supported environment variables and CLI flags",
|
||||
Flags: report.CliFlags,
|
||||
Action: showFlagsAction,
|
||||
Name: "flags",
|
||||
Aliases: []string{"env", "vars"},
|
||||
Usage: "Displays supported environment variables and CLI flags",
|
||||
Flags: report.CliFlags,
|
||||
Action: showFlagsAction,
|
||||
}
|
||||
|
||||
var faceFlagsInfo = `!!! info ""
|
||||
@ -23,7 +24,7 @@ var faceFlagsInfo = `!!! info ""
|
||||
|
||||
We recommend that only advanced users change these parameters:`
|
||||
|
||||
// showFlagsAction shows environment variable command-line parameter names.
|
||||
// showFlagsAction displays supported environment variables and CLI flags.
|
||||
func showFlagsAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
conf.SetLogLevel(logrus.FatalLevel)
|
||||
@ -53,6 +54,7 @@ func showFlagsAction(ctx *cli.Context) error {
|
||||
{Start: "PHOTOPRISM_READONLY", Title: "Feature Flags"},
|
||||
{Start: "PHOTOPRISM_DEFAULT_LOCALE", Title: "Customization"},
|
||||
{Start: "PHOTOPRISM_CDN_URL", Title: "Site Information"},
|
||||
{Start: "PHOTOPRISM_HTTPS_PROXY", Title: "HTTPS Proxy"},
|
||||
{Start: "PHOTOPRISM_TRUSTED_PROXY", Title: "Web Server"},
|
||||
{Start: "PHOTOPRISM_DATABASE_DRIVER", Title: "Database Connection"},
|
||||
{Start: "PHOTOPRISM_DARKTABLE_BIN", Title: "File Converters"},
|
||||
|
@ -18,7 +18,7 @@ var ShowOptionsCommand = cli.Command{
|
||||
Action: showOptionsAction,
|
||||
}
|
||||
|
||||
// showOptionsAction shows supported YAML config file options.
|
||||
// showOptionsAction displays supported YAML config options and CLI flag.
|
||||
func showOptionsAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
conf.SetLogLevel(logrus.TraceLevel)
|
||||
|
@ -1,9 +1,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -232,6 +234,15 @@ func (c *Config) Init() error {
|
||||
log.Warnf("config: the wakeup interval is %s, but must be 1h or less for face recognition to work", c.WakeupInterval().String())
|
||||
}
|
||||
|
||||
// Set HTTPS proxy for outgoing connections.
|
||||
if httpsProxy := c.HttpsProxy(); httpsProxy != "" {
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: c.HttpsProxyInsecure(),
|
||||
}
|
||||
|
||||
_ = os.Setenv("HTTPS_PROXY", httpsProxy)
|
||||
}
|
||||
|
||||
// Set HTTP user agent.
|
||||
places.UserAgent = c.UserAgent()
|
||||
|
||||
@ -720,20 +731,20 @@ func (c *Config) ResolutionLimit() int {
|
||||
return result
|
||||
}
|
||||
|
||||
// UpdateHub renews backend api credentials for maps & places without a token.
|
||||
// UpdateHub renews backend api credentials for maps and places without a token.
|
||||
func (c *Config) UpdateHub() {
|
||||
_ = c.ResyncHub("")
|
||||
}
|
||||
|
||||
// ResyncHub renews backend api credentials for maps & places with an optional token.
|
||||
// ResyncHub renews backend api credentials for maps and places with an optional token.
|
||||
func (c *Config) ResyncHub(token string) error {
|
||||
if err := c.hub.ReSync(token); err != nil {
|
||||
log.Debugf("config: %s (refresh backend api tokens)", err)
|
||||
log.Debugf("config: %s, see https://docs.photoprism.app/getting-started/troubleshooting/firewall/", err)
|
||||
if token != "" {
|
||||
return i18n.Error(i18n.ErrAccountConnect)
|
||||
}
|
||||
} else if err = c.hub.Save(); err != nil {
|
||||
log.Debugf("config: %s (save backend api tokens)", err)
|
||||
log.Debugf("config: %s while saving api keys for maps and places", err)
|
||||
} else {
|
||||
c.hub.Propagate()
|
||||
}
|
||||
@ -751,10 +762,10 @@ func (c *Config) initHub() {
|
||||
|
||||
if err := c.hub.Load(); err == nil {
|
||||
// Do nothing.
|
||||
} else if err := c.hub.Update(); err != nil {
|
||||
log.Debugf("config: %s (init backend api tokens)", err)
|
||||
} else if err := c.hub.Save(); err != nil {
|
||||
log.Debugf("config: %s (save backend api tokens)", err)
|
||||
} else if err = c.hub.Update(); err != nil {
|
||||
log.Debugf("config: %s, see https://docs.photoprism.app/getting-started/troubleshooting/firewall/", err)
|
||||
} else if err = c.hub.Save(); err != nil {
|
||||
log.Debugf("config: %s while saving api keys for maps and places", err)
|
||||
}
|
||||
|
||||
c.hub.Propagate()
|
||||
|
25
internal/config/config_proxy.go
Normal file
25
internal/config/config_proxy.go
Normal file
@ -0,0 +1,25 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// HttpsProxy returns the HTTPS proxy to use for outgoing connections.
|
||||
func (c *Config) HttpsProxy() string {
|
||||
if c.options.HttpsProxy != "" {
|
||||
return c.options.HttpsProxy
|
||||
} else if httpsProxy := os.Getenv("HTTPS_PROXY"); httpsProxy != "" {
|
||||
return httpsProxy
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// HttpsProxyInsecure checks if invalid TLS certificates should be ignored when using the configured HTTPS proxy.
|
||||
func (c *Config) HttpsProxyInsecure() bool {
|
||||
if c.HttpsProxy() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return c.options.HttpsProxyInsecure
|
||||
}
|
36
internal/config/config_proxy_test.go
Normal file
36
internal/config/config_proxy_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfig_HttpsProxy(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, "", c.HttpsProxy())
|
||||
|
||||
_ = os.Setenv("HTTPS_PROXY", "https://foo.bar:8081")
|
||||
|
||||
assert.Equal(t, "https://foo.bar:8081", c.HttpsProxy())
|
||||
|
||||
_ = os.Setenv("HTTPS_PROXY", "")
|
||||
|
||||
assert.Equal(t, "", c.HttpsProxy())
|
||||
}
|
||||
|
||||
func TestConfig_HttpsProxyInsecure(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.False(t, c.HttpsProxyInsecure())
|
||||
|
||||
_ = os.Setenv("HTTPS_PROXY", "https://foo.bar:8081")
|
||||
|
||||
assert.False(t, c.HttpsProxyInsecure())
|
||||
|
||||
_ = os.Setenv("HTTPS_PROXY", "")
|
||||
|
||||
assert.False(t, c.HttpsProxyInsecure())
|
||||
}
|
@ -407,6 +407,16 @@ var Flags = CliFlags{
|
||||
Usage: "sharing preview image `URL`",
|
||||
EnvVar: "PHOTOPRISM_SITE_PREVIEW",
|
||||
}, Tags: []string{EnvSponsor}}, {
|
||||
Flag: cli.StringFlag{
|
||||
Name: "https-proxy",
|
||||
Usage: "trusted HTTPS proxy to use for outgoing connections",
|
||||
EnvVar: "PHOTOPRISM_HTTPS_PROXY",
|
||||
}}, {
|
||||
Flag: cli.BoolFlag{
|
||||
Name: "https-proxy-insecure",
|
||||
Usage: "ignore invalid certificates when using an HTTPS proxy",
|
||||
EnvVar: "PHOTOPRISM_HTTPS_PROXY_INSECURE",
|
||||
}}, {
|
||||
Flag: cli.StringSliceFlag{
|
||||
Name: "trusted-proxy",
|
||||
Usage: "`CIDR` range from which reverse proxy headers can be trusted",
|
||||
|
@ -94,6 +94,8 @@ type Options struct {
|
||||
SiteCaption string `yaml:"SiteCaption" json:"SiteCaption" flag:"site-caption"`
|
||||
SiteDescription string `yaml:"SiteDescription" json:"SiteDescription" flag:"site-description"`
|
||||
SitePreview string `yaml:"SitePreview" json:"SitePreview" flag:"site-preview"`
|
||||
HttpsProxy string `yaml:"HttpsProxy" json:"HttpsProxy" flag:"https-proxy"`
|
||||
HttpsProxyInsecure bool `yaml:"HttpsProxyInsecure" json:"HttpsProxyInsecure" flag:"https-proxy-insecure"`
|
||||
TrustedProxies []string `yaml:"TrustedProxies" json:"-" flag:"trusted-proxy"`
|
||||
ProxyProtoHeaders []string `yaml:"ProxyProtoHeaders" json:"-" flag:"proxy-proto-header"`
|
||||
ProxyProtoHttps []string `yaml:"ProxyProtoHttps" json:"-" flag:"proxy-proto-https"`
|
||||
|
@ -107,6 +107,8 @@ func (c *Config) Report() (rows [][]string, cols []string) {
|
||||
{"app-icon", c.AppIcon()},
|
||||
{"app-name", c.AppName()},
|
||||
{"app-mode", c.AppMode()},
|
||||
{"legal-info", c.LegalInfo()},
|
||||
{"legal-url", c.LegalUrl()},
|
||||
{"wallpaper-uri", c.WallpaperUri()},
|
||||
|
||||
// Site Infos.
|
||||
@ -120,16 +122,16 @@ func (c *Config) Report() (rows [][]string, cols []string) {
|
||||
{"site-description", c.SiteDescription()},
|
||||
{"site-preview", c.SitePreview()},
|
||||
|
||||
// Legal info.
|
||||
{"legal-info", c.LegalInfo()},
|
||||
{"legal-url", c.LegalUrl()},
|
||||
|
||||
// URIs.
|
||||
{"content-uri", c.ContentUri()},
|
||||
{"static-uri", c.StaticUri()},
|
||||
{"api-uri", c.ApiUri()},
|
||||
{"base-uri", c.BaseUri("/")},
|
||||
|
||||
// HTTPS Proxy.
|
||||
{"https-proxy", c.HttpsProxy()},
|
||||
{"https-proxy-insecure", fmt.Sprintf("%t", c.HttpsProxyInsecure())},
|
||||
|
||||
// HTTP(S) Proxy.
|
||||
{"trusted-proxy", c.TrustedProxy()},
|
||||
{"proxy-proto-header", strings.Join(c.ProxyProtoHeader(), ", ")},
|
||||
|
@ -208,9 +208,9 @@ func (c *Config) ReSync(token string) (err error) {
|
||||
if c.Key != "" {
|
||||
url = fmt.Sprintf(ServiceURL+"/%s", c.Key)
|
||||
method = http.MethodPut
|
||||
log.Debugf("config: requesting updated api key for maps and places")
|
||||
log.Tracef("config: requesting updated keys for maps and places")
|
||||
} else {
|
||||
log.Debugf("config: requesting new api key for maps and places")
|
||||
log.Tracef("config: requesting new api keys for maps and places")
|
||||
}
|
||||
|
||||
// Create JSON request.
|
||||
|
Loading…
x
Reference in New Issue
Block a user