Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit f81f187

Browse files
committed
Support empty environment variables to simulate Apache behavior
1 parent 752cfba commit f81f187

File tree

11 files changed

+98
-18
lines changed

11 files changed

+98
-18
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ looks like this:
163163
exec script [args...]
164164
env key1=val1 [key2=val2...]
165165
pass_env key1 [key2...]
166+
empty_env key1 [key2...]
166167
}
167168

168169
For example,
@@ -173,17 +174,24 @@ For example,
173174
exec /usr/local/cgi-bin/phpwrap /usr/local/cgi-bin{match}
174175
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
175176
pass_env HOME UID
177+
empty_env CGI_LOCAL
176178
}
177179

178180
With the advanced syntax, the `exec` subdirective must appear exactly once. The
179-
`match` subdirective must appear at least once. The `env`, `pass_env`, and
180-
`except` subdirectives can appear any reasonable number of times.
181+
`match` subdirective must appear at least once. The `env`, `pass_env`,
182+
`empty_env`, and `except` subdirectives can appear any reasonable number of
183+
times.
181184

182185
The `except` subdirective uses the same pattern matching logic that is used
183186
with the `match` subdirective. Any request that matches a `match` pattern is
184187
then checked with the patterns in `except`, if any. If any matches are made
185188
with the `except` pattern, the request is rejected.
186189

190+
The empty_env subdirective is used to pass one or more empty environment
191+
variables. Some CGI scripts may expect the server to pass certain empty
192+
variables rather than leaving them unset. This subdirective allows you to deal
193+
with those situations.
194+
187195
The values associated with environment variable keys are all subject to
188196
placeholder substitution, just as with the script name and arguments.
189197

cgi.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ func setupCall(h handlerType, rule ruleType, lfStr, rtStr string,
8989
for _, env := range rule.envs {
9090
envAdd(env[0], env[1])
9191
}
92+
for _, env := range rule.emptyEnvs {
93+
cgiHnd.Env = append(cgiHnd.Env, env+"=")
94+
}
9295
envAdd("PATH_INFO", rtStr)
9396
envAdd("SCRIPT_FILENAME", cgiHnd.Path)
9497
envAdd("SCRIPT_NAME", lfStr)

cgi_test.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func TestServe(t *testing.T) {
5555
except /servertime/1934
5656
exec {.}/test/example --example
5757
env CGI_GLOBAL=12
58+
empty_env CGI_LOCAL
5859
}`,
5960
}
6061

@@ -69,31 +70,56 @@ func TestServe(t *testing.T) {
6970
cgi /servertime {.}/test/example
7071
--- Request /servertime ---
7172
code [0], error [example error message]
72-
[---] [---] [---] [quixote] [] []
73+
PATH_INFO []
74+
CGI_GLOBAL []
75+
Arg 1 []
76+
QUERY_STRING []
77+
HTTP_TOKEN_CLAIM_USER [quixote]
78+
CGI_LOCAL is unset
7379
--- Request /servertime/1930/05/11?name=Edsger%20W.%20Dijkstra ---
7480
code [0], error [example error message]
75-
[/1930/05/11] [---] [---] [---] [name=Edsger%20W.%20Dijkstra] [quixote]
81+
PATH_INFO [/1930/05/11]
82+
CGI_GLOBAL []
83+
Arg 1 []
84+
QUERY_STRING [name=Edsger%20W.%20Dijkstra]
85+
HTTP_TOKEN_CLAIM_USER [quixote]
86+
CGI_LOCAL is unset
7687
--- Request /servertime/1934/02/15?name=Niklaus%20Wirth ---
7788
code [0], error [example error message]
78-
[/1934/02/15] [---] [---] [---] [name=Niklaus%20Wirth] [quixote]
89+
PATH_INFO [/1934/02/15]
90+
CGI_GLOBAL []
91+
Arg 1 []
92+
QUERY_STRING [name=Niklaus%20Wirth]
93+
HTTP_TOKEN_CLAIM_USER [quixote]
94+
CGI_LOCAL is unset
7995
--- Request /example.txt ---
8096
=== Directive 1 ===
8197
cgi {
8298
match /servertime
8399
except /servertime/1934
84100
exec {.}/test/example --example
85101
env CGI_GLOBAL=12
102+
empty_env CGI_LOCAL
86103
}
87104
--- Request /servertime ---
88105
code [0], error [example error message]
89-
[---] [12] [--example] [quixote] [] []
106+
PATH_INFO []
107+
CGI_GLOBAL [12]
108+
Arg 1 [--example]
109+
QUERY_STRING []
110+
HTTP_TOKEN_CLAIM_USER [quixote]
111+
CGI_LOCAL is set to []
90112
--- Request /servertime/1930/05/11?name=Edsger%20W.%20Dijkstra ---
91113
code [0], error [example error message]
92-
[/1930/05/11] [---] [12] [--example] [name=Edsger%20W.%20Dijkstra] [quixote]
114+
PATH_INFO [/1930/05/11]
115+
CGI_GLOBAL [12]
116+
Arg 1 [--example]
117+
QUERY_STRING [name=Edsger%20W.%20Dijkstra]
118+
HTTP_TOKEN_CLAIM_USER [quixote]
119+
CGI_LOCAL is set to []
93120
--- Request /servertime/1934/02/15?name=Niklaus%20Wirth ---
94121
--- Request /example.txt ---
95122
`
96-
97123
// Testing the ServeHTTP method requires OS-specific CGI scripts, because a
98124
// system call is made to respond to the request.
99125
if runtime.GOOS == "linux" || runtime.GOOS == "darwin" {

def.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ type ruleType struct {
2626
envs [][2]string // [0..n]
2727
// Environment keys to pass through for all apps
2828
passEnvs []string // [0..n]
29+
// Environment keys to send with empty values
30+
emptyEnvs []string // [0..n]
2931
}

doc.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ looks like this:
160160
exec script [args...]
161161
env key1=val1 [key2=val2...]
162162
pass_env key1 [key2...]
163+
empty_env key1 [key2...]
163164
}
164165
165166
For example,
@@ -170,17 +171,24 @@ For example,
170171
exec /usr/local/cgi-bin/phpwrap /usr/local/cgi-bin{match}
171172
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
172173
pass_env HOME UID
174+
empty_env CGI_LOCAL
173175
}
174176
175177
With the advanced syntax, the exec subdirective must appear exactly once. The
176-
match subdirective must appear at least once. The env, pass_env, and
177-
except subdirectives can appear any reasonable number of times.
178+
match subdirective must appear at least once. The env, pass_env,
179+
empty_env, and except subdirectives can appear any reasonable number of
180+
times.
178181
179182
The except subdirective uses the same pattern matching logic that is used
180183
with the match subdirective. Any request that matches a match pattern is
181184
then checked with the patterns in except, if any. If any matches are made
182185
with the except pattern, the request is rejected.
183186
187+
The empty_env subdirective is used to pass one or more empty environment
188+
variables. Some CGI scripts may expect the server to pass certain empty
189+
variables rather than leaving them unset. This subdirective allows you to deal
190+
with those situations.
191+
184192
The values associated with environment variable keys are all subject to
185193
placeholder substitution, just as with the script name and arguments.
186194

doc/cgi.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ looks like this:
166166
> [exec][key] [script [args...]][subkey]
167167
> [env][key] [key1=val1 [key2=val2...]][subkey]
168168
> [pass_env][key] [key1 [key2...]][subkey]
169+
> [empty_env][key] [key1 [key2...]][subkey]
169170
> }
170171
171172
For example,
@@ -176,17 +177,24 @@ For example,
176177
exec /usr/local/cgi-bin/phpwrap /usr/local/cgi-bin{match}
177178
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
178179
pass_env HOME UID
180+
empty_env CGI_LOCAL
179181
}
180182

181183
With the advanced syntax, the `exec` subdirective must appear exactly once. The
182-
`match` subdirective must appear at least once. The `env`, `pass_env`, and
183-
`except` subdirectives can appear any reasonable number of times.
184+
`match` subdirective must appear at least once. The `env`, `pass_env`,
185+
`empty_env`, and `except` subdirectives can appear any reasonable number of
186+
times.
184187

185188
The `except` subdirective uses the same pattern matching logic that is used
186189
with the `match` subdirective. Any request that matches a `match` pattern is
187190
then checked with the patterns in `except`, if any. If any matches are made
188191
with the `except` pattern, the request is rejected.
189192

193+
The empty_env subdirective is used to pass one or more empty environment
194+
variables. Some CGI scripts may expect the server to pass certain empty
195+
variables rather than leaving them unset. This subdirective allows you to deal
196+
with those situations.
197+
190198
The values associated with environment variable keys are all subject to
191199
placeholder substitution, just as with the script name and arguments.
192200

doc/doc.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ looks like this:
195195
> [exec][key] [script [args...]][subkey]
196196
> [env][key] [key1=val1 [key2=val2...]][subkey]
197197
> [pass_env][key] [key1 [key2...]][subkey]
198+
> [empty_env][key] [key1 [key2...]][subkey]
198199
> }
199200
~rg~
200201
cgi {
@@ -203,6 +204,7 @@ looks like this:
203204
exec script [args...]
204205
env key1=val1 [key2=val2...]
205206
pass_env key1 [key2...]
207+
empty_env key1 [key2...]
206208
}
207209
~rgc~
208210

@@ -214,17 +216,24 @@ For example,
214216
exec /usr/local/cgi-bin/phpwrap /usr/local/cgi-bin{match}
215217
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
216218
pass_env HOME UID
219+
empty_env CGI_LOCAL
217220
}
218221

219222
With the advanced syntax, the `exec` subdirective must appear exactly once. The
220-
`match` subdirective must appear at least once. The `env`, `pass_env`, and
221-
`except` subdirectives can appear any reasonable number of times.
223+
`match` subdirective must appear at least once. The `env`, `pass_env`,
224+
`empty_env`, and `except` subdirectives can appear any reasonable number of
225+
times.
222226

223227
The `except` subdirective uses the same pattern matching logic that is used
224228
with the `match` subdirective. Any request that matches a `match` pattern is
225229
then checked with the patterns in `except`, if any. If any matches are made
226230
with the `except` pattern, the request is rejected.
227231

232+
The empty_env subdirective is used to pass one or more empty environment
233+
variables. Some CGI scripts may expect the server to pass certain empty
234+
variables rather than leaving them unset. This subdirective allows you to deal
235+
with those situations.
236+
228237
The values associated with environment variable keys are all subject to
229238
placeholder substitution, just as with the script name and arguments.
230239

setup.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017 Kurt Jung (Gmail: kurt.w.jung)
2+
* Copyright (c) 2017-2018 Kurt Jung (Gmail: kurt.w.jung)
33
*
44
* Permission to use, copy, modify, and distribute this software for any
55
* purpose with or without fee is hereby granted, provided that the above
@@ -120,14 +120,16 @@ func parseBlock(c *caddy.Controller) (rule ruleType, err error) {
120120
switch val {
121121
case "match": // [1..n]
122122
err = parseMatch(&rule, args)
123-
case "except":
123+
case "except": // [0..n]
124124
err = parseExcept(&rule, args)
125125
case "exec": // [1]
126126
err = parseExec(&rule, args)
127127
case "env": // [0..n]
128128
err = parseEnv(&rule.envs, args)
129129
case "pass_env": // [0..n]
130130
rule.passEnvs = append(rule.passEnvs, args...)
131+
case "empty_env": // [0..n]
132+
rule.emptyEnvs = append(rule.emptyEnvs, args...)
131133
case "}":
132134
loop = false
133135
}

setup_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func Example_rule() {
5757
except utility.lua
5858
exec /usr/bin/lua /usr/local/cgi-bin/{match}
5959
pass_env LUA_PATH LUA_CPATH
60+
empty_env REMOTE_USER CONTENT_TYPE
6061
}`,
6162
`cgi {
6263
match *.py *.pyc
@@ -91,6 +92,8 @@ func Example_rule() {
9192
// Arg 0: /usr/local/cgi-bin/{match}
9293
// Pass env 0: LUA_PATH
9394
// Pass env 1: LUA_CPATH
95+
// Empty env 0: REMOTE_USER
96+
// Empty env 1: CONTENT_TYPE
9497
// Rule 0
9598
// Match 0: *.py
9699
// Match 1: *.pyc

test/example

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
#!/bin/bash
22

33
printf "Content-type: text/plain\n\n"
4-
printf "[%s] [%s] [%s] [%s] [%s] [%s]\n" ${PATH_INFO----} ${CGI_LOCAL----} \
5-
${CGI_GLOBAL----} ${1----} ${QUERY_STRING----} ${HTTP_TOKEN_CLAIM_USER----}
4+
printf "PATH_INFO [%s]\n" ${PATH_INFO}
5+
printf "CGI_GLOBAL [%s]\n" ${CGI_GLOBAL}
6+
printf "Arg 1 [%s]\n" ${1}
7+
printf "QUERY_STRING [%s]\n" ${QUERY_STRING}
8+
printf "HTTP_TOKEN_CLAIM_USER [%s]\n" ${HTTP_TOKEN_CLAIM_USER}
9+
if [ -z ${CGI_LOCAL+x} ]; then
10+
printf "CGI_LOCAL is unset\n"
11+
else
12+
printf "CGI_LOCAL is set to [%s]\n" ${CGI_LOCAL}
13+
fi
614
printf "example error message\n" > /dev/stderr
715
exit 0

0 commit comments

Comments
 (0)