Skip to content

Commit

Permalink
Even more slice operations
Browse files Browse the repository at this point in the history
  • Loading branch information
francislavoie committed Sep 23, 2024
1 parent e2a22fe commit 794423b
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 126 deletions.
19 changes: 5 additions & 14 deletions admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"os"
"path"
"regexp"
"slices"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -675,13 +676,7 @@ func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {
// key recognized; make sure its HTTP request is permitted
for _, accessPerm := range adminAccess.Permissions {
// verify method
methodFound := accessPerm.Methods == nil
for _, method := range accessPerm.Methods {
if method == r.Method {
methodFound = true
break
}
}
methodFound := accessPerm.Methods == nil || slices.Contains(accessPerm.Methods, r.Method)
if !methodFound {
return APIError{
HTTPStatus: http.StatusForbidden,
Expand Down Expand Up @@ -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
// rebinding attacks.
func (h adminHandler) checkHost(r *http.Request) error {
var allowed bool
for _, allowedOrigin := range h.allowedOrigins {
if r.Host == allowedOrigin.Host {
allowed = true
break
}
}
allowed := slices.ContainsFunc(h.allowedOrigins, func(u *url.URL) bool {
return r.Host == u.Host
})
if !allowed {
return APIError{
HTTPStatus: http.StatusForbidden,
Expand Down
7 changes: 1 addition & 6 deletions caddyconfig/httpcaddyfile/directives.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,7 @@ func RegisterDirectiveOrder(dir string, position Positional, standardDir string)
// check if directive exists in standard distribution, since
// we can't allow plugins to depend on one another; we can't
// guarantee the order that plugins are loaded in.
foundStandardDir := false
for _, d := range defaultDirectiveOrder {
if d == standardDir {
foundStandardDir = true
}
}
foundStandardDir := slices.Contains(defaultDirectiveOrder, standardDir)
if !foundStandardDir {
panic("the 3rd argument '" + standardDir + "' must be a directive that exists in the standard distribution of Caddy")
}
Expand Down
13 changes: 2 additions & 11 deletions caddyconfig/httpcaddyfile/httptype.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,17 +1354,8 @@ func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.Mod

// add this server block's keys to the matcher
// pair if it doesn't already exist
if 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)
}
if addr.Host != "" && !slices.Contains(chosenMatcherPair.hostm, addr.Host) {
chosenMatcherPair.hostm = append(chosenMatcherPair.hostm, addr.Host)
}
}

Expand Down
40 changes: 20 additions & 20 deletions caddyconfig/httpcaddyfile/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package httpcaddyfile

import (
"slices"
"strconv"

"github.com/caddyserver/certmagic"
Expand Down Expand Up @@ -110,17 +111,12 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
}
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
for i, d := range newOrder {
if d == dirName {
newOrder = append(newOrder[:i], newOrder[i+1:]...)
break
}
}

// act on the positional
// act on the positional; if it's First or Last, we're done right away
switch pos {
case First:
newOrder = append([]string{dirName}, newOrder...)
Expand All @@ -129,15 +125,19 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
}
directiveOrder = newOrder
return newOrder, nil

case Last:
newOrder = append(newOrder, dirName)
if d.NextArg() {
return nil, d.ArgErr()
}
directiveOrder = newOrder
return newOrder, nil

// if it's Before or After, continue
case Before:
case After:

default:
return nil, d.Errf("unknown positional '%s'", pos)
}
Expand All @@ -151,17 +151,17 @@ func parseOptOrder(d *caddyfile.Dispenser, _ any) (any, error) {
return nil, d.ArgErr()
}

// insert directive into proper position
for i, d := range newOrder {
if d == otherDir {
if pos == Before {
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
}
// get the position of the target directive
targetIndex := slices.Index(newOrder, otherDir)
if targetIndex == -1 {
return nil, d.Errf("directive '%s' not found", otherDir)
}
// 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

Expand Down
19 changes: 5 additions & 14 deletions caddyconfig/httpcaddyfile/serveroptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,24 +289,15 @@ func applyServerOptions(

for key, server := range servers {
// find the options that apply to this server
opts := func() *serverOptions {
for _, entry := range serverOpts {
if entry.ListenerAddress == "" {
return &entry
}
for _, listener := range server.Listen {
if entry.ListenerAddress == listener {
return &entry
}
}
}
return nil
}()
optsIndex := slices.IndexFunc(serverOpts, func(s serverOptions) bool {
return s.ListenerAddress == "" || slices.Contains(server.Listen, s.ListenerAddress)
})

// if none apply, then move to the next server
if opts == nil {
if optsIndex == -1 {
continue
}
opts := serverOpts[optsIndex]

// set all the options
server.ListenerWrappersRaw = opts.ListenerWrappersRaw
Expand Down
41 changes: 19 additions & 22 deletions caddyconfig/httpcaddyfile/tlsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,20 @@ func (st ServerType) buildTLSApp(
for _, pair := range pairings {
for _, sb := range pair.serverBlocks {
for _, addr := range sb.keys {
if addr.Host == "" {
// this server block has a hostless key, now
// go through and add all the hosts to the set
for _, otherAddr := range sb.keys {
if otherAddr.Original == addr.Original {
continue
}
if otherAddr.Host != "" && otherAddr.Scheme != "http" && otherAddr.Port != httpPort {
httpsHostsSharedWithHostlessKey[otherAddr.Host] = struct{}{}
}
if addr.Host != "" {
continue
}
// this server block has a hostless key, now
// go through and add all the hosts to the set
for _, otherAddr := range sb.keys {
if otherAddr.Original == addr.Original {
continue
}
if otherAddr.Host != "" && otherAddr.Scheme != "http" && otherAddr.Port != httpPort {
httpsHostsSharedWithHostlessKey[otherAddr.Host] = struct{}{}
}
break
}
break
}
}
}
Expand Down Expand Up @@ -581,7 +582,7 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls
if !automationPolicyHasAllPublicNames(aps[i]) {
// if this automation policy has internal names, we might as well remove it
// so auto-https can implicitly use the internal issuer
aps = append(aps[:i], aps[i+1:]...)
aps = slices.Delete(aps, i, i+1)
i--
}
}
Expand All @@ -598,7 +599,7 @@ outer:
for j := i + 1; j < len(aps); j++ {
// if they're exactly equal in every way, just keep one of them
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!
// even if i decrements to -1, will be incremented to 0 immediately
i--
Expand Down Expand Up @@ -628,7 +629,7 @@ outer:
// cause example.com to be served by the less specific policy for
// '*.com', which might be different (yes we've seen this happen)
if automationPolicyShadows(i, aps) >= j {
aps = append(aps[:i], aps[i+1:]...)
aps = slices.Delete(aps, i, i+1)
i--
continue outer
}
Expand All @@ -639,7 +640,7 @@ outer:
aps[i].SubjectsRaw = append(aps[i].SubjectsRaw, subj)
}
}
aps = append(aps[:j], aps[j+1:]...)
aps = slices.Delete(aps, j, j+1)
j--
}
}
Expand All @@ -659,13 +660,9 @@ func automationPolicyIsSubset(a, b *caddytls.AutomationPolicy) bool {
return false
}
for _, aSubj := range a.SubjectsRaw {
var inSuperset bool
for _, bSubj := range b.SubjectsRaw {
if certmagic.MatchWildcard(aSubj, bSubj) {
inSuperset = true
break
}
}
inSuperset := slices.ContainsFunc(b.SubjectsRaw, func(bSubj string) bool {
return certmagic.MatchWildcard(aSubj, bSubj)
})
if !inSuperset {
return false
}
Expand Down
25 changes: 13 additions & 12 deletions modules/caddyevents/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,19 @@ func (app *App) Provision(ctx caddy.Context) error {
app.subscriptions = make(map[string]map[caddy.ModuleID][]Handler)

for _, sub := range app.Subscriptions {
if sub.HandlersRaw != nil {
handlersIface, err := ctx.LoadModule(sub, "HandlersRaw")
if err != nil {
return fmt.Errorf("loading event subscriber modules: %v", err)
}
for _, h := range handlersIface.([]any) {
sub.Handlers = append(sub.Handlers, h.(Handler))
}
if len(sub.Handlers) == 0 {
// pointless to bind without any handlers
return fmt.Errorf("no handlers defined")
}
if sub.HandlersRaw == nil {
continue
}
handlersIface, err := ctx.LoadModule(sub, "HandlersRaw")
if err != nil {
return fmt.Errorf("loading event subscriber modules: %v", err)
}
for _, h := range handlersIface.([]any) {
sub.Handlers = append(sub.Handlers, h.(Handler))
}
if len(sub.Handlers) == 0 {
// pointless to bind without any handlers
return fmt.Errorf("no handlers defined")
}
}

Expand Down
10 changes: 4 additions & 6 deletions modules/caddyhttp/encode/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"io"
"math"
"net/http"
"slices"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -441,12 +442,9 @@ func AcceptedEncodings(r *http.Request, preferredOrder []string) []string {
}

// set server preference
prefOrder := -1
for i, p := range preferredOrder {
if encName == p {
prefOrder = len(preferredOrder) - i
break
}
prefOrder := slices.Index(preferredOrder, encName)
if prefOrder > -1 {
prefOrder = len(preferredOrder) - prefOrder
}

prefs = append(prefs, encodingPreference{
Expand Down
13 changes: 7 additions & 6 deletions modules/caddyhttp/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,14 @@ type HeaderOps struct {
func (ops *HeaderOps) Provision(_ caddy.Context) error {
for fieldName, replacements := range ops.Replace {
for i, r := range replacements {
if r.SearchRegexp != "" {
re, err := regexp.Compile(r.SearchRegexp)
if err != nil {
return fmt.Errorf("replacement %d for header field '%s': %v", i, fieldName, err)
}
replacements[i].re = re
if r.SearchRegexp == "" {
continue
}
re, err := regexp.Compile(r.SearchRegexp)
if err != nil {
return fmt.Errorf("replacement %d for header field '%s': %v", i, fieldName, err)
}
replacements[i].re = re
}
}
return nil
Expand Down
9 changes: 3 additions & 6 deletions modules/caddyhttp/reverseproxy/healthchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"net/url"
"regexp"
"runtime/debug"
"slices"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -397,12 +398,8 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
u.Scheme = "https"

// if the port is in the except list, flip back to HTTP
if ht, ok := h.Transport.(*HTTPTransport); ok {
for _, exceptPort := range ht.TLS.ExceptPorts {
if exceptPort == port {
u.Scheme = "http"
}
}
if ht, ok := h.Transport.(*HTTPTransport); ok && slices.Contains(ht.TLS.ExceptPorts, port) {
u.Scheme = "http"
}
}

Expand Down
1 change: 1 addition & 0 deletions modules/caddyhttp/templates/frontmatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func extractFrontMatter(input string) (map[string]any, string, error) {
if firstLine == fmType.FenceOpen {
closingFence = fmType.FenceClose
fmParser = fmType.ParseFunc
break
}
}

Expand Down
Loading

0 comments on commit 794423b

Please sign in to comment.