Read every setting through viper and rename the settings (closes #211)
check / check (push) Failing after 3m27s
check / check (push) Failing after 3m27s
Every setting of discriminator and rproxy is read through viper, in place of the os.LookupEnv function Main passed down. NewViper turns AutomaticEnv and AllowEmptyEnv on, so a setting that is set but empty reads as set. A setting may also be given as a file, the _FILE form, which rproxy's settings now have too; rproxy still writes nothing to disk. The settings are renamed. Discriminator's take the prefix SWW_WAF_, rproxy's take SWW_RPROXY_, and the shared SWW_COMMAND keeps SWW_. The Core Rule Set's settings take SWW_WAF_CORE_RULE_SET_ rather than SWW_WAF_WAF_. Every place a name appeared changed: the code, the viper keys, tests, documents, examples, the README's settings table and the image files. Model: deepseek-v4-pro
This commit is contained in:
1 parent
beb503b233
commit
68da92f414
89 files changed
+2027
-1916
No files matched your search
+37
-48
@@ -8,38 +8,39 @@ import (
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// RProxy is the settings of `sww rproxy`. A size or time limit of zero
|
||||
// is off.
|
||||
type RProxy struct {
|
||||
// ListenAddr is where rproxy listens (SWRP_LISTEN_ADDR).
|
||||
// ListenAddr is where rproxy listens (SWW_RPROXY_LISTEN_ADDR).
|
||||
ListenAddr string
|
||||
// UpstreamURL is the app (SWRP_UPSTREAM_URL).
|
||||
// UpstreamURL is the app (SWW_RPROXY_UPSTREAM_URL).
|
||||
UpstreamURL *url.URL
|
||||
// TrustedProxies are the netblocks whose X-Forwarded-For is believed
|
||||
// (SWRP_TRUSTED_PROXIES).
|
||||
// (SWW_RPROXY_TRUSTED_PROXIES).
|
||||
TrustedProxies []netip.Prefix
|
||||
// WAFBackend is discriminator's URL (SWRP_WAF_BACKEND).
|
||||
// WAFBackend is discriminator's URL (SWW_RPROXY_WAF_BACKEND).
|
||||
WAFBackend *url.URL
|
||||
// Timeout is how long rproxy waits for discriminator's answer to a question,
|
||||
// and to a report (SWRP_TIMEOUT_MS). It cannot be off.
|
||||
// and to a report (SWW_RPROXY_TIMEOUT_MS). It cannot be off.
|
||||
Timeout time.Duration
|
||||
// DefaultDisposition is what is done with a request when discriminator cannot be
|
||||
// connected to, does not answer at all, or does not answer within Timeout:
|
||||
// allow or deny (SWRP_DEFAULT_DISPOSITION).
|
||||
// allow or deny (SWW_RPROXY_DEFAULT_DISPOSITION).
|
||||
DefaultDisposition string
|
||||
// MaxRequestSize is the largest request body (SWRP_MAX_REQUEST_SIZE), and
|
||||
// MaxResponseSize the largest response body (SWRP_MAX_RESPONSE_SIZE).
|
||||
// MaxRequestSize is the largest request body (SWW_RPROXY_MAX_REQUEST_SIZE), and
|
||||
// MaxResponseSize the largest response body (SWW_RPROXY_MAX_RESPONSE_SIZE).
|
||||
MaxRequestSize int64
|
||||
MaxResponseSize int64
|
||||
// MaxRequestTime bounds sending the whole request: the visitor's request
|
||||
// line and headers, and then, from their end, its body on its way to the
|
||||
// app (SWRP_MAX_REQUEST_TIME_MS). MaxResponseTime bounds the answer, from
|
||||
// app (SWW_RPROXY_MAX_REQUEST_TIME_MS). MaxResponseTime bounds the answer, from
|
||||
// the end of the request to its last byte reaching the visitor
|
||||
// (SWRP_MAX_RESPONSE_TIME_MS).
|
||||
// (SWW_RPROXY_MAX_RESPONSE_TIME_MS).
|
||||
MaxRequestTime time.Duration
|
||||
MaxResponseTime time.Duration
|
||||
|
||||
@@ -58,24 +59,26 @@ var (
|
||||
"is not a whole number of milliseconds above zero, such as 60000, or off")
|
||||
)
|
||||
|
||||
// RProxyFromEnvironment reads rproxy's settings with lookupEnv, normally
|
||||
// os.LookupEnv. A setting that is not set takes its default, and
|
||||
// SWRP_WAF_BACKEND, which has none, must be set. A setting that is set but
|
||||
// invalid is an error that names it. Since rproxy never touches disk, its
|
||||
// settings have no _FILE form.
|
||||
func RProxyFromEnvironment(lookupEnv func(string) (string, bool)) (*RProxy, error) {
|
||||
env := &environment{lookupEnv: withoutFileForms(lookupEnv)}
|
||||
// RProxyFromEnvironment reads rproxy's settings through v, normally the viper
|
||||
// NewViper returns, bound to the process's environment. A setting that is not
|
||||
// set takes its default, and SWW_RPROXY_WAF_BACKEND, which has none, must be
|
||||
// set. A setting may instead be given as a file: the variable named by the
|
||||
// setting's name with _FILE added names the file, which is read now. A setting
|
||||
// that is set but invalid is an error that names it.
|
||||
func RProxyFromEnvironment(v *viper.Viper) (*RProxy, error) {
|
||||
env := &environment{v: v, readFiles: true}
|
||||
cfg := &RProxy{
|
||||
ListenAddr: env.address("SWRP_LISTEN_ADDR"),
|
||||
UpstreamURL: env.appURL("SWRP_UPSTREAM_URL", defaultUpstreamURL),
|
||||
TrustedProxies: env.netblocks("SWRP_TRUSTED_PROXIES", privateRanges),
|
||||
WAFBackend: env.wafBackend("SWRP_WAF_BACKEND"),
|
||||
Timeout: env.milliseconds("SWRP_TIMEOUT_MS", "2000"),
|
||||
DefaultDisposition: env.disposition("SWRP_DEFAULT_DISPOSITION", "allow"),
|
||||
MaxRequestSize: env.size("SWRP_MAX_REQUEST_SIZE", "100M"),
|
||||
MaxResponseSize: env.size("SWRP_MAX_RESPONSE_SIZE", "1G"),
|
||||
MaxRequestTime: env.millisecondsOrOff("SWRP_MAX_REQUEST_TIME_MS", "60000"),
|
||||
MaxResponseTime: env.millisecondsOrOff("SWRP_MAX_RESPONSE_TIME_MS", "1800000"),
|
||||
ListenAddr: env.address("SWW_RPROXY_LISTEN_ADDR"),
|
||||
UpstreamURL: env.appURL("SWW_RPROXY_UPSTREAM_URL", defaultUpstreamURL),
|
||||
TrustedProxies: env.netblocks("SWW_RPROXY_TRUSTED_PROXIES", privateRanges),
|
||||
WAFBackend: env.wafBackend("SWW_RPROXY_WAF_BACKEND"),
|
||||
Timeout: env.milliseconds("SWW_RPROXY_TIMEOUT_MS", "2000"),
|
||||
DefaultDisposition: env.disposition("SWW_RPROXY_DEFAULT_DISPOSITION", "allow"),
|
||||
MaxRequestSize: env.size("SWW_RPROXY_MAX_REQUEST_SIZE", "100M"),
|
||||
MaxResponseSize: env.size("SWW_RPROXY_MAX_RESPONSE_SIZE", "1G"),
|
||||
MaxRequestTime: env.millisecondsOrOff("SWW_RPROXY_MAX_REQUEST_TIME_MS", "60000"),
|
||||
MaxResponseTime: env.millisecondsOrOff(
|
||||
"SWW_RPROXY_MAX_RESPONSE_TIME_MS", "1800000"),
|
||||
}
|
||||
|
||||
if env.err != nil {
|
||||
@@ -87,15 +90,15 @@ func RProxyFromEnvironment(lookupEnv func(string) (string, bool)) (*RProxy, erro
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// RProxyListenAddrAndUpstreamURL reads only SWRP_LISTEN_ADDR and
|
||||
// SWRP_UPSTREAM_URL. The health check in rproxy's container needs no other
|
||||
// RProxyListenAddrAndUpstreamURL reads only SWW_RPROXY_LISTEN_ADDR and
|
||||
// SWW_RPROXY_UPSTREAM_URL. The health check in rproxy's container needs no other
|
||||
// setting, so it reads no other.
|
||||
func RProxyListenAddrAndUpstreamURL(
|
||||
lookupEnv func(string) (string, bool),
|
||||
v *viper.Viper,
|
||||
) (string, *url.URL, error) {
|
||||
env := &environment{lookupEnv: withoutFileForms(lookupEnv)}
|
||||
listenAddr := env.address("SWRP_LISTEN_ADDR")
|
||||
upstreamURL := env.appURL("SWRP_UPSTREAM_URL", defaultUpstreamURL)
|
||||
env := &environment{v: v, readFiles: true}
|
||||
listenAddr := env.address("SWW_RPROXY_LISTEN_ADDR")
|
||||
upstreamURL := env.appURL("SWW_RPROXY_UPSTREAM_URL", defaultUpstreamURL)
|
||||
|
||||
if env.err != nil {
|
||||
return "", nil, env.err
|
||||
@@ -104,20 +107,6 @@ func RProxyListenAddrAndUpstreamURL(
|
||||
return listenAddr, upstreamURL, nil
|
||||
}
|
||||
|
||||
// withoutFileForms returns lookupEnv finding no setting named with _FILE, since
|
||||
// rproxy never touches disk.
|
||||
func withoutFileForms(
|
||||
lookupEnv func(string) (string, bool),
|
||||
) func(string) (string, bool) {
|
||||
return func(name string) (string, bool) {
|
||||
if strings.HasSuffix(name, "_FILE") {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return lookupEnv(name)
|
||||
}
|
||||
}
|
||||
|
||||
// LogValue makes an RProxy log as each setting's name with the value it was
|
||||
// given, or its default.
|
||||
func (c *RProxy) LogValue() slog.Value {
|
||||
|
||||
Reference in new issue
Block a user