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

Commit 68f742b

Browse files
committed
Add "inspect" subdirective to examine CGI environment
1 parent fa58438 commit 68f742b

File tree

10 files changed

+432
-10
lines changed

10 files changed

+432
-10
lines changed

README.md

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,12 @@ With the advanced syntax, the `exec` subdirective must appear exactly once. The
183183
times.
184184

185185
The `except` subdirective uses the same pattern matching logic that is used
186-
with the `match` subdirective. Any request that matches a `match` pattern is
187-
then checked with the patterns in `except`, if any. If any matches are made
188-
with the `except` pattern, the request is rejected.
186+
with the `match` subdirective except that the request must match a rule fully;
187+
no request path prefix matching is performed. Any request that matches a
188+
`match` pattern is then checked with the patterns in `except`, if any. If any
189+
matches are made with the `except` pattern, the request is rejected and passed
190+
along to subsequent handlers. This is a convenient way to have static file
191+
resources served properly rather than being confused as CGI applications.
189192

190193
The `empty_env` subdirective is used to pass one or more empty environment
191194
variables. Some CGI scripts may expect the server to pass certain empty
@@ -221,6 +224,64 @@ will be available with the following environment variables
221224
All values are conveyed as strings, so some conversion may be necessary in your
222225
program. No placeholder substitutions are made on these values.
223226

227+
### Troubleshooting
228+
229+
If you run into unexpected results with the CGI plugin, you are able to examine
230+
the environment in which your CGI application runs. To enter inspection mode,
231+
add the subdirective `inspect` to your CGI configuration block. This is a
232+
development option that should not be used in production. When in inspection
233+
mode, the plugin will respond to matching requests with a page that displays
234+
variables of interest. In particular, it will show the replacement value of
235+
`{match}` and the environment variables to which your CGI application has
236+
access.
237+
238+
For example, consider this example CGI block:
239+
240+
cgi {
241+
match /wapp/*
242+
exec /usr/local/bin/wapptclsh /home/quixote/projects{match}.tcl
243+
pass_env HOME LANG
244+
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
245+
inspect
246+
}
247+
248+
When you request a matching URL, for example,
249+
250+
https://example.com/wapp/hello.tcl
251+
252+
the Caddy server will deliver a text page similar to the following. The CGI
253+
application (in this case, wapptclsh) will not be called.
254+
255+
CGI for Caddy inspection page
256+
257+
Executable .................... /usr/local/bin/wapptclsh
258+
Arg 1 ....................... /home/quixote/projects/wapp/hello.tcl
259+
Root .......................... /
260+
Dir ........................... /home/quixote/www
261+
Environment
262+
DB .......................... /usr/local/share/app/app.db
263+
PATH_INFO ...................
264+
REMOTE_USER .................
265+
SCRIPT_EXEC ................. /usr/local/bin/wapptclsh /home/quixote/projects/wapp/hello.tcl
266+
SCRIPT_FILENAME ............. /usr/local/bin/wapptclsh
267+
SCRIPT_NAME ................. /wapp/hello
268+
SECRET ...................... /usr/local/share/app/secret
269+
Inherited environment
270+
HOME ........................ /home/quixote
271+
LANG ........................ en_US.UTF-8
272+
Placeholders
273+
{.} ......................... /home/quixote/go/src/github.com/mholt/caddy/caddy
274+
{host} ...................... example.com
275+
{match} ..................... /wapp/hello
276+
{method} .................... GET
277+
{root} ...................... /home/quixote/www
278+
{when} ...................... 23/May/2018:14:49:55 -0400
279+
280+
This information can be used to diagnose problems with how a CGI application is
281+
called.
282+
283+
To return to operation mode, remove or comment out the `inspect` subdirective.
284+
224285
### Environment Variable Example
225286

226287
In this example, the Caddyfile looks like this:

cgi.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ func (h handlerType) ServeHTTP(w http.ResponseWriter, r *http.Request) (code int
130130
remoteUser, _ := r.Context().Value(httpserver.RemoteUserCtxKey).(string) // Blank if not set
131131
cgiHnd := setupCall(h, rule, lfStr, rtStr, rep, r.Header, remoteUser)
132132
cgiHnd.Stderr = &buf
133-
cgiHnd.ServeHTTP(w, r)
133+
if rule.inspect {
134+
inspect(cgiHnd, w, r, rep)
135+
} else {
136+
cgiHnd.ServeHTTP(w, r)
137+
}
134138
if buf.Len() > 0 {
135139
err = errors.New(trim(buf.String()))
136140
}

cgi_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/http"
77
"net/http/httptest"
88
"runtime"
9+
"strings"
910
"testing"
1011

1112
"github.com/mholt/caddy"
@@ -204,3 +205,42 @@ func TestExceptions(t *testing.T) {
204205
}
205206
}
206207
}
208+
209+
func TestInspect(t *testing.T) {
210+
var err error
211+
var hnd handlerType
212+
var srv *httptest.Server
213+
var buf bytes.Buffer
214+
215+
block := `cgi {
216+
match /foo/*
217+
exec bar
218+
inspect
219+
}`
220+
221+
hnd, err = handlerGet(block, "./test")
222+
if err == nil {
223+
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
224+
_, hndErr := hnd.ServeHTTP(w, r)
225+
if err == nil && hndErr != nil {
226+
err = hndErr
227+
}
228+
}))
229+
var res *http.Response
230+
res, err = http.Get(srv.URL + "/foo/bar.tcl")
231+
if err == nil {
232+
_, err = buf.ReadFrom(res.Body)
233+
if err == nil {
234+
str := buf.String()
235+
if !strings.Contains(str, "CGI for Caddy") {
236+
err = fmt.Errorf("unexpected response for \"inspect\" request")
237+
}
238+
}
239+
res.Body.Close()
240+
}
241+
srv.Close()
242+
}
243+
if err != nil {
244+
t.Fatalf("%s", err)
245+
}
246+
}

def.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ type ruleType struct {
2828
passEnvs []string // [0..n]
2929
// Environment keys to send with empty values
3030
emptyEnvs []string // [0..n]
31+
// True to return inspection page rather than call CGI executable
32+
inspect bool
3133
}

doc.go

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,12 @@ empty_env, and except subdirectives can appear any reasonable number of
180180
times.
181181
182182
The except subdirective uses the same pattern matching logic that is used
183-
with the match subdirective. Any request that matches a match pattern is
184-
then checked with the patterns in except, if any. If any matches are made
185-
with the except pattern, the request is rejected.
183+
with the match subdirective except that the request must match a rule fully;
184+
no request path prefix matching is performed. Any request that matches a
185+
match pattern is then checked with the patterns in except, if any. If any
186+
matches are made with the except pattern, the request is rejected and passed
187+
along to subsequent handlers. This is a convenient way to have static file
188+
resources served properly rather than being confused as CGI applications.
186189
187190
The empty_env subdirective is used to pass one or more empty environment
188191
variables. Some CGI scripts may expect the server to pass certain empty
@@ -218,6 +221,64 @@ will be available with the following environment variables
218221
All values are conveyed as strings, so some conversion may be necessary in your
219222
program. No placeholder substitutions are made on these values.
220223
224+
Troubleshooting
225+
226+
If you run into unexpected results with the CGI plugin, you are able to examine
227+
the environment in which your CGI application runs. To enter inspection mode,
228+
add the subdirective inspect to your CGI configuration block. This is a
229+
development option that should not be used in production. When in inspection
230+
mode, the plugin will respond to matching requests with a page that displays
231+
variables of interest. In particular, it will show the replacement value of
232+
{match} and the environment variables to which your CGI application has
233+
access.
234+
235+
For example, consider this example CGI block:
236+
237+
cgi {
238+
match /wapp/*
239+
exec /usr/local/bin/wapptclsh /home/quixote/projects{match}.tcl
240+
pass_env HOME LANG
241+
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
242+
inspect
243+
}
244+
245+
When you request a matching URL, for example,
246+
247+
https://example.com/wapp/hello.tcl
248+
249+
the Caddy server will deliver a text page similar to the following. The CGI
250+
application (in this case, wapptclsh) will not be called.
251+
252+
CGI for Caddy inspection page
253+
254+
Executable .................... /usr/local/bin/wapptclsh
255+
Arg 1 ....................... /home/quixote/projects/wapp/hello.tcl
256+
Root .......................... /
257+
Dir ........................... /home/quixote/www
258+
Environment
259+
DB .......................... /usr/local/share/app/app.db
260+
PATH_INFO ...................
261+
REMOTE_USER .................
262+
SCRIPT_EXEC ................. /usr/local/bin/wapptclsh /home/quixote/projects/wapp/hello.tcl
263+
SCRIPT_FILENAME ............. /usr/local/bin/wapptclsh
264+
SCRIPT_NAME ................. /wapp/hello
265+
SECRET ...................... /usr/local/share/app/secret
266+
Inherited environment
267+
HOME ........................ /home/quixote
268+
LANG ........................ en_US.UTF-8
269+
Placeholders
270+
{.} ......................... /home/quixote/go/src/github.com/mholt/caddy/caddy
271+
{host} ...................... example.com
272+
{match} ..................... /wapp/hello
273+
{method} .................... GET
274+
{root} ...................... /home/quixote/www
275+
{when} ...................... 23/May/2018:14:49:55 -0400
276+
277+
This information can be used to diagnose problems with how a CGI application is
278+
called.
279+
280+
To return to operation mode, remove or comment out the inspect subdirective.
281+
221282
Environment Variable Example
222283
223284
In this example, the Caddyfile looks like this:

doc/cgi.md

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,12 @@ With the advanced syntax, the `exec` subdirective must appear exactly once. The
186186
times.
187187

188188
The `except` subdirective uses the same pattern matching logic that is used
189-
with the `match` subdirective. Any request that matches a `match` pattern is
190-
then checked with the patterns in `except`, if any. If any matches are made
191-
with the `except` pattern, the request is rejected.
189+
with the `match` subdirective except that the request must match a rule fully;
190+
no request path prefix matching is performed. Any request that matches a
191+
`match` pattern is then checked with the patterns in `except`, if any. If any
192+
matches are made with the `except` pattern, the request is rejected and passed
193+
along to subsequent handlers. This is a convenient way to have static file
194+
resources served properly rather than being confused as CGI applications.
192195

193196
The `empty_env` subdirective is used to pass one or more empty environment
194197
variables. Some CGI scripts may expect the server to pass certain empty
@@ -224,6 +227,64 @@ will be available with the following environment variables
224227
All values are conveyed as strings, so some conversion may be necessary in your
225228
program. No placeholder substitutions are made on these values.
226229

230+
### Troubleshooting
231+
232+
If you run into unexpected results with the CGI plugin, you are able to examine
233+
the environment in which your CGI application runs. To enter inspection mode,
234+
add the subdirective `inspect` to your CGI configuration block. This is a
235+
development option that should not be used in production. When in inspection
236+
mode, the plugin will respond to matching requests with a page that displays
237+
variables of interest. In particular, it will show the replacement value of
238+
`{match}` and the environment variables to which your CGI application has
239+
access.
240+
241+
For example, consider this example CGI block:
242+
243+
cgi {
244+
match /wapp/*
245+
exec /usr/local/bin/wapptclsh /home/quixote/projects{match}.tcl
246+
pass_env HOME LANG
247+
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
248+
inspect
249+
}
250+
251+
When you request a matching URL, for example,
252+
253+
https://example.com/wapp/hello.tcl
254+
255+
the Caddy server will deliver a text page similar to the following. The CGI
256+
application (in this case, wapptclsh) will not be called.
257+
258+
CGI for Caddy inspection page
259+
260+
Executable .................... /usr/local/bin/wapptclsh
261+
Arg 1 ....................... /home/quixote/projects/wapp/hello.tcl
262+
Root .......................... /
263+
Dir ........................... /home/quixote/www
264+
Environment
265+
DB .......................... /usr/local/share/app/app.db
266+
PATH_INFO ...................
267+
REMOTE_USER .................
268+
SCRIPT_EXEC ................. /usr/local/bin/wapptclsh /home/quixote/projects/wapp/hello.tcl
269+
SCRIPT_FILENAME ............. /usr/local/bin/wapptclsh
270+
SCRIPT_NAME ................. /wapp/hello
271+
SECRET ...................... /usr/local/share/app/secret
272+
Inherited environment
273+
HOME ........................ /home/quixote
274+
LANG ........................ en_US.UTF-8
275+
Placeholders
276+
{.} ......................... /home/quixote/go/src/github.com/mholt/caddy/caddy
277+
{host} ...................... example.com
278+
{match} ..................... /wapp/hello
279+
{method} .................... GET
280+
{root} ...................... /home/quixote/www
281+
{when} ...................... 23/May/2018:14:49:55 -0400
282+
283+
This information can be used to diagnose problems with how a CGI application is
284+
called.
285+
286+
To return to operation mode, remove or comment out the `inspect` subdirective.
287+
227288
### Environment Variable Example
228289

229290
In this example, the Caddyfile looks like this:

doc/doc.txt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,64 @@ will be available with the following environment variables
266266
All values are conveyed as strings, so some conversion may be necessary in your
267267
program. No placeholder substitutions are made on these values.
268268

269+
### Troubleshooting
270+
271+
If you run into unexpected results with the CGI plugin, you are able to examine
272+
the environment in which your CGI application runs. To enter inspection mode,
273+
add the subdirective `inspect` to your CGI configuration block. This is a
274+
development option that should not be used in production. When in inspection
275+
mode, the plugin will respond to matching requests with a page that displays
276+
variables of interest. In particular, it will show the replacement value of
277+
`{match}` and the environment variables to which your CGI application has
278+
access.
279+
280+
For example, consider this example CGI block:
281+
282+
cgi {
283+
match /wapp/*
284+
exec /usr/local/bin/wapptclsh /home/quixote/projects{match}.tcl
285+
pass_env HOME LANG
286+
env DB=/usr/local/share/app/app.db SECRET=/usr/local/share/app/secret
287+
inspect
288+
}
289+
290+
When you request a matching URL, for example,
291+
292+
https://example.com/wapp/hello.tcl
293+
294+
the Caddy server will deliver a text page similar to the following. The CGI
295+
application (in this case, wapptclsh) will not be called.
296+
297+
CGI for Caddy inspection page
298+
299+
Executable .................... /usr/local/bin/wapptclsh
300+
Arg 1 ....................... /home/quixote/projects/wapp/hello.tcl
301+
Root .......................... /
302+
Dir ........................... /home/quixote/www
303+
Environment
304+
DB .......................... /usr/local/share/app/app.db
305+
PATH_INFO ...................
306+
REMOTE_USER .................
307+
SCRIPT_EXEC ................. /usr/local/bin/wapptclsh /home/quixote/projects/wapp/hello.tcl
308+
SCRIPT_FILENAME ............. /usr/local/bin/wapptclsh
309+
SCRIPT_NAME ................. /wapp/hello
310+
SECRET ...................... /usr/local/share/app/secret
311+
Inherited environment
312+
HOME ........................ /home/quixote
313+
LANG ........................ en_US.UTF-8
314+
Placeholders
315+
{.} ......................... /home/quixote/go/src/github.com/mholt/caddy/caddy
316+
{host} ...................... example.com
317+
{match} ..................... /wapp/hello
318+
{method} .................... GET
319+
{root} ...................... /home/quixote/www
320+
{when} ...................... 23/May/2018:14:49:55 -0400
321+
322+
This information can be used to diagnose problems with how a CGI application is
323+
called.
324+
325+
To return to operation mode, remove or comment out the `inspect` subdirective.
326+
269327
### Environment Variable Example
270328

271329
In this example, the Caddyfile looks like this:

0 commit comments

Comments
 (0)