mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 06:03:48 +03:00
chore: Use slices package where possible (#6585)
* chore: Use slices package where possible * More, mostly using ContainsFunc * Even more slice operations
This commit is contained in:
parent
9dda8fbf84
commit
2faeac0a10
21 changed files with 142 additions and 268 deletions
19
admin.go
19
admin.go
|
@ -34,6 +34,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -675,13 +676,7 @@ func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {
|
||||||
// key recognized; make sure its HTTP request is permitted
|
// key recognized; make sure its HTTP request is permitted
|
||||||
for _, accessPerm := range adminAccess.Permissions {
|
for _, accessPerm := range adminAccess.Permissions {
|
||||||
// verify method
|
// verify method
|
||||||
methodFound := accessPerm.Methods == nil
|
methodFound := accessPerm.Methods == nil || slices.Contains(accessPerm.Methods, r.Method)
|
||||||
for _, method := range accessPerm.Methods {
|
|
||||||
if method == r.Method {
|
|
||||||
methodFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !methodFound {
|
if !methodFound {
|
||||||
return APIError{
|
return APIError{
|
||||||
HTTPStatus: http.StatusForbidden,
|
HTTPStatus: http.StatusForbidden,
|
||||||
|
@ -877,13 +872,9 @@ func (h adminHandler) handleError(w http.ResponseWriter, r *http.Request, err er
|
||||||
// a trustworthy/expected value. This helps to mitigate DNS
|
// a trustworthy/expected value. This helps to mitigate DNS
|
||||||
// rebinding attacks.
|
// rebinding attacks.
|
||||||
func (h adminHandler) checkHost(r *http.Request) error {
|
func (h adminHandler) checkHost(r *http.Request) error {
|
||||||
var allowed bool
|
allowed := slices.ContainsFunc(h.allowedOrigins, func(u *url.URL) bool {
|
||||||
for _, allowedOrigin := range h.allowedOrigins {
|
return r.Host == u.Host
|
||||||
if r.Host == allowedOrigin.Host {
|
})
|
||||||
allowed = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !allowed {
|
if !allowed {
|
||||||
return APIError{
|
return APIError{
|
||||||
HTTPStatus: http.StatusForbidden,
|
HTTPStatus: http.StatusForbidden,
|
||||||
|
|
|
@ -16,6 +16,7 @@ package caddyfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type adjacency map[string][]string
|
type adjacency map[string][]string
|
||||||
|
@ -91,12 +92,7 @@ func (i *importGraph) areConnected(from, to string) bool {
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, v := range al {
|
return slices.Contains(al, to)
|
||||||
if v == to {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *importGraph) willCycle(from, to string) bool {
|
func (i *importGraph) willCycle(from, to string) bool {
|
||||||
|
|
|
@ -17,6 +17,7 @@ package httpcaddyfile
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -100,17 +101,6 @@ var defaultDirectiveOrder = []string{
|
||||||
// plugins or by the user via the "order" global option.
|
// plugins or by the user via the "order" global option.
|
||||||
var directiveOrder = defaultDirectiveOrder
|
var directiveOrder = defaultDirectiveOrder
|
||||||
|
|
||||||
// directiveIsOrdered returns true if dir is
|
|
||||||
// a known, ordered (sorted) directive.
|
|
||||||
func directiveIsOrdered(dir string) bool {
|
|
||||||
for _, d := range directiveOrder {
|
|
||||||
if d == dir {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterDirective registers a unique directive dir with an
|
// RegisterDirective registers a unique directive dir with an
|
||||||
// associated unmarshaling (setup) function. When directive dir
|
// associated unmarshaling (setup) function. When directive dir
|
||||||
// is encountered in a Caddyfile, setupFunc will be called to
|
// is encountered in a Caddyfile, setupFunc will be called to
|
||||||
|
@ -161,7 +151,7 @@ func RegisterHandlerDirective(dir string, setupFunc UnmarshalHandlerFunc) {
|
||||||
// EXPERIMENTAL: This API may change or be removed.
|
// EXPERIMENTAL: This API may change or be removed.
|
||||||
func RegisterDirectiveOrder(dir string, position Positional, standardDir string) {
|
func RegisterDirectiveOrder(dir string, position Positional, standardDir string) {
|
||||||
// check if directive was already ordered
|
// check if directive was already ordered
|
||||||
if directiveIsOrdered(dir) {
|
if slices.Contains(directiveOrder, dir) {
|
||||||
panic("directive '" + dir + "' already ordered")
|
panic("directive '" + dir + "' already ordered")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,12 +162,7 @@ func RegisterDirectiveOrder(dir string, position Positional, standardDir string)
|
||||||
// check if directive exists in standard distribution, since
|
// check if directive exists in standard distribution, since
|
||||||
// we can't allow plugins to depend on one another; we can't
|
// we can't allow plugins to depend on one another; we can't
|
||||||
// guarantee the order that plugins are loaded in.
|
// guarantee the order that plugins are loaded in.
|
||||||
foundStandardDir := false
|
foundStandardDir := slices.Contains(defaultDirectiveOrder, standardDir)
|
||||||
for _, d := range defaultDirectiveOrder {
|
|
||||||
if d == standardDir {
|
|
||||||
foundStandardDir = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundStandardDir {
|
if !foundStandardDir {
|
||||||
panic("the 3rd argument '" + standardDir + "' must be a directive that exists in the standard distribution of Caddy")
|
panic("the 3rd argument '" + standardDir + "' must be a directive that exists in the standard distribution of Caddy")
|
||||||
}
|
}
|
||||||
|
@ -603,23 +588,17 @@ func (sb serverBlock) hostsFromKeysNotHTTP(httpPort string) []string {
|
||||||
// hasHostCatchAllKey returns true if sb has a key that
|
// hasHostCatchAllKey returns true if sb has a key that
|
||||||
// omits a host portion, i.e. it "catches all" hosts.
|
// omits a host portion, i.e. it "catches all" hosts.
|
||||||
func (sb serverBlock) hasHostCatchAllKey() bool {
|
func (sb serverBlock) hasHostCatchAllKey() bool {
|
||||||
for _, addr := range sb.keys {
|
return slices.ContainsFunc(sb.keys, func(addr Address) bool {
|
||||||
if addr.Host == "" {
|
return addr.Host == ""
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// isAllHTTP returns true if all sb keys explicitly specify
|
// isAllHTTP returns true if all sb keys explicitly specify
|
||||||
// the http:// scheme
|
// the http:// scheme
|
||||||
func (sb serverBlock) isAllHTTP() bool {
|
func (sb serverBlock) isAllHTTP() bool {
|
||||||
for _, addr := range sb.keys {
|
return !slices.ContainsFunc(sb.keys, func(addr Address) bool {
|
||||||
if addr.Scheme != "http" {
|
return addr.Scheme != "http"
|
||||||
return false
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Positional are the supported modes for ordering directives.
|
// Positional are the supported modes for ordering directives.
|
||||||
|
|
|
@ -536,7 +536,7 @@ func (st *ServerType) serversFromPairings(
|
||||||
if k == j {
|
if k == j {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sliceContains(sblock2.block.GetKeysText(), key) {
|
if slices.Contains(sblock2.block.GetKeysText(), key) {
|
||||||
return nil, fmt.Errorf("ambiguous site definition: %s", key)
|
return nil, fmt.Errorf("ambiguous site definition: %s", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,7 +720,7 @@ func (st *ServerType) serversFromPairings(
|
||||||
if srv.AutoHTTPS == nil {
|
if srv.AutoHTTPS == nil {
|
||||||
srv.AutoHTTPS = new(caddyhttp.AutoHTTPSConfig)
|
srv.AutoHTTPS = new(caddyhttp.AutoHTTPSConfig)
|
||||||
}
|
}
|
||||||
if !sliceContains(srv.AutoHTTPS.Skip, addr.Host) {
|
if !slices.Contains(srv.AutoHTTPS.Skip, addr.Host) {
|
||||||
srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, addr.Host)
|
srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, addr.Host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -734,7 +734,7 @@ func (st *ServerType) serversFromPairings(
|
||||||
// https://caddy.community/t/making-sense-of-auto-https-and-why-disabling-it-still-serves-https-instead-of-http/9761
|
// https://caddy.community/t/making-sense-of-auto-https-and-why-disabling-it-still-serves-https-instead-of-http/9761
|
||||||
createdTLSConnPolicies, ok := sblock.pile["tls.connection_policy"]
|
createdTLSConnPolicies, ok := sblock.pile["tls.connection_policy"]
|
||||||
hasTLSEnabled := (ok && len(createdTLSConnPolicies) > 0) ||
|
hasTLSEnabled := (ok && len(createdTLSConnPolicies) > 0) ||
|
||||||
(addr.Host != "" && srv.AutoHTTPS != nil && !sliceContains(srv.AutoHTTPS.Skip, addr.Host))
|
(addr.Host != "" && srv.AutoHTTPS != nil && !slices.Contains(srv.AutoHTTPS.Skip, addr.Host))
|
||||||
|
|
||||||
// we'll need to remember if the address qualifies for auto-HTTPS, so we
|
// we'll need to remember if the address qualifies for auto-HTTPS, so we
|
||||||
// can add a TLS conn policy if necessary
|
// can add a TLS conn policy if necessary
|
||||||
|
@ -1061,7 +1061,7 @@ func consolidateConnPolicies(cps caddytls.ConnectionPolicies) (caddytls.Connecti
|
||||||
} else if cps[i].CertSelection != nil && cps[j].CertSelection != nil {
|
} else if cps[i].CertSelection != nil && cps[j].CertSelection != nil {
|
||||||
// if both have one, then combine AnyTag
|
// if both have one, then combine AnyTag
|
||||||
for _, tag := range cps[j].CertSelection.AnyTag {
|
for _, tag := range cps[j].CertSelection.AnyTag {
|
||||||
if !sliceContains(cps[i].CertSelection.AnyTag, tag) {
|
if !slices.Contains(cps[i].CertSelection.AnyTag, tag) {
|
||||||
cps[i].CertSelection.AnyTag = append(cps[i].CertSelection.AnyTag, tag)
|
cps[i].CertSelection.AnyTag = append(cps[i].CertSelection.AnyTag, tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1144,7 @@ func appendSubrouteToRouteList(routeList caddyhttp.RouteList,
|
||||||
func buildSubroute(routes []ConfigValue, groupCounter counter, needsSorting bool) (*caddyhttp.Subroute, error) {
|
func buildSubroute(routes []ConfigValue, groupCounter counter, needsSorting bool) (*caddyhttp.Subroute, error) {
|
||||||
if needsSorting {
|
if needsSorting {
|
||||||
for _, val := range routes {
|
for _, val := range routes {
|
||||||
if !directiveIsOrdered(val.directive) {
|
if !slices.Contains(directiveOrder, val.directive) {
|
||||||
return nil, fmt.Errorf("directive '%s' is not an ordered HTTP handler, so it cannot be used here - try placing within a route block or using the order global option", val.directive)
|
return nil, fmt.Errorf("directive '%s' is not an ordered HTTP handler, so it cannot be used here - try placing within a route block or using the order global option", val.directive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1354,19 +1354,10 @@ func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.Mod
|
||||||
|
|
||||||
// add this server block's keys to the matcher
|
// add this server block's keys to the matcher
|
||||||
// pair if it doesn't already exist
|
// pair if it doesn't already exist
|
||||||
if addr.Host != "" {
|
if addr.Host != "" && !slices.Contains(chosenMatcherPair.hostm, addr.Host) {
|
||||||
var found bool
|
|
||||||
for _, h := range chosenMatcherPair.hostm {
|
|
||||||
if h == addr.Host {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
chosenMatcherPair.hostm = append(chosenMatcherPair.hostm, addr.Host)
|
chosenMatcherPair.hostm = append(chosenMatcherPair.hostm, addr.Host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// iterate each pairing of host and path matchers and
|
// iterate each pairing of host and path matchers and
|
||||||
// put them into a map for JSON encoding
|
// put them into a map for JSON encoding
|
||||||
|
@ -1540,16 +1531,6 @@ func tryDuration(val any, warnings *[]caddyconfig.Warning) caddy.Duration {
|
||||||
return durationVal
|
return durationVal
|
||||||
}
|
}
|
||||||
|
|
||||||
// sliceContains returns true if needle is in haystack.
|
|
||||||
func sliceContains(haystack []string, needle string) bool {
|
|
||||||
for _, s := range haystack {
|
|
||||||
if s == needle {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// listenersUseAnyPortOtherThan returns true if there are any
|
// listenersUseAnyPortOtherThan returns true if there are any
|
||||||
// listeners in addresses that use a port which is not otherPort.
|
// listeners in addresses that use a port which is not otherPort.
|
||||||
// Mostly borrowed from unexported method in caddyhttp package.
|
// Mostly borrowed from unexported method in caddyhttp package.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package httpcaddyfile
|
package httpcaddyfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
|
@ -110,17 +111,12 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
}
|
}
|
||||||
pos := Positional(d.Val())
|
pos := Positional(d.Val())
|
||||||
|
|
||||||
newOrder := directiveOrder
|
// if directive already had an order, drop it
|
||||||
|
newOrder := slices.DeleteFunc(directiveOrder, func(d string) bool {
|
||||||
|
return d == dirName
|
||||||
|
})
|
||||||
|
|
||||||
// if directive exists, first remove it
|
// act on the positional; if it's First or Last, we're done right away
|
||||||
for i, d := range newOrder {
|
|
||||||
if d == dirName {
|
|
||||||
newOrder = append(newOrder[:i], newOrder[i+1:]...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// act on the positional
|
|
||||||
switch pos {
|
switch pos {
|
||||||
case First:
|
case First:
|
||||||
newOrder = append([]string{dirName}, newOrder...)
|
newOrder = append([]string{dirName}, newOrder...)
|
||||||
|
@ -129,6 +125,7 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
}
|
}
|
||||||
directiveOrder = newOrder
|
directiveOrder = newOrder
|
||||||
return newOrder, nil
|
return newOrder, nil
|
||||||
|
|
||||||
case Last:
|
case Last:
|
||||||
newOrder = append(newOrder, dirName)
|
newOrder = append(newOrder, dirName)
|
||||||
if d.NextArg() {
|
if d.NextArg() {
|
||||||
|
@ -136,8 +133,11 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
}
|
}
|
||||||
directiveOrder = newOrder
|
directiveOrder = newOrder
|
||||||
return newOrder, nil
|
return newOrder, nil
|
||||||
|
|
||||||
|
// if it's Before or After, continue
|
||||||
case Before:
|
case Before:
|
||||||
case After:
|
case After:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, d.Errf("unknown positional '%s'", pos)
|
return nil, d.Errf("unknown positional '%s'", pos)
|
||||||
}
|
}
|
||||||
|
@ -151,17 +151,17 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
return nil, d.ArgErr()
|
return nil, d.ArgErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert directive into proper position
|
// get the position of the target directive
|
||||||
for i, d := range newOrder {
|
targetIndex := slices.Index(newOrder, otherDir)
|
||||||
if d == otherDir {
|
if targetIndex == -1 {
|
||||||
if pos == Before {
|
return nil, d.Errf("directive '%s' not found", otherDir)
|
||||||
newOrder = append(newOrder[:i], append([]string{dirName}, newOrder[i:]...)...)
|
|
||||||
} else if pos == After {
|
|
||||||
newOrder = append(newOrder[:i+1], append([]string{dirName}, newOrder[i+1:]...)...)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
// if we're inserting after, we need to increment the index to go after
|
||||||
|
if pos == After {
|
||||||
|
targetIndex++
|
||||||
}
|
}
|
||||||
|
// insert the directive into the new order
|
||||||
|
newOrder = slices.Insert(newOrder, targetIndex, dirName)
|
||||||
|
|
||||||
directiveOrder = newOrder
|
directiveOrder = newOrder
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package httpcaddyfile
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
|
|
||||||
|
@ -180,7 +181,7 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
|
||||||
if proto != "h1" && proto != "h2" && proto != "h2c" && proto != "h3" {
|
if proto != "h1" && proto != "h2" && proto != "h2c" && proto != "h3" {
|
||||||
return nil, d.Errf("unknown protocol '%s': expected h1, h2, h2c, or h3", proto)
|
return nil, d.Errf("unknown protocol '%s': expected h1, h2, h2c, or h3", proto)
|
||||||
}
|
}
|
||||||
if sliceContains(serverOpts.Protocols, proto) {
|
if slices.Contains(serverOpts.Protocols, proto) {
|
||||||
return nil, d.Errf("protocol %s specified more than once", proto)
|
return nil, d.Errf("protocol %s specified more than once", proto)
|
||||||
}
|
}
|
||||||
serverOpts.Protocols = append(serverOpts.Protocols, proto)
|
serverOpts.Protocols = append(serverOpts.Protocols, proto)
|
||||||
|
@ -229,7 +230,7 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
|
||||||
case "client_ip_headers":
|
case "client_ip_headers":
|
||||||
headers := d.RemainingArgs()
|
headers := d.RemainingArgs()
|
||||||
for _, header := range headers {
|
for _, header := range headers {
|
||||||
if sliceContains(serverOpts.ClientIPHeaders, header) {
|
if slices.Contains(serverOpts.ClientIPHeaders, header) {
|
||||||
return nil, d.Errf("client IP header %s specified more than once", header)
|
return nil, d.Errf("client IP header %s specified more than once", header)
|
||||||
}
|
}
|
||||||
serverOpts.ClientIPHeaders = append(serverOpts.ClientIPHeaders, header)
|
serverOpts.ClientIPHeaders = append(serverOpts.ClientIPHeaders, header)
|
||||||
|
@ -288,24 +289,15 @@ func applyServerOptions(
|
||||||
|
|
||||||
for key, server := range servers {
|
for key, server := range servers {
|
||||||
// find the options that apply to this server
|
// find the options that apply to this server
|
||||||
opts := func() *serverOptions {
|
optsIndex := slices.IndexFunc(serverOpts, func(s serverOptions) bool {
|
||||||
for _, entry := range serverOpts {
|
return s.ListenerAddress == "" || slices.Contains(server.Listen, s.ListenerAddress)
|
||||||
if entry.ListenerAddress == "" {
|
})
|
||||||
return &entry
|
|
||||||
}
|
|
||||||
for _, listener := range server.Listen {
|
|
||||||
if entry.ListenerAddress == listener {
|
|
||||||
return &entry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}()
|
|
||||||
|
|
||||||
// if none apply, then move to the next server
|
// if none apply, then move to the next server
|
||||||
if opts == nil {
|
if optsIndex == -1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
opts := serverOpts[optsIndex]
|
||||||
|
|
||||||
// set all the options
|
// set all the options
|
||||||
server.ListenerWrappersRaw = opts.ListenerWrappersRaw
|
server.ListenerWrappersRaw = opts.ListenerWrappersRaw
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -57,7 +58,9 @@ func (st ServerType) buildTLSApp(
|
||||||
for _, pair := range pairings {
|
for _, pair := range pairings {
|
||||||
for _, sb := range pair.serverBlocks {
|
for _, sb := range pair.serverBlocks {
|
||||||
for _, addr := range sb.keys {
|
for _, addr := range sb.keys {
|
||||||
if addr.Host == "" {
|
if addr.Host != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// this server block has a hostless key, now
|
// this server block has a hostless key, now
|
||||||
// go through and add all the hosts to the set
|
// go through and add all the hosts to the set
|
||||||
for _, otherAddr := range sb.keys {
|
for _, otherAddr := range sb.keys {
|
||||||
|
@ -73,7 +76,6 @@ func (st ServerType) buildTLSApp(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// a catch-all automation policy is used as a "default" for all subjects that
|
// a catch-all automation policy is used as a "default" for all subjects that
|
||||||
// don't have custom configuration explicitly associated with them; this
|
// don't have custom configuration explicitly associated with them; this
|
||||||
|
@ -465,7 +467,7 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
|
||||||
if globalACMECA != nil && acmeIssuer.CA == "" {
|
if globalACMECA != nil && acmeIssuer.CA == "" {
|
||||||
acmeIssuer.CA = globalACMECA.(string)
|
acmeIssuer.CA = globalACMECA.(string)
|
||||||
}
|
}
|
||||||
if globalACMECARoot != nil && !sliceContains(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string)) {
|
if globalACMECARoot != nil && !slices.Contains(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string)) {
|
||||||
acmeIssuer.TrustedRootsPEMFiles = append(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string))
|
acmeIssuer.TrustedRootsPEMFiles = append(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string))
|
||||||
}
|
}
|
||||||
if globalACMEDNS != nil && (acmeIssuer.Challenges == nil || acmeIssuer.Challenges.DNS == nil) {
|
if globalACMEDNS != nil && (acmeIssuer.Challenges == nil || acmeIssuer.Challenges.DNS == nil) {
|
||||||
|
@ -580,7 +582,7 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls
|
||||||
if !automationPolicyHasAllPublicNames(aps[i]) {
|
if !automationPolicyHasAllPublicNames(aps[i]) {
|
||||||
// if this automation policy has internal names, we might as well remove it
|
// if this automation policy has internal names, we might as well remove it
|
||||||
// so auto-https can implicitly use the internal issuer
|
// so auto-https can implicitly use the internal issuer
|
||||||
aps = append(aps[:i], aps[i+1:]...)
|
aps = slices.Delete(aps, i, i+1)
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +599,7 @@ outer:
|
||||||
for j := i + 1; j < len(aps); j++ {
|
for j := i + 1; j < len(aps); j++ {
|
||||||
// if they're exactly equal in every way, just keep one of them
|
// if they're exactly equal in every way, just keep one of them
|
||||||
if reflect.DeepEqual(aps[i], aps[j]) {
|
if reflect.DeepEqual(aps[i], aps[j]) {
|
||||||
aps = append(aps[:j], aps[j+1:]...)
|
aps = slices.Delete(aps, j, j+1)
|
||||||
// must re-evaluate current i against next j; can't skip it!
|
// must re-evaluate current i against next j; can't skip it!
|
||||||
// even if i decrements to -1, will be incremented to 0 immediately
|
// even if i decrements to -1, will be incremented to 0 immediately
|
||||||
i--
|
i--
|
||||||
|
@ -627,18 +629,18 @@ outer:
|
||||||
// cause example.com to be served by the less specific policy for
|
// cause example.com to be served by the less specific policy for
|
||||||
// '*.com', which might be different (yes we've seen this happen)
|
// '*.com', which might be different (yes we've seen this happen)
|
||||||
if automationPolicyShadows(i, aps) >= j {
|
if automationPolicyShadows(i, aps) >= j {
|
||||||
aps = append(aps[:i], aps[i+1:]...)
|
aps = slices.Delete(aps, i, i+1)
|
||||||
i--
|
i--
|
||||||
continue outer
|
continue outer
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// avoid repeated subjects
|
// avoid repeated subjects
|
||||||
for _, subj := range aps[j].SubjectsRaw {
|
for _, subj := range aps[j].SubjectsRaw {
|
||||||
if !sliceContains(aps[i].SubjectsRaw, subj) {
|
if !slices.Contains(aps[i].SubjectsRaw, subj) {
|
||||||
aps[i].SubjectsRaw = append(aps[i].SubjectsRaw, subj)
|
aps[i].SubjectsRaw = append(aps[i].SubjectsRaw, subj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aps = append(aps[:j], aps[j+1:]...)
|
aps = slices.Delete(aps, j, j+1)
|
||||||
j--
|
j--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,13 +660,9 @@ func automationPolicyIsSubset(a, b *caddytls.AutomationPolicy) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, aSubj := range a.SubjectsRaw {
|
for _, aSubj := range a.SubjectsRaw {
|
||||||
var inSuperset bool
|
inSuperset := slices.ContainsFunc(b.SubjectsRaw, func(bSubj string) bool {
|
||||||
for _, bSubj := range b.SubjectsRaw {
|
return certmagic.MatchWildcard(aSubj, bSubj)
|
||||||
if certmagic.MatchWildcard(aSubj, bSubj) {
|
})
|
||||||
inSuperset = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !inSuperset {
|
if !inSuperset {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -709,12 +707,9 @@ func subjectQualifiesForPublicCert(ap *caddytls.AutomationPolicy, subj string) b
|
||||||
// automationPolicyHasAllPublicNames returns true if all the names on the policy
|
// automationPolicyHasAllPublicNames returns true if all the names on the policy
|
||||||
// do NOT qualify for public certs OR are tailscale domains.
|
// do NOT qualify for public certs OR are tailscale domains.
|
||||||
func automationPolicyHasAllPublicNames(ap *caddytls.AutomationPolicy) bool {
|
func automationPolicyHasAllPublicNames(ap *caddytls.AutomationPolicy) bool {
|
||||||
for _, subj := range ap.SubjectsRaw {
|
return !slices.ContainsFunc(ap.SubjectsRaw, func(i string) bool {
|
||||||
if !subjectQualifiesForPublicCert(ap, subj) || isTailscaleDomain(subj) {
|
return !subjectQualifiesForPublicCert(ap, i) || isTailscaleDomain(i)
|
||||||
return false
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isTailscaleDomain(name string) bool {
|
func isTailscaleDomain(name string) bool {
|
||||||
|
|
|
@ -124,7 +124,9 @@ func (app *App) Provision(ctx caddy.Context) error {
|
||||||
app.subscriptions = make(map[string]map[caddy.ModuleID][]Handler)
|
app.subscriptions = make(map[string]map[caddy.ModuleID][]Handler)
|
||||||
|
|
||||||
for _, sub := range app.Subscriptions {
|
for _, sub := range app.Subscriptions {
|
||||||
if sub.HandlersRaw != nil {
|
if sub.HandlersRaw == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
handlersIface, err := ctx.LoadModule(sub, "HandlersRaw")
|
handlersIface, err := ctx.LoadModule(sub, "HandlersRaw")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("loading event subscriber modules: %v", err)
|
return fmt.Errorf("loading event subscriber modules: %v", err)
|
||||||
|
@ -137,7 +139,6 @@ func (app *App) Provision(ctx caddy.Context) error {
|
||||||
return fmt.Errorf("no handlers defined")
|
return fmt.Errorf("no handlers defined")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package caddyhttp
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -66,17 +67,6 @@ type AutoHTTPSConfig struct {
|
||||||
IgnoreLoadedCerts bool `json:"ignore_loaded_certificates,omitempty"`
|
IgnoreLoadedCerts bool `json:"ignore_loaded_certificates,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skipped returns true if name is in skipSlice, which
|
|
||||||
// should be either the Skip or SkipCerts field on ahc.
|
|
||||||
func (ahc AutoHTTPSConfig) Skipped(name string, skipSlice []string) bool {
|
|
||||||
for _, n := range skipSlice {
|
|
||||||
if name == n {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// automaticHTTPSPhase1 provisions all route matchers, determines
|
// automaticHTTPSPhase1 provisions all route matchers, determines
|
||||||
// which domain names found in the routes qualify for automatic
|
// which domain names found in the routes qualify for automatic
|
||||||
// HTTPS, and sets up HTTP->HTTPS redirects. This phase must occur
|
// HTTPS, and sets up HTTP->HTTPS redirects. This phase must occur
|
||||||
|
@ -158,7 +148,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
|
||||||
return fmt.Errorf("%s: route %d, matcher set %d, matcher %d, host matcher %d: %v",
|
return fmt.Errorf("%s: route %d, matcher set %d, matcher %d, host matcher %d: %v",
|
||||||
srvName, routeIdx, matcherSetIdx, matcherIdx, hostMatcherIdx, err)
|
srvName, routeIdx, matcherSetIdx, matcherIdx, hostMatcherIdx, err)
|
||||||
}
|
}
|
||||||
if !srv.AutoHTTPS.Skipped(d, srv.AutoHTTPS.Skip) {
|
if !slices.Contains(srv.AutoHTTPS.Skip, d) {
|
||||||
serverDomainSet[d] = struct{}{}
|
serverDomainSet[d] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +183,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
|
||||||
} else {
|
} else {
|
||||||
for d := range serverDomainSet {
|
for d := range serverDomainSet {
|
||||||
if certmagic.SubjectQualifiesForCert(d) &&
|
if certmagic.SubjectQualifiesForCert(d) &&
|
||||||
!srv.AutoHTTPS.Skipped(d, srv.AutoHTTPS.SkipCerts) {
|
!slices.Contains(srv.AutoHTTPS.SkipCerts, d) {
|
||||||
// if a certificate for this name is already loaded,
|
// if a certificate for this name is already loaded,
|
||||||
// don't obtain another one for it, unless we are
|
// don't obtain another one for it, unless we are
|
||||||
// supposed to ignore loaded certificates
|
// supposed to ignore loaded certificates
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -441,12 +442,9 @@ func AcceptedEncodings(r *http.Request, preferredOrder []string) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set server preference
|
// set server preference
|
||||||
prefOrder := -1
|
prefOrder := slices.Index(preferredOrder, encName)
|
||||||
for i, p := range preferredOrder {
|
if prefOrder > -1 {
|
||||||
if encName == p {
|
prefOrder = len(preferredOrder) - prefOrder
|
||||||
prefOrder = len(preferredOrder) - i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prefs = append(prefs, encodingPreference{
|
prefs = append(prefs, encodingPreference{
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -281,12 +282,9 @@ type fileInfo struct {
|
||||||
|
|
||||||
// HasExt returns true if the filename has any of the given suffixes, case-insensitive.
|
// HasExt returns true if the filename has any of the given suffixes, case-insensitive.
|
||||||
func (fi fileInfo) HasExt(exts ...string) bool {
|
func (fi fileInfo) HasExt(exts ...string) bool {
|
||||||
for _, ext := range exts {
|
return slices.ContainsFunc(exts, func(ext string) bool {
|
||||||
if strings.HasSuffix(strings.ToLower(fi.Name), strings.ToLower(ext)) {
|
return strings.HasSuffix(strings.ToLower(fi.Name), strings.ToLower(ext))
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanSize returns the size of the file as a
|
// HumanSize returns the size of the file as a
|
||||||
|
|
|
@ -135,7 +135,9 @@ type HeaderOps struct {
|
||||||
func (ops *HeaderOps) Provision(_ caddy.Context) error {
|
func (ops *HeaderOps) Provision(_ caddy.Context) error {
|
||||||
for fieldName, replacements := range ops.Replace {
|
for fieldName, replacements := range ops.Replace {
|
||||||
for i, r := range replacements {
|
for i, r := range replacements {
|
||||||
if r.SearchRegexp != "" {
|
if r.SearchRegexp == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
re, err := regexp.Compile(r.SearchRegexp)
|
re, err := regexp.Compile(r.SearchRegexp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("replacement %d for header field '%s': %v", i, fieldName, err)
|
return fmt.Errorf("replacement %d for header field '%s': %v", i, fieldName, err)
|
||||||
|
@ -143,7 +145,6 @@ func (ops *HeaderOps) Provision(_ caddy.Context) error {
|
||||||
replacements[i].re = re
|
replacements[i].re = re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
|
@ -126,7 +127,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
|
||||||
// defer work until a variable is actually evaluated by using replacer's Map callback
|
// defer work until a variable is actually evaluated by using replacer's Map callback
|
||||||
repl.Map(func(key string) (any, bool) {
|
repl.Map(func(key string) (any, bool) {
|
||||||
// return early if the variable is not even a configured destination
|
// return early if the variable is not even a configured destination
|
||||||
destIdx := h.destinationIndex(key)
|
destIdx := slices.Index(h.Destinations, key)
|
||||||
if destIdx < 0 {
|
if destIdx < 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -170,17 +171,6 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
|
||||||
return next.ServeHTTP(w, r)
|
return next.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// destinationIndex returns the positional index of the destination
|
|
||||||
// is name is a known destination; otherwise it returns -1.
|
|
||||||
func (h Handler) destinationIndex(name string) int {
|
|
||||||
for i, dest := range h.Destinations {
|
|
||||||
if dest == name {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mapping describes a mapping from input to outputs.
|
// Mapping describes a mapping from input to outputs.
|
||||||
type Mapping struct {
|
type Mapping struct {
|
||||||
// The input value to match. Must be distinct from other mappings.
|
// The input value to match. Must be distinct from other mappings.
|
||||||
|
|
|
@ -764,12 +764,7 @@ func (m *MatchMethod) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
|
|
||||||
// Match returns true if r matches m.
|
// Match returns true if r matches m.
|
||||||
func (m MatchMethod) Match(r *http.Request) bool {
|
func (m MatchMethod) Match(r *http.Request) bool {
|
||||||
for _, method := range m {
|
return slices.Contains(m, r.Method)
|
||||||
if r.Method == method {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CELLibrary produces options that expose this matcher for use in CEL
|
// CELLibrary produces options that expose this matcher for use in CEL
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -397,14 +398,10 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
|
||||||
u.Scheme = "https"
|
u.Scheme = "https"
|
||||||
|
|
||||||
// if the port is in the except list, flip back to HTTP
|
// if the port is in the except list, flip back to HTTP
|
||||||
if ht, ok := h.Transport.(*HTTPTransport); ok {
|
if ht, ok := h.Transport.(*HTTPTransport); ok && slices.Contains(ht.TLS.ExceptPorts, port) {
|
||||||
for _, exceptPort := range ht.TLS.ExceptPorts {
|
|
||||||
if exceptPort == port {
|
|
||||||
u.Scheme = "http"
|
u.Scheme = "http"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have a provisioned uri, use that, otherwise use
|
// if we have a provisioned uri, use that, otherwise use
|
||||||
// the deprecated Path option
|
// the deprecated Path option
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -381,7 +382,7 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
|
||||||
rt.DisableCompression = !*h.Compression
|
rt.DisableCompression = !*h.Compression
|
||||||
}
|
}
|
||||||
|
|
||||||
if sliceContains(h.Versions, "2") {
|
if slices.Contains(h.Versions, "2") {
|
||||||
if err := http2.ConfigureTransport(rt); err != nil {
|
if err := http2.ConfigureTransport(rt); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -400,13 +401,13 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
|
||||||
return nil, fmt.Errorf("making TLS client config for HTTP/3 transport: %v", err)
|
return nil, fmt.Errorf("making TLS client config for HTTP/3 transport: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if len(h.Versions) > 1 && sliceContains(h.Versions, "3") {
|
} else if len(h.Versions) > 1 && slices.Contains(h.Versions, "3") {
|
||||||
return nil, fmt.Errorf("if HTTP/3 is enabled to the upstream, no other HTTP versions are supported")
|
return nil, fmt.Errorf("if HTTP/3 is enabled to the upstream, no other HTTP versions are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
// if h2c is enabled, configure its transport (std lib http.Transport
|
// if h2c is enabled, configure its transport (std lib http.Transport
|
||||||
// does not "HTTP/2 over cleartext TCP")
|
// does not "HTTP/2 over cleartext TCP")
|
||||||
if sliceContains(h.Versions, "h2c") {
|
if slices.Contains(h.Versions, "h2c") {
|
||||||
// crafting our own http2.Transport doesn't allow us to utilize
|
// crafting our own http2.Transport doesn't allow us to utilize
|
||||||
// most of the customizations/preferences on the http.Transport,
|
// most of the customizations/preferences on the http.Transport,
|
||||||
// because, for some reason, only http2.ConfigureTransport()
|
// because, for some reason, only http2.ConfigureTransport()
|
||||||
|
@ -783,16 +784,6 @@ func decodeBase64DERCert(certStr string) (*x509.Certificate, error) {
|
||||||
return x509.ParseCertificate(derBytes)
|
return x509.ParseCertificate(derBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sliceContains returns true if needle is in haystack.
|
|
||||||
func sliceContains(haystack []string, needle string) bool {
|
|
||||||
for _, s := range haystack {
|
|
||||||
if s == needle {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interface guards
|
// Interface guards
|
||||||
var (
|
var (
|
||||||
_ caddy.Provisioner = (*HTTPTransport)(nil)
|
_ caddy.Provisioner = (*HTTPTransport)(nil)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -543,12 +544,9 @@ func (s *Server) hasListenerAddress(fullAddr string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) hasTLSClientAuth() bool {
|
func (s *Server) hasTLSClientAuth() bool {
|
||||||
for _, cp := range s.TLSConnPolicies {
|
return slices.ContainsFunc(s.TLSConnPolicies, func(cp *caddytls.ConnectionPolicy) bool {
|
||||||
if cp.ClientAuthentication != nil && cp.ClientAuthentication.Active() {
|
return cp.ClientAuthentication != nil && cp.ClientAuthentication.Active()
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// findLastRouteWithHostMatcher returns the index of the last route
|
// findLastRouteWithHostMatcher returns the index of the last route
|
||||||
|
@ -849,12 +847,7 @@ func (s *Server) logRequest(
|
||||||
|
|
||||||
// protocol returns true if the protocol proto is configured/enabled.
|
// protocol returns true if the protocol proto is configured/enabled.
|
||||||
func (s *Server) protocol(proto string) bool {
|
func (s *Server) protocol(proto string) bool {
|
||||||
for _, p := range s.Protocols {
|
return slices.Contains(s.Protocols, proto)
|
||||||
if p == proto {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listeners returns the server's listeners. These are active listeners,
|
// Listeners returns the server's listeners. These are active listeners,
|
||||||
|
@ -959,12 +952,9 @@ func determineTrustedProxy(r *http.Request, s *Server) (bool, string) {
|
||||||
// isTrustedClientIP returns true if the given IP address is
|
// isTrustedClientIP returns true if the given IP address is
|
||||||
// in the list of trusted IP ranges.
|
// in the list of trusted IP ranges.
|
||||||
func isTrustedClientIP(ipAddr netip.Addr, trusted []netip.Prefix) bool {
|
func isTrustedClientIP(ipAddr netip.Addr, trusted []netip.Prefix) bool {
|
||||||
for _, ipRange := range trusted {
|
return slices.ContainsFunc(trusted, func(prefix netip.Prefix) bool {
|
||||||
if ipRange.Contains(ipAddr) {
|
return prefix.Contains(ipAddr)
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// trustedRealClientIP finds the client IP from the request assuming it is
|
// trustedRealClientIP finds the client IP from the request assuming it is
|
||||||
|
|
|
@ -40,6 +40,7 @@ func extractFrontMatter(input string) (map[string]any, string, error) {
|
||||||
if firstLine == fmType.FenceOpen {
|
if firstLine == fmType.FenceOpen {
|
||||||
closingFence = fmType.FenceClose
|
closingFence = fmType.FenceClose
|
||||||
fmParser = fmType.ParseFunc
|
fmParser = fmType.ParseFunc
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
|
@ -373,12 +374,9 @@ func (ap *AutomationPolicy) Subjects() []string {
|
||||||
|
|
||||||
// AllInternalSubjects returns true if all the subjects on this policy are internal.
|
// AllInternalSubjects returns true if all the subjects on this policy are internal.
|
||||||
func (ap *AutomationPolicy) AllInternalSubjects() bool {
|
func (ap *AutomationPolicy) AllInternalSubjects() bool {
|
||||||
for _, subj := range ap.subjects {
|
return !slices.ContainsFunc(ap.subjects, func(s string) bool {
|
||||||
if !certmagic.SubjectIsInternal(subj) {
|
return !certmagic.SubjectIsInternal(s)
|
||||||
return false
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ap *AutomationPolicy) onlyInternalIssuer() bool {
|
func (ap *AutomationPolicy) onlyInternalIssuer() bool {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
|
|
||||||
|
@ -72,15 +73,9 @@ nextChoice:
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.SubjectOrganization) > 0 {
|
if len(p.SubjectOrganization) > 0 {
|
||||||
var found bool
|
found := slices.ContainsFunc(p.SubjectOrganization, func(s string) bool {
|
||||||
for _, subjOrg := range p.SubjectOrganization {
|
return slices.Contains(cert.Leaf.Subject.Organization, s)
|
||||||
for _, org := range cert.Leaf.Subject.Organization {
|
})
|
||||||
if subjOrg == org {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
if !found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -321,12 +322,9 @@ func (MatchRemoteIP) parseIPRange(str string) ([]netip.Prefix, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MatchRemoteIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
|
func (MatchRemoteIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
|
||||||
for _, ipRange := range ranges {
|
return slices.ContainsFunc(ranges, func(prefix netip.Prefix) bool {
|
||||||
if ipRange.Contains(ip) {
|
return prefix.Contains(ip)
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalCaddyfile sets up the MatchRemoteIP from Caddyfile tokens. Syntax:
|
// UnmarshalCaddyfile sets up the MatchRemoteIP from Caddyfile tokens. Syntax:
|
||||||
|
@ -439,12 +437,9 @@ func (MatchLocalIP) parseIPRange(str string) ([]netip.Prefix, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MatchLocalIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
|
func (MatchLocalIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
|
||||||
for _, ipRange := range ranges {
|
return slices.ContainsFunc(ranges, func(prefix netip.Prefix) bool {
|
||||||
if ipRange.Contains(ip) {
|
return prefix.Contains(ip)
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalCaddyfile sets up the MatchLocalIP from Caddyfile tokens. Syntax:
|
// UnmarshalCaddyfile sets up the MatchLocalIP from Caddyfile tokens. Syntax:
|
||||||
|
|
Loading…
Reference in a new issue