fix(caddy): incorrectly prepared environment variables when not using Caddyfile

This commit is contained in:
Kévin Dunglas
2024-06-23 09:42:06 +02:00
parent 549239d16f
commit e45a788824
4 changed files with 101 additions and 10 deletions

View File

@@ -210,8 +210,10 @@ type FrankenPHPModule struct {
// ResolveRootSymlink enables resolving the `root` directory to its actual value by evaluating a symbolic link, if one exists.
ResolveRootSymlink *bool `json:"resolve_root_symlink,omitempty"`
// Env sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables.
Env frankenphp.PreparedEnv `json:"env,omitempty"`
logger *zap.Logger
Env map[string]string `json:"env,omitempty"`
preparedEnv frankenphp.PreparedEnv
logger *zap.Logger
}
// CaddyModule returns the Caddy module information.
@@ -249,6 +251,10 @@ func (f *FrankenPHPModule) Provision(ctx caddy.Context) error {
f.ResolveRootSymlink = &rrs
}
if f.preparedEnv == nil {
f.preparedEnv = frankenphp.PrepareEnv(f.Env)
}
return nil
}
@@ -260,9 +266,9 @@ func (f FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ ca
documentRoot := repl.ReplaceKnown(f.Root, "")
env := make(map[string]string, len(f.Env)+1)
env := make(map[string]string, len(f.preparedEnv)+1)
env["REQUEST_URI\x00"] = origReq.URL.RequestURI()
for k, v := range f.Env {
for k, v := range f.preparedEnv {
env[k] = repl.ReplaceKnown(v, "")
}
@@ -303,9 +309,11 @@ func (f *FrankenPHPModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return d.ArgErr()
}
if f.Env == nil {
f.Env = make(frankenphp.PreparedEnv)
f.Env = make(map[string]string)
f.preparedEnv = make(frankenphp.PreparedEnv)
}
f.Env[args[0]+"\x00"] = args[1]
f.Env[args[0]] = args[1]
f.preparedEnv[args[0]+"\x00"] = args[1]
case "resolve_root_symlink":
if d.NextArg() {

View File

@@ -120,7 +120,7 @@ func TestEnv(t *testing.T) {
frankenphp {
worker {
file ../testdata/env.php
file ../testdata/worker-env.php
num 1
env FOO bar
}
@@ -137,7 +137,90 @@ func TestEnv(t *testing.T) {
}
`, "caddyfile")
tester.AssertGetResponse("http://localhost:9080/env.php", http.StatusOK, "bazbar")
tester.AssertGetResponse("http://localhost:9080/worker-env.php", http.StatusOK, "bazbar")
}
func TestJsonEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
{
"admin": {
"listen": "localhost:2999"
},
"apps": {
"frankenphp": {
"workers": [
{
"env": {
"FOO": "bar"
},
"file_name": "../testdata/worker-env.php",
"num": 1
}
]
},
"http": {
"http_port": 9080,
"https_port": 9443,
"servers": {
"srv0": {
"listen": [
":9080"
],
"routes": [
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"env": {
"FOO": "baz"
},
"handler": "php",
"root": "../testdata"
}
]
}
]
}
]
}
]
}
],
"match": [
{
"host": [
"localhost"
]
}
],
"terminal": true
}
]
}
}
},
"pki": {
"certificate_authorities": {
"local": {
"install_trust": false
}
}
}
}
}
`, "json")
tester.AssertGetResponse("http://localhost:9080/worker-env.php", http.StatusOK, "bazbar")
}
func TestPHPServerDirective(t *testing.T) {

View File

@@ -80,7 +80,7 @@ func TestCannotCallHandleRequestInNonWorkerMode(t *testing.T) {
func TestWorkerEnv(t *testing.T) {
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/env.php?i=%d", i), nil)
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/worker-env.php?i=%d", i), nil)
w := httptest.NewRecorder()
handler(w, req)
@@ -88,7 +88,7 @@ func TestWorkerEnv(t *testing.T) {
body, _ := io.ReadAll(resp.Body)
assert.Equal(t, fmt.Sprintf("bar%d", i), string(body))
}, &testOptions{workerScript: "env.php", nbWorkers: 1, env: map[string]string{"FOO": "bar"}, nbParrallelRequests: 10})
}, &testOptions{workerScript: "worker-env.php", nbWorkers: 1, env: map[string]string{"FOO": "bar"}, nbParrallelRequests: 10})
}
func TestWorkerGetOpt(t *testing.T) {