Merge branch 'master' into net-wal
commit
e2104d3235
|
@ -19,6 +19,7 @@ import (
|
|||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
|
@ -335,9 +336,7 @@ func TestAdminHandlerBuiltinRouteErrors(t *testing.T) {
|
|||
|
||||
func testGetMetricValue(labels map[string]string) float64 {
|
||||
promLabels := prometheus.Labels{}
|
||||
for k, v := range labels {
|
||||
promLabels[k] = v
|
||||
}
|
||||
maps.Copy(promLabels, labels)
|
||||
|
||||
metric, err := adminMetrics.requestErrors.GetMetricWith(promLabels)
|
||||
if err != nil {
|
||||
|
@ -377,9 +376,7 @@ func (m *mockModule) CaddyModule() ModuleInfo {
|
|||
|
||||
func TestNewAdminHandlerRouterRegistration(t *testing.T) {
|
||||
originalModules := make(map[string]ModuleInfo)
|
||||
for k, v := range modules {
|
||||
originalModules[k] = v
|
||||
}
|
||||
maps.Copy(originalModules, modules)
|
||||
defer func() {
|
||||
modules = originalModules
|
||||
}()
|
||||
|
@ -479,9 +476,7 @@ func TestAdminRouterProvisioning(t *testing.T) {
|
|||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
originalModules := make(map[string]ModuleInfo)
|
||||
for k, v := range modules {
|
||||
originalModules[k] = v
|
||||
}
|
||||
maps.Copy(originalModules, modules)
|
||||
defer func() {
|
||||
modules = originalModules
|
||||
}()
|
||||
|
@ -774,9 +769,7 @@ func (m *mockIssuerModule) CaddyModule() ModuleInfo {
|
|||
|
||||
func TestManageIdentity(t *testing.T) {
|
||||
originalModules := make(map[string]ModuleInfo)
|
||||
for k, v := range modules {
|
||||
originalModules[k] = v
|
||||
}
|
||||
maps.Copy(originalModules, modules)
|
||||
defer func() {
|
||||
modules = originalModules
|
||||
}()
|
||||
|
|
|
@ -16,6 +16,7 @@ package httpcaddyfile
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"maps"
|
||||
"net"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -365,9 +366,7 @@ func parseSegmentAsConfig(h Helper) ([]ConfigValue, error) {
|
|||
// copy existing matcher definitions so we can augment
|
||||
// new ones that are defined only in this scope
|
||||
matcherDefs := make(map[string]caddy.ModuleMap, len(h.matcherDefs))
|
||||
for key, val := range h.matcherDefs {
|
||||
matcherDefs[key] = val
|
||||
}
|
||||
maps.Copy(matcherDefs, h.matcherDefs)
|
||||
|
||||
// find and extract any embedded matcher definitions in this scope
|
||||
for i := 0; i < len(segments); i++ {
|
||||
|
@ -483,12 +482,29 @@ func sortRoutes(routes []ConfigValue) {
|
|||
// we can only confidently compare path lengths if both
|
||||
// directives have a single path to match (issue #5037)
|
||||
if iPathLen > 0 && jPathLen > 0 {
|
||||
// trim the trailing wildcard if there is one
|
||||
iPathTrimmed := strings.TrimSuffix(iPM[0], "*")
|
||||
jPathTrimmed := strings.TrimSuffix(jPM[0], "*")
|
||||
|
||||
// if both paths are the same except for a trailing wildcard,
|
||||
// sort by the shorter path first (which is more specific)
|
||||
if strings.TrimSuffix(iPM[0], "*") == strings.TrimSuffix(jPM[0], "*") {
|
||||
if iPathTrimmed == jPathTrimmed {
|
||||
return iPathLen < jPathLen
|
||||
}
|
||||
|
||||
// we use the trimmed length to compare the paths
|
||||
// https://github.com/caddyserver/caddy/issues/7012#issuecomment-2870142195
|
||||
// credit to https://github.com/Hellio404
|
||||
// for sorts with many items, mixing matchers w/ and w/o wildcards will confuse the sort and result in incorrect orders
|
||||
iPathLen = len(iPathTrimmed)
|
||||
jPathLen = len(jPathTrimmed)
|
||||
|
||||
// if both paths have the same length, sort lexically
|
||||
// https://github.com/caddyserver/caddy/pull/7015#issuecomment-2871993588
|
||||
if iPathLen == jPathLen {
|
||||
return iPathTrimmed < jPathTrimmed
|
||||
}
|
||||
|
||||
// sort most-specific (longest) path first
|
||||
return iPathLen > jPathLen
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -703,9 +704,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io
|
|||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
for k, v := range headers {
|
||||
req.Header[k] = v
|
||||
}
|
||||
maps.Copy(req.Header, headers)
|
||||
|
||||
// make an HTTP client that dials our network type, since admin
|
||||
// endpoints aren't always TCP, which is what the default transport
|
||||
|
|
|
@ -300,8 +300,10 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
|
|||
info, err := fs.Stat(fileSystem, filename)
|
||||
if err != nil {
|
||||
err = fsrv.mapDirOpenError(fileSystem, err, filename)
|
||||
if errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrInvalid) {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return fsrv.notFound(w, r, next)
|
||||
} else if errors.Is(err, fs.ErrInvalid) {
|
||||
return caddyhttp.Error(http.StatusBadRequest, err)
|
||||
} else if errors.Is(err, fs.ErrPermission) {
|
||||
return caddyhttp.Error(http.StatusForbidden, err)
|
||||
}
|
||||
|
@ -611,6 +613,11 @@ func (fsrv *FileServer) mapDirOpenError(fileSystem fs.FS, originalErr error, nam
|
|||
return originalErr
|
||||
}
|
||||
|
||||
var pathErr *fs.PathError
|
||||
if errors.As(originalErr, &pathErr) {
|
||||
return fs.ErrInvalid
|
||||
}
|
||||
|
||||
parts := strings.Split(name, separator)
|
||||
for i := range parts {
|
||||
if parts[i] == "" {
|
||||
|
|
|
@ -118,6 +118,11 @@ func (irh interceptedResponseHandler) WriteHeader(statusCode int) {
|
|||
irh.ResponseRecorder.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
// EXPERIMENTAL: Subject to change or removal.
|
||||
func (irh interceptedResponseHandler) Unwrap() http.ResponseWriter {
|
||||
return irh.ResponseRecorder
|
||||
}
|
||||
|
||||
// EXPERIMENTAL: Subject to change or removal.
|
||||
func (ir Intercept) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
|
|
|
@ -17,6 +17,7 @@ package fastcgi
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -314,7 +315,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
|
|||
|
||||
// if the index is turned off, we skip the redirect and try_files
|
||||
if indexFile != "off" {
|
||||
dirRedir := false
|
||||
var dirRedir bool
|
||||
dirIndex := "{http.request.uri.path}/" + indexFile
|
||||
tryPolicy := "first_exist_fallback"
|
||||
|
||||
|
@ -328,13 +329,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
|
|||
tryPolicy = ""
|
||||
}
|
||||
|
||||
for _, tf := range tryFiles {
|
||||
if tf == dirIndex {
|
||||
dirRedir = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
dirRedir = slices.Contains(tryFiles, dirIndex)
|
||||
}
|
||||
|
||||
if dirRedir {
|
||||
|
|
|
@ -528,13 +528,7 @@ func (h *HTTPTransport) shouldUseTLS(req *http.Request) bool {
|
|||
}
|
||||
|
||||
port := req.URL.Port()
|
||||
for i := range h.TLS.ExceptPorts {
|
||||
if h.TLS.ExceptPorts[i] == port {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return !slices.Contains(h.TLS.ExceptPorts, port)
|
||||
}
|
||||
|
||||
// TLSEnabled returns true if TLS is enabled.
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"net/http"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
@ -323,13 +324,7 @@ func cmdRespond(fl caddycmd.Flags) (int, error) {
|
|||
|
||||
// figure out if status code was explicitly specified; this lets
|
||||
// us set a non-zero value as the default but is a little hacky
|
||||
var statusCodeFlagSpecified bool
|
||||
for _, fl := range os.Args {
|
||||
if fl == "--status" {
|
||||
statusCodeFlagSpecified = true
|
||||
break
|
||||
}
|
||||
}
|
||||
statusCodeFlagSpecified := slices.Contains(os.Args, "--status")
|
||||
|
||||
// try to determine what kind of parameter the unnamed argument is
|
||||
if arg != "" {
|
||||
|
|
|
@ -87,13 +87,7 @@ nextChoice:
|
|||
}
|
||||
|
||||
if len(p.AnyTag) > 0 {
|
||||
var found bool
|
||||
for _, tag := range p.AnyTag {
|
||||
if cert.HasTag(tag) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
found := slices.ContainsFunc(p.AnyTag, cert.HasTag)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/acmez/v3"
|
||||
|
@ -369,13 +370,7 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
|
|||
}
|
||||
|
||||
// ensure ALPN includes the ACME TLS-ALPN protocol
|
||||
var alpnFound bool
|
||||
for _, a := range p.ALPN {
|
||||
if a == acmez.ACMETLS1Protocol {
|
||||
alpnFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
alpnFound := slices.Contains(p.ALPN, acmez.ACMETLS1Protocol)
|
||||
if !alpnFound && (cfg.NextProtos == nil || len(cfg.NextProtos) > 0) {
|
||||
cfg.NextProtos = append(cfg.NextProtos, acmez.ACMETLS1Protocol)
|
||||
}
|
||||
|
@ -1004,10 +999,8 @@ func (l LeafCertClientAuth) VerifyClientCertificate(rawCerts [][]byte, _ [][]*x5
|
|||
return fmt.Errorf("can't parse the given certificate: %s", err.Error())
|
||||
}
|
||||
|
||||
for _, trustedLeafCert := range l.trustedLeafCerts {
|
||||
if remoteLeafCert.Equal(trustedLeafCert) {
|
||||
return nil
|
||||
}
|
||||
if slices.ContainsFunc(l.trustedLeafCerts, remoteLeafCert.Equal) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("client leaf certificate failed validation")
|
||||
|
|
Loading…
Reference in New Issue