Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions caddy/caddy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,6 @@ func TestMetrics(t *testing.T) {
mercure {
transport local
anonymous
publisher_jwt !ChangeMe!
}

php {
Expand All @@ -707,7 +706,6 @@ func TestMetrics(t *testing.T) {
mercure {
transport local
anonymous
publisher_jwt !ChangeMe!
}

php {
Expand Down
18 changes: 14 additions & 4 deletions caddy/frankenphp/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,20 @@

# Uncomment the following lines to enable Mercure and Vulcain modules
#mercure {
# # Publisher JWT key
# publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# # Subscriber JWT key
# subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# # Trusted issuer: binds the iss claim access tokens must carry to its keys.
# # The localhost default suits local development only: in production, set
# # MERCURE_TRUSTED_ISSUERS to the stable identifier of your token issuer
# # (your app's URL for self-issued tokens).
# issuer {$MERCURE_TRUSTED_ISSUERS:https://localhost} {
# # Publisher JWT key
# publisher {
# jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# }
# # Subscriber JWT key
# subscriber {
# jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# }
# }
# # Allow anonymous subscribers (double-check that it's what you want)
# anonymous
# # Enable the subscription API (double-check that it's what you want)
Expand Down
8 changes: 5 additions & 3 deletions caddy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ require (
github.com/caddyserver/certmagic v0.25.4
github.com/dunglas/caddy-cbrotli v1.0.1
github.com/dunglas/frankenphp v1.12.7
github.com/dunglas/mercure v0.24.2
github.com/dunglas/mercure/caddy v0.24.2
github.com/dunglas/mercure v1.0.0-alpha.3
github.com/dunglas/mercure/caddy v1.0.0-alpha.3
github.com/dunglas/vulcain/caddy v1.4.2
github.com/prometheus/client_golang v1.24.1
github.com/spf13/cobra v1.10.2
Expand Down Expand Up @@ -60,6 +60,7 @@ require (
github.com/dgraph-io/ristretto v0.2.0 // indirect
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/dlclark/regexp2/v2 v2.1.1 // indirect
github.com/dunglas/go-urlpattern v0.0.0-20260716093037-fb05c4998526 // indirect
github.com/dunglas/httpsfv v1.1.0 // indirect
github.com/dunglas/skipfilter v1.0.0 // indirect
github.com/dunglas/vulcain v1.4.2 // indirect
Expand Down Expand Up @@ -117,6 +118,7 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nlnwa/whatwg-url v0.6.2 // indirect
github.com/oasdiff/yaml v0.1.0 // indirect
github.com/oasdiff/yaml3 v0.0.13 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
Expand Down Expand Up @@ -214,7 +216,7 @@ require (
google.golang.org/api v0.283.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc v1.81.1 // indirect
google.golang.org/grpc v1.82.1 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
17 changes: 17 additions & 0 deletions caddy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI=
github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bits-and-blooms/bitset v1.24.6 h1:qcrftZUVBIwfs+m+nhoCBAPT+ZPZZjti8SbHbDQQkZ4=
github.com/bits-and-blooms/bitset v1.24.6/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/caddyserver/caddy/v2 v2.11.4 h1:XKxkMTgNSizEvKG6QHue6cAsFOteU2qA61w2tKkCWi0=
Expand Down Expand Up @@ -152,12 +153,18 @@ github.com/dlclark/regexp2/v2 v2.1.1 h1:LCUGyd9Wf+r+VVOl8Ny38JTpWJcAsdVnCIuhhtth
github.com/dlclark/regexp2/v2 v2.1.1/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
github.com/dunglas/caddy-cbrotli v1.0.1 h1:mkg7EB1GmoyfBt3kY3mq4o/0bfnBeq7ZLQjmVmdBE3Y=
github.com/dunglas/caddy-cbrotli v1.0.1/go.mod h1:uXABy3tjy1FABF+3JWKVh1ajFvIO/kfpwHaeZGSBaAY=
github.com/dunglas/go-urlpattern v0.0.0-20260716093037-fb05c4998526 h1:biCci7wlx/ChMqOkoUw6FPrhEZYRpulBZ+fO4Geo5Xs=
github.com/dunglas/go-urlpattern v0.0.0-20260716093037-fb05c4998526/go.mod h1:9qyjDljBPOWyWCGz7vo3Ek7cdnoG/DVk0Ucle7gWVS8=
github.com/dunglas/httpsfv v1.1.0 h1:Jw76nAyKWKZKFrpMMcL76y35tOpYHqQPzHQiwDvpe54=
github.com/dunglas/httpsfv v1.1.0/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
github.com/dunglas/mercure v0.24.2 h1:0uKT5XR/tkaGWhwUlXqjWek/0w+dY1n8HEY9Q8YB0hw=
github.com/dunglas/mercure v0.24.2/go.mod h1:BAaiHFKr5+rS5SUP1tJBRXlCjPWZmzy1n0BDlVJnWzY=
github.com/dunglas/mercure v1.0.0-alpha.3 h1:e+u4JpBTMNv0sd3igwSo5RzqSVWuo3E6HOMonhfTP94=
github.com/dunglas/mercure v1.0.0-alpha.3/go.mod h1:7i/xv2fXgCRgoJe/Yj+FYY7YV4VdMGkCpFNJEfFfqCo=
github.com/dunglas/mercure/caddy v0.24.2 h1:QjdJXvyJQaOtrt/LSk4QoCdFmRbyTVMl72bqmAGFPxw=
github.com/dunglas/mercure/caddy v0.24.2/go.mod h1:9e8vEukfn1eq0iHCsBwWWSsHBlNt660L2wUsisnOOWM=
github.com/dunglas/mercure/caddy v1.0.0-alpha.3 h1:l5cfLXIjKsZqNsMYYnYUwk3QYFMxDWb06P9HOn/HL64=
github.com/dunglas/mercure/caddy v1.0.0-alpha.3/go.mod h1:jm1xTnsY4vY20Rc4dDYZI2MNY+IaVQmi5opHWOiuUgs=
github.com/dunglas/skipfilter v1.0.0 h1:JG9SgGg4n6BlFwuTYzb9RIqjH7PfwszvWehanrYWPF4=
github.com/dunglas/skipfilter v1.0.0/go.mod h1:ryhr8j7CAHSjzeN7wI6YEuwoArQ3OQmRqWWVCEAfb9w=
github.com/dunglas/vulcain v1.4.2 h1:Y5iOA/wq8TJuxBPg9tIbTjgoaCrK0hqOETOb3WN1a8U=
Expand Down Expand Up @@ -313,6 +320,8 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nlnwa/whatwg-url v0.6.2 h1:jU61lU2ig4LANydbEJmA2nPrtCGiKdtgT0rmMd2VZ/Q=
github.com/nlnwa/whatwg-url v0.6.2/go.mod h1:x0FPXJzzOEieQtsBT/AKvbiBbQ46YlL6Xa7m02M1ECk=
github.com/oasdiff/yaml v0.1.0 h1:0bqZjfKc/8S9urj4JuwepX41WX9EoA6ifhU3SV06cXg=
github.com/oasdiff/yaml v0.1.0/go.mod h1:kOlRmMdL2X3vucLCEQO5u61SU22RysnfXvcttrZA1O0=
github.com/oasdiff/yaml3 v0.0.13 h1:06svmvOHOVBqF81+sY2EUScvUI/iS/vl2VIeUUxZQwg=
Expand Down Expand Up @@ -551,6 +560,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
Expand All @@ -573,6 +583,7 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
Expand All @@ -583,6 +594,7 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
Expand All @@ -600,6 +612,7 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
Expand All @@ -611,6 +624,7 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
Expand All @@ -622,6 +636,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
Expand All @@ -648,6 +663,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 h1:rgSNvqscFZ1JgV/4wH5GOsZFSFkR2Eua9As3KIr2LlM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2/go.mod h1:iMEtFwDlAhjDU9L5mY6U1XLwlIId/G3h+QcBHDIvrJ8=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
Expand Down
4 changes: 3 additions & 1 deletion caddy/hotreload.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ func (f *FrankenPHPModule) configureHotReload(app *FrankenPHPApp) error {
}

app.opts = append(app.opts, frankenphp.WithHotReload(f.HotReload.Topic, f.mercureHub, f.HotReload.Watch))
f.preparedEnv["FRANKENPHP_HOT_RELOAD\x00"] = "/.well-known/mercure?topic=" + url.QueryEscape(f.HotReload.Topic)
// "match" is the exact topic matcher of the Mercure protocol, the "topic"
// parameter it replaces is only honored in compatibility mode.
f.preparedEnv["FRANKENPHP_HOT_RELOAD\x00"] = "/.well-known/mercure?match=" + url.QueryEscape(f.HotReload.Topic)

return nil
}
Expand Down
3 changes: 1 addition & 2 deletions caddy/hotreload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
func TestHotReload(t *testing.T) {
const topic = "https://frankenphp.dev/hot-reload/test"

u := "/.well-known/mercure?topic=" + url.QueryEscape(topic)
u := "/.well-known/mercure?match=" + url.QueryEscape(topic)

tmpDir := t.TempDir()
indexFile := filepath.Join(tmpDir, "index.php")
Expand All @@ -40,7 +40,6 @@ func TestHotReload(t *testing.T) {
http://localhost:`+testPort+` {
mercure {
transport local
subscriber_jwt TestKey
anonymous
}

Expand Down
30 changes: 23 additions & 7 deletions caddy/mercure.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,32 @@ func createMercureRoute() (caddyhttp.Route, error) {
return caddyhttp.Route{}, errors.New(`the "MERCURE_SUBSCRIBER_JWT_KEY" environment variable must be set to use the Mercure.rocks hub`)
}

// The protocol requires access tokens to name their issuer, so the keys are
// bound to one trusted issuer instead of being set globally.
issuer := os.Getenv("MERCURE_TRUSTED_ISSUERS")
if issuer == "" {
issuer = "https://localhost"
}

mercureRoute := caddyhttp.Route{
HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(
mercureCaddy.Mercure{
PublisherJWT: mercureCaddy.JWTConfig{
Alg: os.Getenv("MERCURE_PUBLISHER_JWT_ALG"),
Key: mercurePublisherJwtKey,
},
SubscriberJWT: mercureCaddy.JWTConfig{
Alg: os.Getenv("MERCURE_SUBSCRIBER_JWT_ALG"),
Key: mercureSubscriberJwtKey,
Issuers: []mercureCaddy.IssuerConfig{
{
Identifier: issuer,
Publisher: mercureCaddy.VerifierConfig{
JWT: mercureCaddy.JWTConfig{
Alg: os.Getenv("MERCURE_PUBLISHER_JWT_ALG"),
Key: mercurePublisherJwtKey,
},
},
Subscriber: mercureCaddy.VerifierConfig{
JWT: mercureCaddy.JWTConfig{
Alg: os.Getenv("MERCURE_SUBSCRIBER_JWT_ALG"),
Key: mercureSubscriberJwtKey,
},
},
},
},
},
"handler",
Expand Down
Loading
Loading