Skip to content

Commit 2faeac0

Browse files
chore: Use slices package where possible (#6585)
* chore: Use slices package where possible * More, mostly using ContainsFunc * Even more slice operations
1 parent 9dda8fb commit 2faeac0

21 files changed

Lines changed: 141 additions & 267 deletions

File tree

admin.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"os"
3535
"path"
3636
"regexp"
37+
"slices"
3738
"strconv"
3839
"strings"
3940
"sync"
@@ -675,13 +676,7 @@ func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {
675676
// key recognized; make sure its HTTP request is permitted
676677
for _, accessPerm := range adminAccess.Permissions {
677678
// verify method
678-
methodFound := accessPerm.Methods == nil
679-
for _, method := range accessPerm.Methods {
680-
if method == r.Method {
681-
methodFound = true
682-
break
683-
}
684-
}
679+
methodFound := accessPerm.Methods == nil || slices.Contains(accessPerm.Methods, r.Method)
685680
if !methodFound {
686681
return APIError{
687682
HTTPStatus: http.StatusForbidden,
@@ -877,13 +872,9 @@ func (h adminHandler) handleError(w http.ResponseWriter, r *http.Request, err er
877872
// a trustworthy/expected value. This helps to mitigate DNS
878873
// rebinding attacks.
879874
func (h adminHandler) checkHost(r *http.Request) error {
880-
var allowed bool
881-
for _, allowedOrigin := range h.allowedOrigins {
882-
if r.Host == allowedOrigin.Host {
883-
allowed = true
884-
break
885-
}
886-
}
875+
allowed := slices.ContainsFunc(h.allowedOrigins, func(u *url.URL) bool {
876+
return r.Host == u.Host
877+
})
887878
if !allowed {
888879
return APIError{
889880
HTTPStatus: http.StatusForbidden,

caddyconfig/caddyfile/importgraph.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package caddyfile
1616

1717
import (
1818
"fmt"
19+
"slices"
1920
)
2021

2122
type adjacency map[string][]string
@@ -91,12 +92,7 @@ func (i *importGraph) areConnected(from, to string) bool {
9192
if !ok {
9293
return false
9394
}
94-
for _, v := range al {
95-
if v == to {
96-
return true
97-
}
98-
}
99-
return false
95+
return slices.Contains(al, to)
10096
}
10197

10298
func (i *importGraph) willCycle(from, to string) bool {

caddyconfig/httpcaddyfile/directives.go

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package httpcaddyfile
1717
import (
1818
"encoding/json"
1919
"net"
20+
"slices"
2021
"sort"
2122
"strconv"
2223
"strings"
@@ -100,17 +101,6 @@ var defaultDirectiveOrder = []string{
100101
// plugins or by the user via the "order" global option.
101102
var directiveOrder = defaultDirectiveOrder
102103

103-
// directiveIsOrdered returns true if dir is
104-
// a known, ordered (sorted) directive.
105-
func directiveIsOrdered(dir string) bool {
106-
for _, d := range directiveOrder {
107-
if d == dir {
108-
return true
109-
}
110-
}
111-
return false
112-
}
113-
114104
// RegisterDirective registers a unique directive dir with an
115105
// associated unmarshaling (setup) function. When directive dir
116106
// is encountered in a Caddyfile, setupFunc will be called to
@@ -161,7 +151,7 @@ func RegisterHandlerDirective(dir string, setupFunc UnmarshalHandlerFunc) {
161151
// EXPERIMENTAL: This API may change or be removed.
162152
func RegisterDirectiveOrder(dir string, position Positional, standardDir string) {
163153
// check if directive was already ordered
164-
if directiveIsOrdered(dir) {
154+
if slices.Contains(directiveOrder, dir) {
165155
panic("directive '" + dir + "' already ordered")
166156
}
167157

@@ -172,12 +162,7 @@ func RegisterDirectiveOrder(dir string, position Positional, standardDir string)
172162
// check if directive exists in standard distribution, since
173163
// we can't allow plugins to depend on one another; we can't
174164
// guarantee the order that plugins are loaded in.
175-
foundStandardDir := false
176-
for _, d := range defaultDirectiveOrder {
177-
if d == standardDir {
178-
foundStandardDir = true
179-
}
180-
}
165+
foundStandardDir := slices.Contains(defaultDirectiveOrder, standardDir)
181166
if !foundStandardDir {
182167
panic("the 3rd argument '" + standardDir + "' must be a directive that exists in the standard distribution of Caddy")
183168
}
@@ -603,23 +588,17 @@ func (sb serverBlock) hostsFromKeysNotHTTP(httpPort string) []string {
603588
// hasHostCatchAllKey returns true if sb has a key that
604589
// omits a host portion, i.e. it "catches all" hosts.
605590
func (sb serverBlock) hasHostCatchAllKey() bool {
606-
for _, addr := range sb.keys {
607-
if addr.Host == "" {
608-
return true
609-
}
610-
}
611-
return false
591+
return slices.ContainsFunc(sb.keys, func(addr Address) bool {
592+
return addr.Host == ""
593+
})
612594
}
613595

614596
// isAllHTTP returns true if all sb keys explicitly specify
615597
// the http:// scheme
616598
func (sb serverBlock) isAllHTTP() bool {
617-
for _, addr := range sb.keys {
618-
if addr.Scheme != "http" {
619-
return false
620-
}
621-
}
622-
return true
599+
return !slices.ContainsFunc(sb.keys, func(addr Address) bool {
600+
return addr.Scheme != "http"
601+
})
623602
}
624603

625604
// Positional are the supported modes for ordering directives.

caddyconfig/httpcaddyfile/httptype.go

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ func (st *ServerType) serversFromPairings(
536536
if k == j {
537537
continue
538538
}
539-
if sliceContains(sblock2.block.GetKeysText(), key) {
539+
if slices.Contains(sblock2.block.GetKeysText(), key) {
540540
return nil, fmt.Errorf("ambiguous site definition: %s", key)
541541
}
542542
}
@@ -720,7 +720,7 @@ func (st *ServerType) serversFromPairings(
720720
if srv.AutoHTTPS == nil {
721721
srv.AutoHTTPS = new(caddyhttp.AutoHTTPSConfig)
722722
}
723-
if !sliceContains(srv.AutoHTTPS.Skip, addr.Host) {
723+
if !slices.Contains(srv.AutoHTTPS.Skip, addr.Host) {
724724
srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, addr.Host)
725725
}
726726
}
@@ -734,7 +734,7 @@ func (st *ServerType) serversFromPairings(
734734
// https://caddy.community/t/making-sense-of-auto-https-and-why-disabling-it-still-serves-https-instead-of-http/9761
735735
createdTLSConnPolicies, ok := sblock.pile["tls.connection_policy"]
736736
hasTLSEnabled := (ok && len(createdTLSConnPolicies) > 0) ||
737-
(addr.Host != "" && srv.AutoHTTPS != nil && !sliceContains(srv.AutoHTTPS.Skip, addr.Host))
737+
(addr.Host != "" && srv.AutoHTTPS != nil && !slices.Contains(srv.AutoHTTPS.Skip, addr.Host))
738738

739739
// we'll need to remember if the address qualifies for auto-HTTPS, so we
740740
// can add a TLS conn policy if necessary
@@ -1061,7 +1061,7 @@ func consolidateConnPolicies(cps caddytls.ConnectionPolicies) (caddytls.Connecti
10611061
} else if cps[i].CertSelection != nil && cps[j].CertSelection != nil {
10621062
// if both have one, then combine AnyTag
10631063
for _, tag := range cps[j].CertSelection.AnyTag {
1064-
if !sliceContains(cps[i].CertSelection.AnyTag, tag) {
1064+
if !slices.Contains(cps[i].CertSelection.AnyTag, tag) {
10651065
cps[i].CertSelection.AnyTag = append(cps[i].CertSelection.AnyTag, tag)
10661066
}
10671067
}
@@ -1144,7 +1144,7 @@ func appendSubrouteToRouteList(routeList caddyhttp.RouteList,
11441144
func buildSubroute(routes []ConfigValue, groupCounter counter, needsSorting bool) (*caddyhttp.Subroute, error) {
11451145
if needsSorting {
11461146
for _, val := range routes {
1147-
if !directiveIsOrdered(val.directive) {
1147+
if !slices.Contains(directiveOrder, val.directive) {
11481148
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)
11491149
}
11501150
}
@@ -1354,17 +1354,8 @@ func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.Mod
13541354

13551355
// add this server block's keys to the matcher
13561356
// pair if it doesn't already exist
1357-
if addr.Host != "" {
1358-
var found bool
1359-
for _, h := range chosenMatcherPair.hostm {
1360-
if h == addr.Host {
1361-
found = true
1362-
break
1363-
}
1364-
}
1365-
if !found {
1366-
chosenMatcherPair.hostm = append(chosenMatcherPair.hostm, addr.Host)
1367-
}
1357+
if addr.Host != "" && !slices.Contains(chosenMatcherPair.hostm, addr.Host) {
1358+
chosenMatcherPair.hostm = append(chosenMatcherPair.hostm, addr.Host)
13681359
}
13691360
}
13701361

@@ -1540,16 +1531,6 @@ func tryDuration(val any, warnings *[]caddyconfig.Warning) caddy.Duration {
15401531
return durationVal
15411532
}
15421533

1543-
// sliceContains returns true if needle is in haystack.
1544-
func sliceContains(haystack []string, needle string) bool {
1545-
for _, s := range haystack {
1546-
if s == needle {
1547-
return true
1548-
}
1549-
}
1550-
return false
1551-
}
1552-
15531534
// listenersUseAnyPortOtherThan returns true if there are any
15541535
// listeners in addresses that use a port which is not otherPort.
15551536
// Mostly borrowed from unexported method in caddyhttp package.

caddyconfig/httpcaddyfile/options.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package httpcaddyfile
1616

1717
import (
18+
"slices"
1819
"strconv"
1920

2021
"github.com/caddyserver/certmagic"
@@ -110,17 +111,12 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
110111
}
111112
pos := Positional(d.Val())
112113

113-
newOrder := directiveOrder
114+
// if directive already had an order, drop it
115+
newOrder := slices.DeleteFunc(directiveOrder, func(d string) bool {
116+
return d == dirName
117+
})
114118

115-
// if directive exists, first remove it
116-
for i, d := range newOrder {
117-
if d == dirName {
118-
newOrder = append(newOrder[:i], newOrder[i+1:]...)
119-
break
120-
}
121-
}
122-
123-
// act on the positional
119+
// act on the positional; if it's First or Last, we're done right away
124120
switch pos {
125121
case First:
126122
newOrder = append([]string{dirName}, newOrder...)
@@ -129,15 +125,19 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
129125
}
130126
directiveOrder = newOrder
131127
return newOrder, nil
128+
132129
case Last:
133130
newOrder = append(newOrder, dirName)
134131
if d.NextArg() {
135132
return nil, d.ArgErr()
136133
}
137134
directiveOrder = newOrder
138135
return newOrder, nil
136+
137+
// if it's Before or After, continue
139138
case Before:
140139
case After:
140+
141141
default:
142142
return nil, d.Errf("unknown positional '%s'", pos)
143143
}
@@ -151,17 +151,17 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
151151
return nil, d.ArgErr()
152152
}
153153

154-
// insert directive into proper position
155-
for i, d := range newOrder {
156-
if d == otherDir {
157-
if pos == Before {
158-
newOrder = append(newOrder[:i], append([]string{dirName}, newOrder[i:]...)...)
159-
} else if pos == After {
160-
newOrder = append(newOrder[:i+1], append([]string{dirName}, newOrder[i+1:]...)...)
161-
}
162-
break
163-
}
154+
// get the position of the target directive
155+
targetIndex := slices.Index(newOrder, otherDir)
156+
if targetIndex == -1 {
157+
return nil, d.Errf("directive '%s' not found", otherDir)
158+
}
159+
// if we're inserting after, we need to increment the index to go after
160+
if pos == After {
161+
targetIndex++
164162
}
163+
// insert the directive into the new order
164+
newOrder = slices.Insert(newOrder, targetIndex, dirName)
165165

166166
directiveOrder = newOrder
167167

caddyconfig/httpcaddyfile/serveroptions.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package httpcaddyfile
1717
import (
1818
"encoding/json"
1919
"fmt"
20+
"slices"
2021

2122
"github.com/dustin/go-humanize"
2223

@@ -180,7 +181,7 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
180181
if proto != "h1" && proto != "h2" && proto != "h2c" && proto != "h3" {
181182
return nil, d.Errf("unknown protocol '%s': expected h1, h2, h2c, or h3", proto)
182183
}
183-
if sliceContains(serverOpts.Protocols, proto) {
184+
if slices.Contains(serverOpts.Protocols, proto) {
184185
return nil, d.Errf("protocol %s specified more than once", proto)
185186
}
186187
serverOpts.Protocols = append(serverOpts.Protocols, proto)
@@ -229,7 +230,7 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
229230
case "client_ip_headers":
230231
headers := d.RemainingArgs()
231232
for _, header := range headers {
232-
if sliceContains(serverOpts.ClientIPHeaders, header) {
233+
if slices.Contains(serverOpts.ClientIPHeaders, header) {
233234
return nil, d.Errf("client IP header %s specified more than once", header)
234235
}
235236
serverOpts.ClientIPHeaders = append(serverOpts.ClientIPHeaders, header)
@@ -288,24 +289,15 @@ func applyServerOptions(
288289

289290
for key, server := range servers {
290291
// find the options that apply to this server
291-
opts := func() *serverOptions {
292-
for _, entry := range serverOpts {
293-
if entry.ListenerAddress == "" {
294-
return &entry
295-
}
296-
for _, listener := range server.Listen {
297-
if entry.ListenerAddress == listener {
298-
return &entry
299-
}
300-
}
301-
}
302-
return nil
303-
}()
292+
optsIndex := slices.IndexFunc(serverOpts, func(s serverOptions) bool {
293+
return s.ListenerAddress == "" || slices.Contains(server.Listen, s.ListenerAddress)
294+
})
304295

305296
// if none apply, then move to the next server
306-
if opts == nil {
297+
if optsIndex == -1 {
307298
continue
308299
}
300+
opts := serverOpts[optsIndex]
309301

310302
// set all the options
311303
server.ListenerWrappersRaw = opts.ListenerWrappersRaw

0 commit comments

Comments
 (0)