Skip to content

Commit

Permalink
Merge branch 'master' into hurl-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammed90 committed Jun 6, 2024
2 parents 1b4bd3e + 243351b commit eb6934f
Show file tree
Hide file tree
Showing 81 changed files with 2,415 additions and 776 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Other menu items:

You can have a huge impact on the project by helping with its code. To contribute code to Caddy, first submit or comment in an issue to discuss your contribution, then open a [pull request](https://github.com/caddyserver/caddy/pulls) (PR). If you're new to our community, that's okay: **we gladly welcome pull requests from anyone, regardless of your native language or coding experience.** You can get familiar with Caddy's code base by using [code search at Sourcegraph](https://sourcegraph.com/github.com/caddyserver/caddy).

We hold contributions to a high standard for quality :bowtie:, so don't be surprised if we ask for revisions—even if it seems small or insignificant. Please don't take it personally. :blue_heart: If your change is on the right track, we can guide you to make it mergable.
We hold contributions to a high standard for quality :bowtie:, so don't be surprised if we ask for revisions—even if it seems small or insignificant. Please don't take it personally. :blue_heart: If your change is on the right track, we can guide you to make it mergeable.

Here are some of the expectations we have of contributors:

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
GO_SEMVER: '~1.21.0'

- go: '1.22'
GO_SEMVER: '~1.22.1'
GO_SEMVER: '~1.22.3'

# Set some variables per OS, usable via ${{ matrix.VAR }}
# OS_LABEL: the VM label from GitHub Actions (see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories)
Expand Down
8 changes: 1 addition & 7 deletions .github/workflows/cross-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ jobs:
matrix:
goos:
- 'aix'
- 'android'
- 'linux'
- 'solaris'
- 'illumos'
- 'dragonfly'
- 'freebsd'
- 'openbsd'
- 'plan9'
- 'windows'
- 'darwin'
- 'netbsd'
Expand All @@ -35,7 +33,7 @@ jobs:
# Set the minimum Go patch version for the given Go minor
# Usable via ${{ matrix.GO_SEMVER }}
- go: '1.22'
GO_SEMVER: '~1.22.1'
GO_SEMVER: '~1.22.3'

runs-on: ubuntu-latest
continue-on-error: true
Expand Down Expand Up @@ -69,7 +67,3 @@ jobs:
working-directory: ./cmd/caddy
run: |
GOOS=$GOOS GOARCH=$GOARCH go build -tags nobadger -trimpath -o caddy-"$GOOS"-$GOARCH 2> /dev/null
if [ $? -ne 0 ]; then
echo "::warning ::$GOOS Build Failed"
exit 0
fi
9 changes: 3 additions & 6 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,14 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '~1.22.1'
go-version: '~1.22.3'
check-latest: true

- name: golangci-lint
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v6
with:
version: v1.55

# Workaround for https://github.com/golangci/golangci-lint-action/issues/135
skip-pkg-cache: true

# Windows times out frequently after about 5m50s if we don't set a longer timeout.
args: --timeout 10m

Expand All @@ -66,5 +63,5 @@ jobs:
- name: govulncheck
uses: golang/govulncheck-action@v1
with:
go-version-input: '~1.22.1'
go-version-input: '~1.22.3'
check-latest: true
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
os:
- ubuntu-latest
go:
- '1.21'
- '1.22'

include:
# Set the minimum Go patch version for the given Go minor
# Usable via ${{ matrix.GO_SEMVER }}
- go: '1.21'
GO_SEMVER: '~1.21.0'
- go: '1.22'
GO_SEMVER: '~1.22.3'

runs-on: ${{ matrix.os }}
# https://github.com/sigstore/cosign/issues/1258#issuecomment-1002251233
Expand Down
2 changes: 1 addition & 1 deletion caddy.go
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ func InstanceID() (uuid.UUID, error) {
if err != nil {
return uuid, err
}
err = os.MkdirAll(appDataDir, 0o600)
err = os.MkdirAll(appDataDir, 0o700)
if err != nil {
return uuid, err
}
Expand Down
15 changes: 15 additions & 0 deletions caddyconfig/caddyfile/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ func (l *lexer) finalizeHeredoc(val []rune, marker string) ([]rune, error) {
return []rune(out), nil
}

// Quoted returns true if the token was enclosed in quotes
// (i.e. double quotes, backticks, or heredoc).
func (t Token) Quoted() bool {
return t.wasQuoted > 0
}
Expand All @@ -356,6 +358,19 @@ func (t Token) NumLineBreaks() int {
return lineBreaks
}

// Clone returns a deep copy of the token.
func (t Token) Clone() Token {
return Token{
File: t.File,
imports: append([]string{}, t.imports...),
Line: t.Line,
Text: t.Text,
wasQuoted: t.wasQuoted,
heredocMarker: t.heredocMarker,
snippetName: t.snippetName,
}
}

var heredocMarkerRegexp = regexp.MustCompile("^[A-Za-z0-9_-]+$")

// isNextOnNewLine tests whether t2 is on a different line from t1
Expand Down
8 changes: 6 additions & 2 deletions caddyconfig/caddyfile/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,12 @@ func (p *parser) addresses() error {
value := p.Val()
token := p.Token()

// special case: import directive replaces tokens during parse-time
// Reject request matchers if trying to define them globally
if strings.HasPrefix(value, "@") {
return p.Errf("request matchers may not be defined globally, they must be in a site block; found %s", value)
}

// Special case: import directive replaces tokens during parse-time
if value == "import" && p.isNewLine() {
err := p.doImport(0)
if err != nil {
Expand Down Expand Up @@ -395,7 +400,6 @@ func (p *parser) doImport(nesting int) error {
return p.Errf("Glob pattern may only contain one wildcard (*), but has others: %s", globPattern)
}
matches, err = filepath.Glob(globPattern)

if err != nil {
return p.Errf("Failed to use import pattern %s: %v", importPattern, err)
}
Expand Down
23 changes: 23 additions & 0 deletions caddyconfig/caddyfile/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,29 @@ func TestSnippetAcrossMultipleFiles(t *testing.T) {
}
}

func TestRejectsGlobalMatcher(t *testing.T) {
p := testParser(`
@rejected path /foo
(common) {
gzip foo
errors stderr
}
http://example.com {
import common
}
`)
_, err := p.parseAll()
if err == nil {
t.Fatal("Expected an error, but got nil")
}
expected := "request matchers may not be defined globally, they must be in a site block; found @rejected, at Testfile:2"
if err.Error() != expected {
t.Errorf("Expected error to be '%s' but got '%v'", expected, err)
}
}

func testParser(input string) parser {
return parser{Dispenser: NewTestDispenser(input)}
}
24 changes: 20 additions & 4 deletions caddyconfig/httpcaddyfile/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func init() {
RegisterDirective("log", parseLog)
RegisterHandlerDirective("skip_log", parseLogSkip)
RegisterHandlerDirective("log_skip", parseLogSkip)
RegisterHandlerDirective("log_name", parseLogName)
}

// parseBind parses the bind directive. Syntax:
Expand All @@ -69,8 +70,7 @@ func parseBind(h Helper) ([]ConfigValue, error) {
// curves <curves...>
// client_auth {
// mode [request|require|verify_if_given|require_and_verify]
// trusted_ca_cert <base64_der>
// trusted_ca_cert_file <filename>
// trust_pool <module_name> [...]
// trusted_leaf_cert <base64_der>
// trusted_leaf_cert_file <filename>
// }
Expand Down Expand Up @@ -915,7 +915,7 @@ func parseLogHelper(h Helper, globalLogNames map[string]struct{}) ([]ConfigValue
// this is useful for setting up loggers per subdomain in a site block
// with a wildcard domain
customHostnames := []string{}

noHostname := false
for h.NextBlock(0) {
switch h.Val() {
case "hostnames":
Expand Down Expand Up @@ -1001,14 +1001,20 @@ func parseLogHelper(h Helper, globalLogNames map[string]struct{}) ([]ConfigValue
cl.Exclude = append(cl.Exclude, h.Val())
}

case "no_hostname":
if h.NextArg() {
return nil, h.ArgErr()
}
noHostname = true

default:
return nil, h.Errf("unrecognized subdirective: %s", h.Val())
}
}

var val namedCustomLog
val.hostnames = customHostnames

val.noHostname = noHostname
isEmptyConfig := reflect.DeepEqual(cl, new(caddy.CustomLog))

// Skip handling of empty logging configs
Expand Down Expand Up @@ -1059,3 +1065,13 @@ func parseLogSkip(h Helper) (caddyhttp.MiddlewareHandler, error) {
}
return caddyhttp.VarsMiddleware{"log_skip": true}, nil
}

// parseLogName parses the log_name directive. Syntax:
//
// log_name <names...>
func parseLogName(h Helper) (caddyhttp.MiddlewareHandler, error) {
h.Next() // consume directive name
return caddyhttp.VarsMiddleware{
caddyhttp.AccessLoggerNameVarKey: h.RemainingArgs(),
}, nil
}
2 changes: 2 additions & 0 deletions caddyconfig/httpcaddyfile/directives.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ var defaultDirectiveOrder = []string{
"log_append",
"skip_log", // TODO: deprecated, renamed to log_skip
"log_skip",
"log_name",

"header",
"copy_response_headers", // only in reverse_proxy's handle_response
Expand All @@ -73,6 +74,7 @@ var defaultDirectiveOrder = []string{
"request_header",
"encode",
"push",
"intercept",
"templates",

// special routing & dispatching directives
Expand Down
41 changes: 29 additions & 12 deletions caddyconfig/httpcaddyfile/httptype.go
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,15 @@ func (st *ServerType) serversFromPairings(
sblockLogHosts := sblock.hostsFromKeys(true)
for _, cval := range sblock.pile["custom_log"] {
ncl := cval.Value.(namedCustomLog)

// if `no_hostname` is set, then this logger will not
// be associated with any of the site block's hostnames,
// and only be usable via the `log_name` directive
// or the `access_logger_names` variable
if ncl.noHostname {
continue
}

if sblock.hasHostCatchAllKey() && len(ncl.hostnames) == 0 {
// all requests for hosts not able to be listed should use
// this log because it's a catch-all-hosts server block
Expand Down Expand Up @@ -1282,19 +1291,24 @@ func matcherSetFromMatcherToken(
if tkn.Text == "*" {
// match all requests == no matchers, so nothing to do
return nil, true, nil
} else if strings.HasPrefix(tkn.Text, "/") {
// convenient way to specify a single path match
}

// convenient way to specify a single path match
if strings.HasPrefix(tkn.Text, "/") {
return caddy.ModuleMap{
"path": caddyconfig.JSON(caddyhttp.MatchPath{tkn.Text}, warnings),
}, true, nil
} else if strings.HasPrefix(tkn.Text, matcherPrefix) {
// pre-defined matcher
}

// pre-defined matcher
if strings.HasPrefix(tkn.Text, matcherPrefix) {
m, ok := matcherDefs[tkn.Text]
if !ok {
return nil, false, fmt.Errorf("unrecognized matcher name: %+v", tkn.Text)
}
return m, true, nil
}

return nil, false, nil
}

Expand Down Expand Up @@ -1430,11 +1444,13 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
if d.NextArg() {
if d.Token().Quoted() {
// since it was missing the matcher name, we insert a token
// in front of the expression token itself
err := makeMatcher("expression", []caddyfile.Token{
{Text: "expression", File: d.File(), Line: d.Line()},
d.Token(),
})
// in front of the expression token itself; we use Clone() to
// make the new token to keep the same the import location as
// the next token, if this is within a snippet or imported file.
// see https://github.com/caddyserver/caddy/issues/6287
expressionToken := d.Token().Clone()
expressionToken.Text = "expression"
err := makeMatcher("expression", []caddyfile.Token{expressionToken, d.Token()})
if err != nil {
return err
}
Expand Down Expand Up @@ -1591,9 +1607,10 @@ func (c counter) nextGroup() string {
}

type namedCustomLog struct {
name string
hostnames []string
log *caddy.CustomLog
name string
hostnames []string
log *caddy.CustomLog
noHostname bool
}

// sbAddrAssociation is a mapping from a list of
Expand Down
26 changes: 26 additions & 0 deletions caddyconfig/httpcaddyfile/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func init() {
RegisterGlobalOption("auto_https", parseOptAutoHTTPS)
RegisterGlobalOption("servers", parseServerOptions)
RegisterGlobalOption("ocsp_stapling", parseOCSPStaplingOptions)
RegisterGlobalOption("cert_lifetime", parseOptDuration)
RegisterGlobalOption("log", parseLogOptions)
RegisterGlobalOption("preferred_chains", parseOptPreferredChains)
RegisterGlobalOption("persist_config", parseOptPersistConfig)
Expand Down Expand Up @@ -345,9 +346,34 @@ func parseOptOnDemand(d *caddyfile.Dispenser, _ any) (any, error) {
if ond == nil {
ond = new(caddytls.OnDemandConfig)
}
if ond.PermissionRaw != nil {
return nil, d.Err("on-demand TLS permission module (or 'ask') already specified")
}
perm := caddytls.PermissionByHTTP{Endpoint: d.Val()}
ond.PermissionRaw = caddyconfig.JSONModuleObject(perm, "module", "http", nil)

case "permission":
if !d.NextArg() {
return nil, d.ArgErr()
}
if ond == nil {
ond = new(caddytls.OnDemandConfig)
}
if ond.PermissionRaw != nil {
return nil, d.Err("on-demand TLS permission module (or 'ask') already specified")
}
modName := d.Val()
modID := "tls.permission." + modName
unm, err := caddyfile.UnmarshalModule(d, modID)
if err != nil {
return nil, err
}
perm, ok := unm.(caddytls.OnDemandPermission)
if !ok {
return nil, d.Errf("module %s (%T) is not an on-demand TLS permission module", modID, unm)
}
ond.PermissionRaw = caddyconfig.JSONModuleObject(perm, "module", modName, nil)

case "interval":
if !d.NextArg() {
return nil, d.ArgErr()
Expand Down
Loading

0 comments on commit eb6934f

Please sign in to comment.