Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package caddy for openSUSE:Factory checked in at 2023-08-06 16:29:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/caddy (Old) and /work/SRC/openSUSE:Factory/.caddy.new.22712 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "caddy" Sun Aug 6 16:29:48 2023 rev:17 rq:1102521 version:2.7.3 Changes: -------- --- /work/SRC/openSUSE:Factory/caddy/caddy.changes 2023-08-05 12:56:39.609251930 +0200 +++ /work/SRC/openSUSE:Factory/.caddy.new.22712/caddy.changes 2023-08-06 16:30:07.435905995 +0200 @@ -1,0 +2,12 @@ +Sun Aug 06 01:06:42 UTC 2023 - jkowalc...@suse.com + +- Update to version 2.7.3: + * go.mod: Upgrade to quic-go v0.37.3 + * cmd: Split unix sockets for admin endpoint addresses (#5696) + * reverseproxy: do not parse upstream address too early if it contains replaceble parts (#5695) + * caddyfile: check that matched key is not a substring of the replacement key (#5685) + * chore: use `--clean` instead of `--rm-dist` for goreleaser (#5691) + * go.mod: Upgrade quic-go to v0.37.2 (fix #5680) + * fileserver: browse: Render SVG images in grid + +------------------------------------------------------------------- Old: ---- caddy-2.7.2.tar.gz New: ---- caddy-2.7.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ caddy.spec ++++++ --- /var/tmp/diff_new_pack.rALFEB/_old 2023-08-06 16:30:08.547912735 +0200 +++ /var/tmp/diff_new_pack.rALFEB/_new 2023-08-06 16:30:08.555912783 +0200 @@ -27,7 +27,7 @@ %endif Name: caddy -Version: 2.7.2 +Version: 2.7.3 Release: 0 Summary: Fast, multi-platform web server with automatic HTTPS License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.rALFEB/_old 2023-08-06 16:30:08.611913123 +0200 +++ /var/tmp/diff_new_pack.rALFEB/_new 2023-08-06 16:30:08.615913147 +0200 @@ -5,7 +5,7 @@ <param name="filename">caddy</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> - <param name="revision">v2.7.2</param> + <param name="revision">v2.7.3</param> <param name="changesgenerate">enable</param> </service> <service mode="disabled" name="set_version"> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.rALFEB/_old 2023-08-06 16:30:08.639913293 +0200 +++ /var/tmp/diff_new_pack.rALFEB/_new 2023-08-06 16:30:08.639913293 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/caddyserver/caddy.git</param> - <param name="changesrevision">e2fc08bd34cc17b8cbb6ac364fa1ec41c4c643b9</param></service></servicedata> + <param name="changesrevision">a8cc5d1a7d9d80e12ab895beaf4eaed34cc6bded</param></service></servicedata> (No newline at EOF) ++++++ caddy-2.7.2.tar.gz -> caddy-2.7.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/.github/workflows/release.yml new/caddy-2.7.3/.github/workflows/release.yml --- old/caddy-2.7.2/.github/workflows/release.yml 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/.github/workflows/release.yml 2023-08-06 02:10:15.000000000 +0200 @@ -109,7 +109,7 @@ uses: goreleaser/goreleaser-action@v4 with: version: latest - args: release --rm-dist --timeout 60m + args: release --clean --timeout 60m env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.vars.outputs.version_tag }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/caddyconfig/caddyfile/importargs.go new/caddy-2.7.3/caddyconfig/caddyfile/importargs.go --- old/caddy-2.7.2/caddyconfig/caddyfile/importargs.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/caddyconfig/caddyfile/importargs.go 2023-08-06 02:10:15.000000000 +0200 @@ -93,6 +93,11 @@ // TODO: Remove the deprecated {args.*} placeholder // support at some point in the future if matches := argsRegexpIndexDeprecated.FindStringSubmatch(key); len(matches) > 0 { + // What's matched may be a substring of the key + if matches[0] != key { + return nil, false + } + value, err := strconv.Atoi(matches[1]) if err != nil { caddy.Log().Named("caddyfile").Warn( @@ -111,6 +116,11 @@ // Handle args[*] form if matches := argsRegexpIndex.FindStringSubmatch(key); len(matches) > 0 { + // What's matched may be a substring of the key + if matches[0] != key { + return nil, false + } + if strings.Contains(matches[1], ":") { caddy.Log().Named("caddyfile").Warn( "Variadic placeholder {args[" + matches[1] + "]} must be a token on its own") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/caddyconfig/caddyfile/parse_test.go new/caddy-2.7.3/caddyconfig/caddyfile/parse_test.go --- old/caddy-2.7.2/caddyconfig/caddyfile/parse_test.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/caddyconfig/caddyfile/parse_test.go 2023-08-06 02:10:15.000000000 +0200 @@ -718,6 +718,36 @@ } } +func TestImportReplacementInJSONWithBrace(t *testing.T) { + for i, test := range []struct { + args []string + input string + expect string + }{ + { + args: []string{"123"}, + input: "{args[0]}", + expect: "123", + }, + { + args: []string{"123"}, + input: `{"key":"{args[0]}"}`, + expect: `{"key":"123"}`, + }, + { + args: []string{"123", "123"}, + input: `{"key":[{args[0]},{args[1]}]}`, + expect: `{"key":[123,123]}`, + }, + } { + repl := makeArgsReplacer(test.args) + actual := repl.ReplaceKnown(test.input, "") + if actual != test.expect { + t.Errorf("Test %d: Expected: '%s' but got '%s'", i, test.expect, actual) + } + } +} + func TestSnippets(t *testing.T) { p := testParser(` (common) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt --- old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt 2023-08-06 02:10:15.000000000 +0200 @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp first_label Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy {re.first_label.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "{http.regexp.first_label.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "first_label", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt --- old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt 2023-08-06 02:10:15.000000000 +0200 @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp port Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy app:6{re.port.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "app:6{http.regexp.port.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "port", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt --- old/caddy-2.7.2/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/caddy-2.7.3/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt 2023-08-06 02:10:15.000000000 +0200 @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp port Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy app:{re.port.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "app:{http.regexp.port.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "port", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/cmd/commandfuncs.go new/caddy-2.7.3/cmd/commandfuncs.go --- old/caddy-2.7.2/cmd/commandfuncs.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/cmd/commandfuncs.go 2023-08-06 02:10:15.000000000 +0200 @@ -35,6 +35,7 @@ "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "github.com/caddyserver/caddy/v2/internal" "go.uber.org/zap" ) @@ -611,6 +612,16 @@ origin := "http://" + parsedAddr.JoinHostPort(0) if parsedAddr.IsUnixNetwork() { origin = "http://127.0.0.1" // bogus host is a hack so that http.NewRequest() is happy + + // the unix address at this point might still contain the optional + // unix socket permissions, which are part of the address/host. + // those need to be removed first, as they aren't part of the + // resulting unix file path + addr, _, err := internal.SplitUnixSocketPermissionsBits(parsedAddr.Host) + if err != nil { + return nil, err + } + parsedAddr.Host = addr } // form the request diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/go.mod new/caddy-2.7.3/go.mod --- old/caddy-2.7.2/go.mod 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/go.mod 2023-08-06 02:10:15.000000000 +0200 @@ -17,7 +17,7 @@ github.com/mastercactapus/proxyprotocol v0.0.4 github.com/mholt/acmez v1.2.0 github.com/prometheus/client_golang v1.14.0 - github.com/quic-go/quic-go v0.37.1 + github.com/quic-go/quic-go v0.37.3 github.com/smallstep/certificates v0.24.3-rc.5 github.com/smallstep/nosql v0.6.0 github.com/smallstep/truststore v0.12.1 @@ -58,7 +58,7 @@ github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.0 // indirect + github.com/quic-go/qtls-go1-20 v0.3.1 // indirect github.com/smallstep/go-attestation v0.4.4-0.20230509120429-e17291421738 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.3 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/go.sum new/caddy-2.7.3/go.sum --- old/caddy-2.7.2/go.sum 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/go.sum 2023-08-06 02:10:15.000000000 +0200 @@ -861,10 +861,10 @@ github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk= -github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.1 h1:M+mcsFq9KoxVjCetIwH65TvusW1UdRBc6zmxI6pkeD0= -github.com/quic-go/quic-go v0.37.1/go.mod h1:XtCUOCALTTWbPyd0IxFfHf6h0sEMubRFvEYHl3QxKw8= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.37.3 h1:pkHH3xaMNUNAh6OtgEV/0K6Fz+YIJXhPzgd/ShiRDm4= +github.com/quic-go/quic-go v0.37.3/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/internal/sockets.go new/caddy-2.7.3/internal/sockets.go --- old/caddy-2.7.2/internal/sockets.go 1970-01-01 01:00:00.000000000 +0100 +++ new/caddy-2.7.3/internal/sockets.go 2023-08-06 02:10:15.000000000 +0200 @@ -0,0 +1,56 @@ +// Copyright 2015 Matthew Holt and The Caddy Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "fmt" + "io/fs" + "strconv" + "strings" +) + +// SplitUnixSocketPermissionsBits takes a unix socket address in the +// unusual "path|bits" format (e.g. /run/caddy.sock|0222) and tries +// to split it into socket path (host) and permissions bits (port). +// Colons (":") can't be used as separator, as socket paths on Windows +// may include a drive letter (e.g. `unix/c:\absolute\path.sock`). +// Permission bits will default to 0200 if none are specified. +// Throws an error, if the first carrying bit does not +// include write perms (e.g. `0422` or `022`). +// Symbolic permission representation (e.g. `u=w,g=w,o=w`) +// is not supported and will throw an error for now! +func SplitUnixSocketPermissionsBits(addr string) (path string, fileMode fs.FileMode, err error) { + addrSplit := strings.SplitN(addr, "|", 2) + + if len(addrSplit) == 2 { + // parse octal permission bit string as uint32 + fileModeUInt64, err := strconv.ParseUint(addrSplit[1], 8, 32) + if err != nil { + return "", 0, fmt.Errorf("could not parse octal permission bits in %s: %v", addr, err) + } + fileMode = fs.FileMode(fileModeUInt64) + + // FileMode.String() returns a string like `-rwxr-xr--` for `u=rwx,g=rx,o=r` (`0754`) + if string(fileMode.String()[2]) != "w" { + return "", 0, fmt.Errorf("owner of the socket requires '-w-' (write, octal: '2') permissions at least; got '%s' in %s", fileMode.String()[1:4], addr) + } + + return addrSplit[0], fileMode, nil + } + + // default to 0200 (symbolic: `u=w,g=,o=`) + // if no permission bits are specified + return addr, 0200, nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/listeners.go new/caddy-2.7.3/listeners.go --- old/caddy-2.7.2/listeners.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/listeners.go 2023-08-06 02:10:15.000000000 +0200 @@ -31,6 +31,7 @@ "syscall" "time" + "github.com/caddyserver/caddy/v2/internal" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" "go.uber.org/zap" @@ -157,7 +158,7 @@ // is independent of permissions bits if na.IsUnixNetwork() { var err error - address, unixFileMode, err = splitUnixSocketPermissionsBits(na.Host) + address, unixFileMode, err = internal.SplitUnixSocketPermissionsBits(na.Host) if err != nil { return nil, err } @@ -319,40 +320,6 @@ return strings.HasPrefix(netw, "unix") } -// Takes a unix socket address in the unusual "path|bits" format -// (e.g. /run/caddy.sock|0222) and tries to split it into -// socket path (host) and permissions bits (port). Colons (":") -// can't be used as separator, as socket paths on Windows may -// include a drive letter (e.g. `unix/c:\absolute\path.sock`). -// Permission bits will default to 0200 if none are specified. -// Throws an error, if the first carrying bit does not -// include write perms (e.g. `0422` or `022`). -// Symbolic permission representation (e.g. `u=w,g=w,o=w`) -// is not supported and will throw an error for now! -func splitUnixSocketPermissionsBits(addr string) (path string, fileMode fs.FileMode, err error) { - addrSplit := strings.SplitN(addr, "|", 2) - - if len(addrSplit) == 2 { - // parse octal permission bit string as uint32 - fileModeUInt64, err := strconv.ParseUint(addrSplit[1], 8, 32) - if err != nil { - return "", 0, fmt.Errorf("could not parse octal permission bits in %s: %v", addr, err) - } - fileMode = fs.FileMode(fileModeUInt64) - - // FileMode.String() returns a string like `-rwxr-xr--` for `u=rwx,g=rx,o=r` (`0754`) - if string(fileMode.String()[2]) != "w" { - return "", 0, fmt.Errorf("owner of the socket requires '-w-' (write, octal: '2') permissions at least; got '%s' in %s", fileMode.String()[1:4], addr) - } - - return addrSplit[0], fileMode, nil - } - - // default to 0200 (symbolic: `u=w,g=,o=`) - // if no permission bits are specified - return addr, 0200, nil -} - // ParseNetworkAddress parses addr into its individual // components. The input string is expected to be of // the form "network/host:port-range" where any part is @@ -377,7 +344,7 @@ network = defaultNetwork } if IsUnixNetwork(network) { - _, _, err := splitUnixSocketPermissionsBits(host) + _, _, err := internal.SplitUnixSocketPermissionsBits(host) return NetworkAddress{ Network: network, Host: host, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/listeners_test.go new/caddy-2.7.3/listeners_test.go --- old/caddy-2.7.2/listeners_test.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/listeners_test.go 2023-08-06 02:10:15.000000000 +0200 @@ -17,6 +17,8 @@ import ( "reflect" "testing" + + "github.com/caddyserver/caddy/v2/internal" ) func TestSplitNetworkAddress(t *testing.T) { @@ -634,7 +636,7 @@ expectErr: true, }, } { - actualPath, actualFileMode, err := splitUnixSocketPermissionsBits(tc.input) + actualPath, actualFileMode, err := internal.SplitUnixSocketPermissionsBits(tc.input) if tc.expectErr && err == nil { t.Errorf("Test %d: Expected error but got: %v", i, err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/modules/caddyhttp/fileserver/browse.html new/caddy-2.7.3/modules/caddyhttp/fileserver/browse.html --- old/caddy-2.7.2/modules/caddyhttp/fileserver/browse.html 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/modules/caddyhttp/fileserver/browse.html 2023-08-06 02:10:15.000000000 +0200 @@ -11,7 +11,7 @@ <path d="M9 7l4 0"></path> <path d="M9 11l4 0"></path> </svg> - {{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" ".bmp" ".heif" ".heic"}} + {{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" ".bmp" ".heif" ".heic" ".svg"}} {{- if eq .Tpl.Layout "grid"}} <img loading="lazy" src="{{html .Name}}"> {{- else}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/modules/caddyhttp/reverseproxy/addresses.go new/caddy-2.7.3/modules/caddyhttp/reverseproxy/addresses.go --- old/caddy-2.7.2/modules/caddyhttp/reverseproxy/addresses.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/modules/caddyhttp/reverseproxy/addresses.go 2023-08-06 02:10:15.000000000 +0200 @@ -23,11 +23,43 @@ "github.com/caddyserver/caddy/v2" ) +type parsedAddr struct { + network, scheme, host, port string + valid bool +} + +func (p parsedAddr) dialAddr() string { + if !p.valid { + return "" + } + // for simplest possible config, we only need to include + // the network portion if the user specified one + if p.network != "" { + return caddy.JoinNetworkAddress(p.network, p.host, p.port) + } + + // if the host is a placeholder, then we don't want to join with an empty port, + // because that would just append an extra ':' at the end of the address. + if p.port == "" && strings.Contains(p.host, "{") { + return p.host + } + return net.JoinHostPort(p.host, p.port) +} +func (p parsedAddr) rangedPort() bool { + return strings.Contains(p.port, "-") +} +func (p parsedAddr) replaceablePort() bool { + return strings.Contains(p.port, "{") && strings.Contains(p.port, "}") +} +func (p parsedAddr) isUnix() bool { + return caddy.IsUnixNetwork(p.network) +} + // parseUpstreamDialAddress parses configuration inputs for // the dial address, including support for a scheme in front // as a shortcut for the port number, and a network type, // for example 'unix' to dial a unix socket. -func parseUpstreamDialAddress(upstreamAddr string) (string, string, error) { +func parseUpstreamDialAddress(upstreamAddr string) (parsedAddr, error) { var network, scheme, host, port string if strings.Contains(upstreamAddr, "://") { @@ -35,7 +67,7 @@ // so we return a more user-friendly error message instead // to explain what to do instead if strings.Contains(upstreamAddr, "{") { - return "", "", fmt.Errorf("due to parsing difficulties, placeholders are not allowed when an upstream address contains a scheme") + return parsedAddr{}, fmt.Errorf("due to parsing difficulties, placeholders are not allowed when an upstream address contains a scheme") } toURL, err := url.Parse(upstreamAddr) @@ -46,19 +78,19 @@ if strings.Contains(err.Error(), "invalid port") && strings.Contains(err.Error(), "-") { index := strings.LastIndex(upstreamAddr, ":") if index == -1 { - return "", "", fmt.Errorf("parsing upstream URL: %v", err) + return parsedAddr{}, fmt.Errorf("parsing upstream URL: %v", err) } portRange := upstreamAddr[index+1:] if strings.Count(portRange, "-") != 1 { - return "", "", fmt.Errorf("parsing upstream URL: parse \"%v\": port range invalid: %v", upstreamAddr, portRange) + return parsedAddr{}, fmt.Errorf("parsing upstream URL: parse \"%v\": port range invalid: %v", upstreamAddr, portRange) } toURL, err = url.Parse(strings.ReplaceAll(upstreamAddr, portRange, "0")) if err != nil { - return "", "", fmt.Errorf("parsing upstream URL: %v", err) + return parsedAddr{}, fmt.Errorf("parsing upstream URL: %v", err) } port = portRange } else { - return "", "", fmt.Errorf("parsing upstream URL: %v", err) + return parsedAddr{}, fmt.Errorf("parsing upstream URL: %v", err) } } if port == "" { @@ -69,18 +101,18 @@ // a backend and proxying to it, so we cannot allow extra components // in backend URLs if toURL.Path != "" || toURL.RawQuery != "" || toURL.Fragment != "" { - return "", "", fmt.Errorf("for now, URLs for proxy upstreams only support scheme, host, and port components") + return parsedAddr{}, fmt.Errorf("for now, URLs for proxy upstreams only support scheme, host, and port components") } // ensure the port and scheme aren't in conflict if toURL.Scheme == "http" && port == "443" { - return "", "", fmt.Errorf("upstream address has conflicting scheme (http://) and port (:443, the HTTPS port)") + return parsedAddr{}, fmt.Errorf("upstream address has conflicting scheme (http://) and port (:443, the HTTPS port)") } if toURL.Scheme == "https" && port == "80" { - return "", "", fmt.Errorf("upstream address has conflicting scheme (https://) and port (:80, the HTTP port)") + return parsedAddr{}, fmt.Errorf("upstream address has conflicting scheme (https://) and port (:80, the HTTP port)") } if toURL.Scheme == "h2c" && port == "443" { - return "", "", fmt.Errorf("upstream address has conflicting scheme (h2c://) and port (:443, the HTTPS port)") + return parsedAddr{}, fmt.Errorf("upstream address has conflicting scheme (h2c://) and port (:443, the HTTPS port)") } // if port is missing, attempt to infer from scheme @@ -112,18 +144,5 @@ network = "unix" scheme = "h2c" } - - // for simplest possible config, we only need to include - // the network portion if the user specified one - if network != "" { - return caddy.JoinNetworkAddress(network, host, port), scheme, nil - } - - // if the host is a placeholder, then we don't want to join with an empty port, - // because that would just append an extra ':' at the end of the address. - if port == "" && strings.Contains(host, "{") { - return host, scheme, nil - } - - return net.JoinHostPort(host, port), scheme, nil + return parsedAddr{network, scheme, host, port, true}, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/modules/caddyhttp/reverseproxy/addresses_test.go new/caddy-2.7.3/modules/caddyhttp/reverseproxy/addresses_test.go --- old/caddy-2.7.2/modules/caddyhttp/reverseproxy/addresses_test.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/modules/caddyhttp/reverseproxy/addresses_test.go 2023-08-06 02:10:15.000000000 +0200 @@ -265,18 +265,18 @@ expectScheme: "h2c", }, } { - actualHostPort, actualScheme, err := parseUpstreamDialAddress(tc.input) + actualAddr, err := parseUpstreamDialAddress(tc.input) if tc.expectErr && err == nil { t.Errorf("Test %d: Expected error but got %v", i, err) } if !tc.expectErr && err != nil { t.Errorf("Test %d: Expected no error but got %v", i, err) } - if actualHostPort != tc.expectHostPort { - t.Errorf("Test %d: Expected host and port '%s' but got '%s'", i, tc.expectHostPort, actualHostPort) + if actualAddr.dialAddr() != tc.expectHostPort { + t.Errorf("Test %d: input %s: Expected host and port '%s' but got '%s'", i, tc.input, tc.expectHostPort, actualAddr.dialAddr()) } - if actualScheme != tc.expectScheme { - t.Errorf("Test %d: Expected scheme '%s' but got '%s'", i, tc.expectScheme, actualScheme) + if actualAddr.scheme != tc.expectScheme { + t.Errorf("Test %d: Expected scheme '%s' but got '%s'", i, tc.expectScheme, actualAddr.scheme) } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/modules/caddyhttp/reverseproxy/caddyfile.go new/caddy-2.7.3/modules/caddyhttp/reverseproxy/caddyfile.go --- old/caddy-2.7.2/modules/caddyhttp/reverseproxy/caddyfile.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/modules/caddyhttp/reverseproxy/caddyfile.go 2023-08-06 02:10:15.000000000 +0200 @@ -146,7 +146,7 @@ // appendUpstream creates an upstream for address and adds // it to the list. appendUpstream := func(address string) error { - dialAddr, scheme, err := parseUpstreamDialAddress(address) + pa, err := parseUpstreamDialAddress(address) if err != nil { return d.WrapErr(err) } @@ -154,21 +154,27 @@ // the underlying JSON does not yet support different // transports (protocols or schemes) to each backend, // so we remember the last one we see and compare them - if commonScheme != "" && scheme != commonScheme { + if commonScheme != "" && pa.scheme != commonScheme { return d.Errf("for now, all proxy upstreams must use the same scheme (transport protocol); expecting '%s://' but got '%s://'", - commonScheme, scheme) + commonScheme, pa.scheme) } - commonScheme = scheme + commonScheme = pa.scheme - parsedAddr, err := caddy.ParseNetworkAddress(dialAddr) + // if the port of upstream address contains a placeholder, only wrap it with the `Upstream` struct, + // delaying actual resolution of the address until request time. + if pa.replaceablePort() { + h.Upstreams = append(h.Upstreams, &Upstream{Dial: pa.dialAddr()}) + return nil + } + parsedAddr, err := caddy.ParseNetworkAddress(pa.dialAddr()) if err != nil { return d.WrapErr(err) } - if parsedAddr.StartPort == 0 && parsedAddr.EndPort == 0 { + if pa.isUnix() || !pa.rangedPort() { // unix networks don't have ports h.Upstreams = append(h.Upstreams, &Upstream{ - Dial: dialAddr, + Dial: pa.dialAddr(), }) } else { // expand a port range into multiple upstreams diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/caddy-2.7.2/modules/caddyhttp/reverseproxy/command.go new/caddy-2.7.3/modules/caddyhttp/reverseproxy/command.go --- old/caddy-2.7.2/modules/caddyhttp/reverseproxy/command.go 2023-08-03 06:08:12.000000000 +0200 +++ new/caddy-2.7.3/modules/caddyhttp/reverseproxy/command.go 2023-08-06 02:10:15.000000000 +0200 @@ -132,14 +132,14 @@ toAddresses := make([]string, len(to)) var toScheme string for i, toLoc := range to { - addr, scheme, err := parseUpstreamDialAddress(toLoc) + addr, err := parseUpstreamDialAddress(toLoc) if err != nil { return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", toLoc, err) } - if scheme != "" && toScheme == "" { - toScheme = scheme + if addr.scheme != "" && toScheme == "" { + toScheme = addr.scheme } - toAddresses[i] = addr + toAddresses[i] = addr.dialAddr() } // proceed to build the handler and server ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/caddy/vendor.tar.gz /work/SRC/openSUSE:Factory/.caddy.new.22712/vendor.tar.gz differ: char 5, line 1