refactor(configuration): umask from query (#5416)
Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>pull/5419/head
parent
3a752f5ac9
commit
6c472d8627
|
@ -22,7 +22,6 @@ aliases:
|
||||||
```yaml
|
```yaml
|
||||||
server:
|
server:
|
||||||
address: 'tcp://:9091'
|
address: 'tcp://:9091'
|
||||||
umask: 0022
|
|
||||||
path: ''
|
path: ''
|
||||||
disable_healthcheck: false
|
disable_healthcheck: false
|
||||||
tls:
|
tls:
|
||||||
|
@ -80,20 +79,6 @@ server:
|
||||||
address: unix:///var/run/authelia.sock
|
address: unix:///var/run/authelia.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
### umask
|
|
||||||
|
|
||||||
{{< confkey type="int" required="no" >}}
|
|
||||||
|
|
||||||
If set temporarily changes the umask during the creation of the unix domain socket if configured as such in the
|
|
||||||
[address](#address). Typically this should be set before the process is actually running and users should not use this
|
|
||||||
option, however it's recognized in various specific scenarios this may not be completely adequate.
|
|
||||||
|
|
||||||
One such example is when you want the proxy to have permission to the socket but not the files, in which case running a
|
|
||||||
umask of `0077` by default is good, and running a umask of `0027` so that the group Authelia is running as has
|
|
||||||
permission to the socket.
|
|
||||||
|
|
||||||
This value should typically be prefixed with a `0` to ensure the relevant parsers handle it correctly.
|
|
||||||
|
|
||||||
### path
|
### path
|
||||||
|
|
||||||
{{< confkey type="string " required="no" >}}
|
{{< confkey type="string " required="no" >}}
|
||||||
|
|
|
@ -108,10 +108,22 @@ The following format represents the unix domain socket format. It's valid for bo
|
||||||
instances. Refer to the individual documentation for an option for clarity. In this format as per the notation there
|
instances. Refer to the individual documentation for an option for clarity. In this format as per the notation there
|
||||||
are no optional portions.
|
are no optional portions.
|
||||||
|
|
||||||
|
The Unix Domain Socket format also accepts a query string. The following query parameters control certain behaviour of
|
||||||
|
this address type.
|
||||||
|
|
||||||
|
| Parameter | Listeners | Connectors | Purpose |
|
||||||
|
|:---------:|:---------:|:----------:|:------------------------------------------------------------------------------------------------------------------------------------:|
|
||||||
|
| `umask` | Yes | No | Sets the umask prior to creating the socket and restores it after creating it. The value must be an octal number with 3 or 4 digits. |
|
||||||
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
unix://<path>
|
unix://<path>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
unix://<path>?umask=0022
|
||||||
|
```
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
Various examples for these formats.
|
Various examples for these formats.
|
||||||
|
|
|
@ -23,7 +23,6 @@ telemetry:
|
||||||
metrics:
|
metrics:
|
||||||
enabled: false
|
enabled: false
|
||||||
address: 'tcp://:9959'
|
address: 'tcp://:9959'
|
||||||
umask: 0022
|
|
||||||
buffers:
|
buffers:
|
||||||
read: 4096
|
read: 4096
|
||||||
write: 4096
|
write: 4096
|
||||||
|
@ -53,20 +52,6 @@ see the [documentation](../prologue/common.md#address) on this format for more i
|
||||||
Configures the listener address for the [Prometheus] Metrics Exporter HTTP Server. The address itself is a listener and
|
Configures the listener address for the [Prometheus] Metrics Exporter HTTP Server. The address itself is a listener and
|
||||||
the scheme must either be the `unix` scheme or one of the `tcp` schemes.
|
the scheme must either be the `unix` scheme or one of the `tcp` schemes.
|
||||||
|
|
||||||
### umask
|
|
||||||
|
|
||||||
{{< confkey type="int" required="no" >}}
|
|
||||||
|
|
||||||
If set temporarily changes the umask during the creation of the unix domain socket if configured as such in the
|
|
||||||
[address](#address). Typically this should be set before the process is actually running and users should not use this
|
|
||||||
option, however it's recognized in various specific scenarios this may not be completely adequate.
|
|
||||||
|
|
||||||
One such example is when you want the proxy to have permission to the socket but not the files, in which case running a
|
|
||||||
umask of `0077` by default is good, and running a umask of `0027` so that the group Authelia is running as has
|
|
||||||
permission to the socket.
|
|
||||||
|
|
||||||
This value should typically be prefixed with a `0` to ensure the relevant parsers handle it correctly.
|
|
||||||
|
|
||||||
### buffers
|
### buffers
|
||||||
|
|
||||||
*__Reference Note:__ This configuration option uses the
|
*__Reference Note:__ This configuration option uses the
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -103,9 +103,17 @@ const (
|
||||||
TOTPSecretSizeMinimum = 20
|
TOTPSecretSizeMinimum = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
// regexpHasScheme checks if a string has a scheme. Valid characters for schemes include alphanumeric, hyphen,
|
var (
|
||||||
// period, and plus characters.
|
// regexpHasScheme checks if a string has a scheme. Valid characters for schemes include alphanumeric, hyphen,
|
||||||
var regexpHasScheme = regexp.MustCompile(`^[-+.a-zA-Z\d]*(://|:$)`)
|
// period, and plus characters.
|
||||||
|
regexpHasScheme = regexp.MustCompile(`^[-+.a-zA-Z\d]*(://|:$)`)
|
||||||
|
|
||||||
|
regexpIsUmask = regexp.MustCompile(`^[0-7]{3,4}$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
addressQueryParamUmask = "umask"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
blockCERTIFICATE = "CERTIFICATE"
|
blockCERTIFICATE = "CERTIFICATE"
|
||||||
|
|
|
@ -239,7 +239,6 @@ var Keys = []string{
|
||||||
"notifier.smtp.port",
|
"notifier.smtp.port",
|
||||||
"notifier.template_path",
|
"notifier.template_path",
|
||||||
"server.address",
|
"server.address",
|
||||||
"server.umask",
|
|
||||||
"server.path",
|
"server.path",
|
||||||
"server.asset_path",
|
"server.asset_path",
|
||||||
"server.disable_healthcheck",
|
"server.disable_healthcheck",
|
||||||
|
@ -262,7 +261,6 @@ var Keys = []string{
|
||||||
"server.port",
|
"server.port",
|
||||||
"telemetry.metrics.enabled",
|
"telemetry.metrics.enabled",
|
||||||
"telemetry.metrics.address",
|
"telemetry.metrics.address",
|
||||||
"telemetry.metrics.umask",
|
|
||||||
"telemetry.metrics.buffers.read",
|
"telemetry.metrics.buffers.read",
|
||||||
"telemetry.metrics.buffers.write",
|
"telemetry.metrics.buffers.write",
|
||||||
"telemetry.metrics.timeouts.read",
|
"telemetry.metrics.timeouts.read",
|
||||||
|
|
|
@ -44,7 +44,7 @@ type NotifierConfiguration struct {
|
||||||
|
|
||||||
// DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier.
|
// DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier.
|
||||||
var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
|
var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
|
||||||
Address: &AddressSMTP{Address{true, false, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}},
|
Address: &AddressSMTP{Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}},
|
||||||
Timeout: time.Second * 5,
|
Timeout: time.Second * 5,
|
||||||
Subject: "[Authelia] {title}",
|
Subject: "[Authelia] {title}",
|
||||||
Identifier: "localhost",
|
Identifier: "localhost",
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
// ServerConfiguration represents the configuration of the http server.
|
// ServerConfiguration represents the configuration of the http server.
|
||||||
type ServerConfiguration struct {
|
type ServerConfiguration struct {
|
||||||
Address *AddressTCP `koanf:"address"`
|
Address *AddressTCP `koanf:"address"`
|
||||||
UMask *int `koanf:"umask"`
|
|
||||||
|
|
||||||
Path string `koanf:"path"`
|
Path string `koanf:"path"`
|
||||||
AssetPath string `koanf:"asset_path"`
|
AssetPath string `koanf:"asset_path"`
|
||||||
DisableHealthcheck bool `koanf:"disable_healthcheck"`
|
DisableHealthcheck bool `koanf:"disable_healthcheck"`
|
||||||
|
@ -62,7 +60,7 @@ type ServerHeaders struct {
|
||||||
|
|
||||||
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
|
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
|
||||||
var DefaultServerConfiguration = ServerConfiguration{
|
var DefaultServerConfiguration = ServerConfiguration{
|
||||||
Address: &AddressTCP{Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091"}}},
|
Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091"}}},
|
||||||
Buffers: ServerBuffers{
|
Buffers: ServerBuffers{
|
||||||
Read: 4096,
|
Read: 4096,
|
||||||
Write: 4096,
|
Write: 4096,
|
||||||
|
|
|
@ -75,7 +75,7 @@ var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{
|
||||||
// DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration.
|
// DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration.
|
||||||
var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{
|
var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{
|
||||||
SQLStorageConfiguration: SQLStorageConfiguration{
|
SQLStorageConfiguration: SQLStorageConfiguration{
|
||||||
Address: &AddressTCP{Address{true, false, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}},
|
Address: &AddressTCP{Address{true, false, -1, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}},
|
||||||
},
|
},
|
||||||
Schema: "public",
|
Schema: "public",
|
||||||
TLS: &TLSConfig{
|
TLS: &TLSConfig{
|
||||||
|
|
|
@ -14,8 +14,6 @@ type TelemetryConfig struct {
|
||||||
type TelemetryMetricsConfig struct {
|
type TelemetryMetricsConfig struct {
|
||||||
Enabled bool `koanf:"enabled"`
|
Enabled bool `koanf:"enabled"`
|
||||||
Address *AddressTCP `koanf:"address"`
|
Address *AddressTCP `koanf:"address"`
|
||||||
UMask *int `koanf:"umask"`
|
|
||||||
|
|
||||||
Buffers ServerBuffers `koanf:"buffers"`
|
Buffers ServerBuffers `koanf:"buffers"`
|
||||||
Timeouts ServerTimeouts `koanf:"timeouts"`
|
Timeouts ServerTimeouts `koanf:"timeouts"`
|
||||||
}
|
}
|
||||||
|
@ -23,7 +21,7 @@ type TelemetryMetricsConfig struct {
|
||||||
// DefaultTelemetryConfig is the default telemetry configuration.
|
// DefaultTelemetryConfig is the default telemetry configuration.
|
||||||
var DefaultTelemetryConfig = TelemetryConfig{
|
var DefaultTelemetryConfig = TelemetryConfig{
|
||||||
Metrics: TelemetryMetricsConfig{
|
Metrics: TelemetryMetricsConfig{
|
||||||
Address: &AddressTCP{Address{true, false, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959"}}},
|
Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959"}}},
|
||||||
Buffers: ServerBuffers{
|
Buffers: ServerBuffers{
|
||||||
Read: 4096,
|
Read: 4096,
|
||||||
Write: 4096,
|
Write: 4096,
|
||||||
|
|
|
@ -21,7 +21,7 @@ func NewAddress(value string) (address *Address, err error) {
|
||||||
// else without a scheme is the schemeDefault scheme.
|
// else without a scheme is the schemeDefault scheme.
|
||||||
func NewAddressDefault(value, schemeDefault, schemeDefaultPath string) (address *Address, err error) {
|
func NewAddressDefault(value, schemeDefault, schemeDefaultPath string) (address *Address, err error) {
|
||||||
if len(value) == 0 {
|
if len(value) == 0 {
|
||||||
return &Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}}, nil
|
return &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var u *url.URL
|
var u *url.URL
|
||||||
|
@ -71,12 +71,17 @@ func NewAddressFromNetworkValuesDefault(value string, port int, schemeDefault, s
|
||||||
|
|
||||||
// NewAddressUnix returns an *Address from a path value.
|
// NewAddressUnix returns an *Address from a path value.
|
||||||
func NewAddressUnix(path string) Address {
|
func NewAddressUnix(path string) Address {
|
||||||
return Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: path}}
|
return Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: path}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressFromNetworkValues returns an *Address from network values.
|
// NewAddressFromNetworkValues returns an *Address from network values.
|
||||||
func NewAddressFromNetworkValues(network, host string, port int) Address {
|
func NewAddressFromNetworkValues(network, host string, port int) Address {
|
||||||
return Address{true, false, port, &url.URL{Scheme: network, Host: fmt.Sprintf("%s:%d", host, port)}}
|
return NewAddressFromNetworkPathValues(network, host, port, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAddressFromNetworkPathValues returns an *Address from network values and a path.
|
||||||
|
func NewAddressFromNetworkPathValues(network, host string, port int, path string) Address {
|
||||||
|
return Address{true, false, -1, port, &url.URL{Scheme: network, Host: fmt.Sprintf("%s:%d", host, port), Path: path}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTPAddress returns an *AddressSMTP from SMTP values.
|
// NewSMTPAddress returns an *AddressSMTP from SMTP values.
|
||||||
|
@ -103,13 +108,14 @@ func NewSMTPAddress(scheme, host string, port int) *AddressSMTP {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &AddressSMTP{Address: Address{true, false, port, &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", host, port)}}}
|
return &AddressSMTP{Address: Address{true, false, -1, port, &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", host, port)}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressFromURL returns an *Address and error depending on the ability to parse the *url.URL as an Address.
|
// NewAddressFromURL returns an *Address and error depending on the ability to parse the *url.URL as an Address.
|
||||||
func NewAddressFromURL(u *url.URL) (addr *Address, err error) {
|
func NewAddressFromURL(u *url.URL) (addr *Address, err error) {
|
||||||
addr = &Address{
|
addr = &Address{
|
||||||
url: u,
|
url: u,
|
||||||
|
umask: -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = addr.validate(); err != nil {
|
if err = addr.validate(); err != nil {
|
||||||
|
@ -143,6 +149,7 @@ type AddressSMTP struct {
|
||||||
type Address struct {
|
type Address struct {
|
||||||
valid bool
|
valid bool
|
||||||
socket bool
|
socket bool
|
||||||
|
umask int
|
||||||
port int
|
port int
|
||||||
|
|
||||||
url *url.URL
|
url *url.URL
|
||||||
|
@ -153,6 +160,15 @@ func (a *Address) Valid() bool {
|
||||||
return a.valid
|
return a.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Umask returns the formatted umask or an empty string.
|
||||||
|
func (a *Address) Umask() string {
|
||||||
|
if a.umask == -1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%04s", strconv.FormatInt(int64(a.umask), 8))
|
||||||
|
}
|
||||||
|
|
||||||
// IsUnixDomainSocket returns true if the address has been determined to be a Unix Domain Socket.
|
// IsUnixDomainSocket returns true if the address has been determined to be a Unix Domain Socket.
|
||||||
func (a *Address) IsUnixDomainSocket() bool {
|
func (a *Address) IsUnixDomainSocket() bool {
|
||||||
return a.socket
|
return a.socket
|
||||||
|
@ -257,16 +273,6 @@ func (a *Address) String() string {
|
||||||
return a.url.String()
|
return a.url.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network returns the Scheme() if it's appropriate for the net packages network arguments otherwise it returns tcp.
|
|
||||||
func (a *Address) Network() string {
|
|
||||||
switch scheme := a.Scheme(); scheme {
|
|
||||||
case AddressSchemeTCP, AddressSchemeTCP4, AddressSchemeTCP6, AddressSchemeUDP, AddressSchemeUDP4, AddressSchemeUDP6, AddressSchemeUnix:
|
|
||||||
return scheme
|
|
||||||
default:
|
|
||||||
return AddressSchemeTCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scheme returns the *url.URL Scheme field.
|
// Scheme returns the *url.URL Scheme field.
|
||||||
func (a *Address) Scheme() string {
|
func (a *Address) Scheme() string {
|
||||||
if !a.valid || a.url == nil {
|
if !a.valid || a.url == nil {
|
||||||
|
@ -276,6 +282,15 @@ func (a *Address) Scheme() string {
|
||||||
return a.url.Scheme
|
return a.url.Scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Host returns the *url.URL Host field.
|
||||||
|
func (a *Address) Host() string {
|
||||||
|
if !a.valid || a.url == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.url.Host
|
||||||
|
}
|
||||||
|
|
||||||
// Hostname returns the output of the *url.URL Hostname func.
|
// Hostname returns the output of the *url.URL Hostname func.
|
||||||
func (a *Address) Hostname() string {
|
func (a *Address) Hostname() string {
|
||||||
if !a.valid || a.url == nil {
|
if !a.valid || a.url == nil {
|
||||||
|
@ -285,19 +300,6 @@ func (a *Address) Hostname() string {
|
||||||
return a.url.Hostname()
|
return a.url.Hostname()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketHostname returns the correct hostname for a socket connection.
|
|
||||||
func (a *Address) SocketHostname() string {
|
|
||||||
if !a.valid || a.url == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.socket {
|
|
||||||
return a.url.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.url.Hostname()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHostname sets the hostname preserving the port.
|
// SetHostname sets the hostname preserving the port.
|
||||||
func (a *Address) SetHostname(hostname string) {
|
func (a *Address) SetHostname(hostname string) {
|
||||||
if !a.valid || a.url == nil {
|
if !a.valid || a.url == nil {
|
||||||
|
@ -325,13 +327,36 @@ func (a *Address) SetPort(port int) {
|
||||||
a.setport(port)
|
a.setport(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host returns the *url.URL Host field.
|
// Path returns the path.
|
||||||
func (a *Address) Host() string {
|
func (a *Address) Path() string {
|
||||||
if !a.valid || a.url == nil {
|
if !a.valid || a.url == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.url.Host
|
return a.url.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketHostname returns the correct hostname for a socket connection.
|
||||||
|
func (a *Address) SocketHostname() string {
|
||||||
|
if !a.valid || a.url == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.socket {
|
||||||
|
return a.url.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.url.Hostname()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network returns the Scheme() if it's appropriate for the net packages network arguments otherwise it returns tcp.
|
||||||
|
func (a *Address) Network() string {
|
||||||
|
switch scheme := a.Scheme(); scheme {
|
||||||
|
case AddressSchemeTCP, AddressSchemeTCP4, AddressSchemeTCP6, AddressSchemeUDP, AddressSchemeUDP4, AddressSchemeUDP6, AddressSchemeUnix:
|
||||||
|
return scheme
|
||||||
|
default:
|
||||||
|
return AddressSchemeTCP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkAddress returns a string representation of the Address with just the host and port.
|
// NetworkAddress returns a string representation of the Address with just the host and port.
|
||||||
|
@ -348,46 +373,33 @@ func (a *Address) NetworkAddress() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listener creates and returns a net.Listener.
|
// Listener creates and returns a net.Listener.
|
||||||
func (a *Address) Listener() (net.Listener, error) {
|
func (a *Address) Listener() (ln net.Listener, err error) {
|
||||||
return a.listener()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial creates and returns a dialed net.Conn.
|
|
||||||
func (a *Address) Dial() (net.Conn, error) {
|
|
||||||
if a.url == nil {
|
if a.url == nil {
|
||||||
return nil, fmt.Errorf("address url is nil")
|
return nil, fmt.Errorf("address url is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
return net.Dial(a.Network(), a.NetworkAddress())
|
if a.socket && a.umask != -1 {
|
||||||
}
|
umask := syscall.Umask(a.umask)
|
||||||
|
|
||||||
// ListenerWithUMask creates and returns a net.Listener with a temporary UMask if the scheme is `unix`.
|
|
||||||
func (a *Address) ListenerWithUMask(umask int) (ln net.Listener, err error) {
|
|
||||||
if !a.socket {
|
|
||||||
return a.listener()
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.url == nil {
|
|
||||||
return nil, fmt.Errorf("address url is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
umask = syscall.Umask(umask)
|
|
||||||
|
|
||||||
ln, err = net.Listen(a.Network(), a.NetworkAddress())
|
ln, err = net.Listen(a.Network(), a.NetworkAddress())
|
||||||
|
|
||||||
_ = syscall.Umask(umask)
|
_ = syscall.Umask(umask)
|
||||||
|
|
||||||
return ln, err
|
return ln, err
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Address) listener() (net.Listener, error) {
|
|
||||||
if a.url == nil {
|
|
||||||
return nil, fmt.Errorf("address url is nil")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return net.Listen(a.Network(), a.NetworkAddress())
|
return net.Listen(a.Network(), a.NetworkAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dial creates and returns a dialed net.Conn.
|
||||||
|
func (a *Address) Dial() (net.Conn, error) {
|
||||||
|
if !a.valid || a.url == nil {
|
||||||
|
return nil, fmt.Errorf("address url is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
return net.Dial(a.Network(), a.NetworkAddress())
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Address) setport(port int) {
|
func (a *Address) setport(port int) {
|
||||||
a.port = port
|
a.port = port
|
||||||
a.url.Host = net.JoinHostPort(a.url.Hostname(), strconv.Itoa(port))
|
a.url.Host = net.JoinHostPort(a.url.Hostname(), strconv.Itoa(port))
|
||||||
|
@ -399,8 +411,8 @@ func (a *Address) validate() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case a.url.RawQuery != "":
|
case a.url.RawQuery != "" && a.url.Scheme != AddressSchemeUnix:
|
||||||
return fmt.Errorf("error validating the address: the url '%s' appears to have a query but this is not valid for addresses", a.url.String())
|
return fmt.Errorf("error validating the address: the url '%s' appears to have a query but this is not valid for addresses with the '%s' scheme", a.url.String(), a.url.Scheme)
|
||||||
case a.url.RawFragment != "", a.url.Fragment != "":
|
case a.url.RawFragment != "", a.url.Fragment != "":
|
||||||
return fmt.Errorf("error validating the address: the url '%s' appears to have a fragment but this is not valid for addresses", a.url.String())
|
return fmt.Errorf("error validating the address: the url '%s' appears to have a fragment but this is not valid for addresses", a.url.String())
|
||||||
case a.url.User != nil:
|
case a.url.User != nil:
|
||||||
|
@ -469,6 +481,8 @@ func (a *Address) validateTCPUDP() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Address) validateUnixSocket() (err error) {
|
func (a *Address) validateUnixSocket() (err error) {
|
||||||
|
umask := -1
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case a.url.Path == "" && a.url.Scheme != AddressSchemeLDAPI:
|
case a.url.Path == "" && a.url.Scheme != AddressSchemeLDAPI:
|
||||||
return fmt.Errorf("error validating the unix socket address: could not determine path from '%s'", a.url.String())
|
return fmt.Errorf("error validating the unix socket address: could not determine path from '%s'", a.url.String())
|
||||||
|
@ -476,7 +490,22 @@ func (a *Address) validateUnixSocket() (err error) {
|
||||||
return fmt.Errorf("error validating the unix socket address: the url '%s' appears to have a host but this is not valid for unix sockets: this may occur if you omit the leading forward slash from the socket path", a.url.String())
|
return fmt.Errorf("error validating the unix socket address: the url '%s' appears to have a host but this is not valid for unix sockets: this may occur if you omit the leading forward slash from the socket path", a.url.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.url.Query().Has(addressQueryParamUmask) {
|
||||||
|
v := a.url.Query().Get(addressQueryParamUmask)
|
||||||
|
|
||||||
|
if !regexpIsUmask.MatchString(v) {
|
||||||
|
return fmt.Errorf("error validating the unix socket address: could not parse address '%s': the address has a umask value of '%s' which does not appear to be a valid octal string", a.url.String(), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
var p int64
|
||||||
|
|
||||||
|
p, _ = strconv.ParseInt(v, 8, 0)
|
||||||
|
|
||||||
|
umask = int(p)
|
||||||
|
}
|
||||||
|
|
||||||
a.socket = true
|
a.socket = true
|
||||||
|
a.umask = umask
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -20,7 +21,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseBasicAddress",
|
"ShouldParseBasicAddress",
|
||||||
"tcp://0.0.0.0:9091",
|
"tcp://0.0.0.0:9091",
|
||||||
&Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
|
&Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
|
||||||
"0.0.0.0:9091",
|
"0.0.0.0:9091",
|
||||||
"tcp://0.0.0.0:9091",
|
"tcp://0.0.0.0:9091",
|
||||||
"",
|
"",
|
||||||
|
@ -28,7 +29,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseEmptyAddress",
|
"ShouldParseEmptyAddress",
|
||||||
"",
|
"",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}},
|
||||||
":0",
|
":0",
|
||||||
"tcp://:0",
|
"tcp://:0",
|
||||||
"",
|
"",
|
||||||
|
@ -36,7 +37,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseAddressMissingScheme",
|
"ShouldParseAddressMissingScheme",
|
||||||
"0.0.0.0:9091",
|
"0.0.0.0:9091",
|
||||||
&Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
|
&Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
|
||||||
"0.0.0.0:9091",
|
"0.0.0.0:9091",
|
||||||
"tcp://0.0.0.0:9091",
|
"tcp://0.0.0.0:9091",
|
||||||
"",
|
"",
|
||||||
|
@ -44,7 +45,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseUnixAddressMissingScheme",
|
"ShouldParseUnixAddressMissingScheme",
|
||||||
"/var/run/example.sock",
|
"/var/run/example.sock",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/var/run/example.sock"}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/var/run/example.sock"}},
|
||||||
"/var/run/example.sock",
|
"/var/run/example.sock",
|
||||||
"unix:///var/run/example.sock",
|
"unix:///var/run/example.sock",
|
||||||
"",
|
"",
|
||||||
|
@ -52,15 +53,23 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseAddressMissingPort",
|
"ShouldParseAddressMissingPort",
|
||||||
"tcp://0.0.0.0",
|
"tcp://0.0.0.0",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:0"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:0"}},
|
||||||
"0.0.0.0:0",
|
"0.0.0.0:0",
|
||||||
"tcp://0.0.0.0:0",
|
"tcp://0.0.0.0:0",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ShouldNotParseAddressWithQuery",
|
||||||
|
"tcp://0.0.0.0?umask=0022",
|
||||||
|
nil,
|
||||||
|
"0.0.0.0:0",
|
||||||
|
"tcp://0.0.0.0:0",
|
||||||
|
"error validating the address: the url 'tcp://0.0.0.0?umask=0022' appears to have a query but this is not valid for addresses with the 'tcp' scheme",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ShouldParseUnixSocket",
|
"ShouldParseUnixSocket",
|
||||||
"unix:///path/to/a/socket.sock",
|
"unix:///path/to/a/socket.sock",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock"}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock"}},
|
||||||
"/path/to/a/socket.sock",
|
"/path/to/a/socket.sock",
|
||||||
"unix:///path/to/a/socket.sock",
|
"unix:///path/to/a/socket.sock",
|
||||||
"",
|
"",
|
||||||
|
@ -82,12 +91,12 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
"error validating the unix socket address: could not determine path from 'unix://nopath.com'",
|
"error validating the unix socket address: could not determine path from 'unix://nopath.com'",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldNotParseUnixSocketWithQuery",
|
"ShouldParseUnixSocketWithQuery",
|
||||||
"unix:///path/to/a/socket.sock?q=yes",
|
"unix:///path/to/a/socket.sock?umask=0022",
|
||||||
nil,
|
&Address{true, true, 18, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock", RawQuery: "umask=0022"}},
|
||||||
|
"/path/to/a/socket.sock",
|
||||||
|
"unix:///path/to/a/socket.sock?umask=0022",
|
||||||
"",
|
"",
|
||||||
"",
|
|
||||||
"error validating the address: the url 'unix:///path/to/a/socket.sock?q=yes' appears to have a query but this is not valid for addresses",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldNotParseUnixSocketWithFragment",
|
"ShouldNotParseUnixSocketWithFragment",
|
||||||
|
@ -108,7 +117,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldParseUnknownScheme",
|
"ShouldParseUnknownScheme",
|
||||||
"a://0.0.0.0",
|
"a://0.0.0.0",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: "a", Host: "0.0.0.0"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: "a", Host: "0.0.0.0"}},
|
||||||
"0.0.0.0",
|
"0.0.0.0",
|
||||||
"a://0.0.0.0",
|
"a://0.0.0.0",
|
||||||
"",
|
"",
|
||||||
|
@ -140,7 +149,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldSetDefaultPortLDAP",
|
"ShouldSetDefaultPortLDAP",
|
||||||
"ldap://127.0.0.1",
|
"ldap://127.0.0.1",
|
||||||
&Address{true, false, 389, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:389"}},
|
&Address{true, false, -1, 389, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:389"}},
|
||||||
"127.0.0.1:389",
|
"127.0.0.1:389",
|
||||||
"ldap://127.0.0.1:389",
|
"ldap://127.0.0.1:389",
|
||||||
"",
|
"",
|
||||||
|
@ -148,7 +157,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldSetDefaultPortLDAPS",
|
"ShouldSetDefaultPortLDAPS",
|
||||||
"ldaps://127.0.0.1",
|
"ldaps://127.0.0.1",
|
||||||
&Address{true, false, 636, &url.URL{Scheme: AddressSchemeLDAPS, Host: "127.0.0.1:636"}},
|
&Address{true, false, -1, 636, &url.URL{Scheme: AddressSchemeLDAPS, Host: "127.0.0.1:636"}},
|
||||||
"127.0.0.1:636",
|
"127.0.0.1:636",
|
||||||
"ldaps://127.0.0.1:636",
|
"ldaps://127.0.0.1:636",
|
||||||
"",
|
"",
|
||||||
|
@ -156,7 +165,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldAllowLDAPI",
|
"ShouldAllowLDAPI",
|
||||||
"ldapi:///abc",
|
"ldapi:///abc",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: "/abc"}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: "/abc"}},
|
||||||
"/abc",
|
"/abc",
|
||||||
"ldapi:///abc",
|
"ldapi:///abc",
|
||||||
"",
|
"",
|
||||||
|
@ -164,7 +173,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldAllowImplicitLDAPI",
|
"ShouldAllowImplicitLDAPI",
|
||||||
"ldapi://",
|
"ldapi://",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
|
||||||
"",
|
"",
|
||||||
"ldapi:",
|
"ldapi:",
|
||||||
"",
|
"",
|
||||||
|
@ -172,7 +181,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldAllowImplicitLDAPINoSlash",
|
"ShouldAllowImplicitLDAPINoSlash",
|
||||||
"ldapi:",
|
"ldapi:",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
|
||||||
"",
|
"",
|
||||||
"ldapi:",
|
"ldapi:",
|
||||||
"",
|
"",
|
||||||
|
@ -180,7 +189,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldSetDefaultPortSMTP",
|
"ShouldSetDefaultPortSMTP",
|
||||||
"smtp://127.0.0.1",
|
"smtp://127.0.0.1",
|
||||||
&Address{true, false, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1:25"}},
|
&Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1:25"}},
|
||||||
"127.0.0.1:25",
|
"127.0.0.1:25",
|
||||||
"smtp://127.0.0.1:25",
|
"smtp://127.0.0.1:25",
|
||||||
"",
|
"",
|
||||||
|
@ -188,7 +197,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldSetDefaultPortSUBMISSION",
|
"ShouldSetDefaultPortSUBMISSION",
|
||||||
"submission://127.0.0.1",
|
"submission://127.0.0.1",
|
||||||
&Address{true, false, 587, &url.URL{Scheme: AddressSchemeSUBMISSION, Host: "127.0.0.1:587"}},
|
&Address{true, false, -1, 587, &url.URL{Scheme: AddressSchemeSUBMISSION, Host: "127.0.0.1:587"}},
|
||||||
"127.0.0.1:587",
|
"127.0.0.1:587",
|
||||||
"submission://127.0.0.1:587",
|
"submission://127.0.0.1:587",
|
||||||
"",
|
"",
|
||||||
|
@ -196,7 +205,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldSetDefaultPortSUBMISSIONS",
|
"ShouldSetDefaultPortSUBMISSIONS",
|
||||||
"submissions://127.0.0.1",
|
"submissions://127.0.0.1",
|
||||||
&Address{true, false, 465, &url.URL{Scheme: AddressSchemeSUBMISSIONS, Host: "127.0.0.1:465"}},
|
&Address{true, false, -1, 465, &url.URL{Scheme: AddressSchemeSUBMISSIONS, Host: "127.0.0.1:465"}},
|
||||||
"127.0.0.1:465",
|
"127.0.0.1:465",
|
||||||
"submissions://127.0.0.1:465",
|
"submissions://127.0.0.1:465",
|
||||||
"",
|
"",
|
||||||
|
@ -204,7 +213,7 @@ func TestNewAddressFromString(t *testing.T) {
|
||||||
{
|
{
|
||||||
"ShouldNotOverridePort",
|
"ShouldNotOverridePort",
|
||||||
"ldap://127.0.0.1:123",
|
"ldap://127.0.0.1:123",
|
||||||
&Address{true, false, 123, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:123"}},
|
&Address{true, false, -1, 123, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:123"}},
|
||||||
"127.0.0.1:123",
|
"127.0.0.1:123",
|
||||||
"ldap://127.0.0.1:123",
|
"ldap://127.0.0.1:123",
|
||||||
"",
|
"",
|
||||||
|
@ -239,7 +248,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"ShouldValidateLDAPAddress",
|
"ShouldValidateLDAPAddress",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1"}},
|
||||||
"",
|
"",
|
||||||
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'ldap'",
|
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'ldap'",
|
||||||
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'ldap'",
|
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'ldap'",
|
||||||
|
@ -248,7 +257,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldValidateSMTPAddress",
|
"ShouldValidateSMTPAddress",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1"}},
|
||||||
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'smtp'",
|
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'smtp'",
|
||||||
"",
|
"",
|
||||||
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'smtp'",
|
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'smtp'",
|
||||||
|
@ -257,7 +266,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldValidateTCPAddress",
|
"ShouldValidateTCPAddress",
|
||||||
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "127.0.0.1"}},
|
&Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "127.0.0.1"}},
|
||||||
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'tcp'",
|
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'tcp'",
|
||||||
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'tcp'",
|
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'tcp'",
|
||||||
"",
|
"",
|
||||||
|
@ -266,7 +275,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldValidateUnixSocket",
|
"ShouldValidateUnixSocket",
|
||||||
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/socket"}},
|
&Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/socket"}},
|
||||||
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'unix'",
|
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'unix'",
|
||||||
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'unix'",
|
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'unix'",
|
||||||
"",
|
"",
|
||||||
|
@ -311,7 +320,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddress_SetHostname(t *testing.T) {
|
func TestAddress_SetHostname(t *testing.T) {
|
||||||
address := &Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0"}}
|
address := &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0"}}
|
||||||
|
|
||||||
assert.Equal(t, "tcp://0.0.0.0", address.String())
|
assert.Equal(t, "tcp://0.0.0.0", address.String())
|
||||||
|
|
||||||
|
@ -320,32 +329,6 @@ func TestAddress_SetHostname(t *testing.T) {
|
||||||
assert.Equal(t, "tcp://127.0.0.1", address.String())
|
assert.Equal(t, "tcp://127.0.0.1", address.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddress_ListenerWithUMask(t *testing.T) {
|
|
||||||
dir := t.TempDir()
|
|
||||||
|
|
||||||
address := &Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: filepath.Join(dir, "example.sock")}}
|
|
||||||
|
|
||||||
ln, err := address.ListenerWithUMask(600)
|
|
||||||
|
|
||||||
assert.NotNil(t, ln)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NoError(t, ln.Close())
|
|
||||||
|
|
||||||
address = &Address{true, true, 0, nil}
|
|
||||||
|
|
||||||
ln, err = address.ListenerWithUMask(600)
|
|
||||||
|
|
||||||
assert.Nil(t, ln)
|
|
||||||
assert.EqualError(t, err, "address url is nil")
|
|
||||||
|
|
||||||
address = &Address{true, false, 0, nil}
|
|
||||||
|
|
||||||
ln, err = address.ListenerWithUMask(600)
|
|
||||||
|
|
||||||
assert.Nil(t, ln)
|
|
||||||
assert.EqualError(t, err, "address url is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddressOutputValues(t *testing.T) {
|
func TestAddressOutputValues(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
address *Address
|
address *Address
|
||||||
|
@ -356,7 +339,7 @@ func TestAddressOutputValues(t *testing.T) {
|
||||||
address = &Address{}
|
address = &Address{}
|
||||||
assert.EqualError(t, address.validate(), "error validating the address: address url was nil")
|
assert.EqualError(t, address.validate(), "error validating the address: address url was nil")
|
||||||
|
|
||||||
address = &Address{false, false, 0, nil}
|
address = &Address{false, false, -1, 0, nil}
|
||||||
|
|
||||||
assert.Equal(t, "", address.String())
|
assert.Equal(t, "", address.String())
|
||||||
assert.Equal(t, "", address.Scheme())
|
assert.Equal(t, "", address.Scheme())
|
||||||
|
@ -370,7 +353,7 @@ func TestAddressOutputValues(t *testing.T) {
|
||||||
assert.Nil(t, listener)
|
assert.Nil(t, listener)
|
||||||
assert.EqualError(t, err, "address url is nil")
|
assert.EqualError(t, err, "address url is nil")
|
||||||
|
|
||||||
address = &Address{true, false, 8080, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:8080"}}
|
address = &Address{true, false, -1, 8080, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:8080"}}
|
||||||
|
|
||||||
assert.Equal(t, "tcp://0.0.0.0:8080", address.String())
|
assert.Equal(t, "tcp://0.0.0.0:8080", address.String())
|
||||||
assert.Equal(t, "tcp", address.Scheme())
|
assert.Equal(t, "tcp", address.Scheme())
|
||||||
|
@ -384,7 +367,7 @@ func TestAddressOutputValues(t *testing.T) {
|
||||||
assert.NotNil(t, listener)
|
assert.NotNil(t, listener)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
address = &Address{true, false, 0, nil}
|
address = &Address{true, false, -1, 0, nil}
|
||||||
|
|
||||||
assert.Equal(t, "", address.String())
|
assert.Equal(t, "", address.String())
|
||||||
assert.Equal(t, "", address.Scheme())
|
assert.Equal(t, "", address.Scheme())
|
||||||
|
@ -413,7 +396,7 @@ func TestAddressOutputValues(t *testing.T) {
|
||||||
assert.Nil(t, listener)
|
assert.Nil(t, listener)
|
||||||
assert.EqualError(t, err, "address url is nil")
|
assert.EqualError(t, err, "address url is nil")
|
||||||
|
|
||||||
address = &Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}}
|
address = &Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}}
|
||||||
|
|
||||||
assert.Equal(t, "tcp://0.0.0.0:9091", address.String())
|
assert.Equal(t, "tcp://0.0.0.0:9091", address.String())
|
||||||
assert.Equal(t, "tcp", address.Scheme())
|
assert.Equal(t, "tcp", address.Scheme())
|
||||||
|
@ -570,6 +553,132 @@ func TestNewSMTPAddress(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddress_Dial(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
have Address
|
||||||
|
success bool
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"ShouldNotDialNil",
|
||||||
|
Address{true, false, -1, 0, nil},
|
||||||
|
false,
|
||||||
|
"address url is nil",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldNotDialInvalid",
|
||||||
|
Address{false, false, -1, 0, &url.URL{}},
|
||||||
|
false,
|
||||||
|
"address url is nil",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldNotDialInvalidAddress",
|
||||||
|
Address{true, false, -1, 0, &url.URL{Scheme: "abc", Host: "127.0.0.1:0"}},
|
||||||
|
false,
|
||||||
|
"dial tcp 127.0.0.1:0: connect: connection refused",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
conn, err := tc.have.Dial()
|
||||||
|
|
||||||
|
defer func(c net.Conn) {
|
||||||
|
if c == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Close()
|
||||||
|
}(conn)
|
||||||
|
|
||||||
|
if tc.success {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert.Nil(t, conn)
|
||||||
|
if tc.err != "" {
|
||||||
|
assert.EqualError(t, err, tc.err)
|
||||||
|
} else {
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddress_UnixDomainSocket(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
have string
|
||||||
|
socket bool
|
||||||
|
path string
|
||||||
|
strUmask string
|
||||||
|
umask int
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"ShouldNotBeSocket",
|
||||||
|
"tcp://:9091",
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseSocket",
|
||||||
|
fmt.Sprintf("unix://%s", filepath.Join(dir, "example.sock")),
|
||||||
|
true,
|
||||||
|
filepath.Join(dir, "example.sock"),
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseSocketWithUmask",
|
||||||
|
fmt.Sprintf("unix://%s?umask=0022", filepath.Join(dir, "example.sock")),
|
||||||
|
true,
|
||||||
|
filepath.Join(dir, "example.sock"),
|
||||||
|
"0022",
|
||||||
|
18,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseSocketWithBadUmask",
|
||||||
|
fmt.Sprintf("unix://%s?umask=abc", filepath.Join(dir, "example.sock")),
|
||||||
|
true,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
fmt.Sprintf("error validating the unix socket address: could not parse address 'unix://%s?umask=abc': the address has a umask value of 'abc' which does not appear to be a valid octal string", filepath.Join(dir, "example.sock")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
actual, err := NewAddress(tc.have)
|
||||||
|
|
||||||
|
if tc.err == "" {
|
||||||
|
assert.Equal(t, tc.socket, actual.IsUnixDomainSocket())
|
||||||
|
assert.Equal(t, tc.path, actual.Path())
|
||||||
|
assert.Equal(t, tc.strUmask, actual.Umask())
|
||||||
|
assert.Equal(t, tc.umask, actual.umask)
|
||||||
|
|
||||||
|
ln, err := actual.Listener()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, ln)
|
||||||
|
|
||||||
|
assert.NoError(t, ln.Close())
|
||||||
|
} else {
|
||||||
|
assert.EqualError(t, err, tc.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddress_SocketHostname(t *testing.T) {
|
func TestAddress_SocketHostname(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -578,22 +687,22 @@ func TestAddress_SocketHostname(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"ShouldReturnHostname",
|
"ShouldReturnHostname",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "examplea:80"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "examplea:80"}},
|
||||||
"examplea",
|
"examplea",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnPath",
|
"ShouldReturnPath",
|
||||||
Address{true, true, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
|
Address{true, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
|
||||||
"/abc/123",
|
"/abc/123",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnNothing",
|
"ShouldReturnNothing",
|
||||||
Address{false, true, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
|
Address{false, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnNothingNil",
|
"ShouldReturnNothingNil",
|
||||||
Address{true, true, 80, nil},
|
Address{true, true, -1, 80, nil},
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -605,6 +714,41 @@ func TestAddress_SocketHostname(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddress_Path(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
have Address
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"ShouldReturnEmptyPath",
|
||||||
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}},
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldReturnPath",
|
||||||
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta", Path: "/apath"}},
|
||||||
|
"/apath",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldNotReturnPathInvalid",
|
||||||
|
Address{false, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta", Path: "/apath"}},
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldNotReturnPathNil",
|
||||||
|
Address{true, false, -1, 80, nil},
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
assert.Equal(t, tc.expected, tc.have.Path())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddress_IsTCP_IsUDP(t *testing.T) {
|
func TestAddress_IsTCP_IsUDP(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -614,49 +758,49 @@ func TestAddress_IsTCP_IsUDP(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"ShouldReturnTrueTCP",
|
"ShouldReturnTrueTCP",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnTrueTCP4",
|
"ShouldReturnTrueTCP4",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP4, Host: "tcphostb"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP4, Host: "tcphostb"}},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnTrueTCP6",
|
"ShouldReturnTrueTCP6",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP6, Host: "tcphostc"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP6, Host: "tcphostc"}},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnFalseUDP",
|
"ShouldReturnFalseUDP",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP, Host: "tcphostd"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP, Host: "tcphostd"}},
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnFalseUDP4",
|
"ShouldReturnFalseUDP4",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP4, Host: "tcphoste"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP4, Host: "tcphoste"}},
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnFalseUDP6",
|
"ShouldReturnFalseUDP6",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP6, Host: "tcphostf"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP6, Host: "tcphostf"}},
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnFalseSMTP",
|
"ShouldReturnFalseSMTP",
|
||||||
Address{true, false, 80, &url.URL{Scheme: AddressSchemeSMTP, Host: "tcphostg"}},
|
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeSMTP, Host: "tcphostg"}},
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ShouldReturnFalseUnix",
|
"ShouldReturnFalseUnix",
|
||||||
Address{true, true, 80, &url.URL{Scheme: AddressSchemeUnix, Host: "tcphosth"}},
|
Address{true, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Host: "tcphosth"}},
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,14 +37,7 @@ func CreateDefaultServer(config *schema.Configuration, providers middlewares.Pro
|
||||||
connectionScheme = schemeHTTP
|
connectionScheme = schemeHTTP
|
||||||
)
|
)
|
||||||
|
|
||||||
switch config.Server.UMask {
|
if listener, err = config.Server.Address.Listener(); err != nil {
|
||||||
case nil:
|
|
||||||
listener, err = config.Server.Address.Listener()
|
|
||||||
default:
|
|
||||||
listener, err = config.Server.Address.ListenerWithUMask(*config.Server.UMask)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize main server listener for address '%s': %w", config.Server.Address.String(), err)
|
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize main server listener for address '%s': %w", config.Server.Address.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +102,7 @@ func CreateMetricsServer(config *schema.Configuration, providers middlewares.Pro
|
||||||
Logger: logging.LoggerPrintf(logrus.DebugLevel),
|
Logger: logging.LoggerPrintf(logrus.DebugLevel),
|
||||||
}
|
}
|
||||||
|
|
||||||
switch config.Telemetry.Metrics.UMask {
|
if listener, err = config.Telemetry.Metrics.Address.Listener(); err != nil {
|
||||||
case nil:
|
|
||||||
listener, err = config.Telemetry.Metrics.Address.Listener()
|
|
||||||
default:
|
|
||||||
listener, err = config.Telemetry.Metrics.Address.ListenerWithUMask(*config.Telemetry.Metrics.UMask)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize metrics telemetry server listener for address '%s': %w", config.Telemetry.Metrics.Address.String(), err)
|
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize metrics telemetry server listener for address '%s': %w", config.Telemetry.Metrics.Address.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue