Rewrite SCGI support to use prefixes, not regexps, and provide the same SCRIPT_PATH / PATH_INFO break as CGI.
This commit is contained in:
parent
d87ecfd20f
commit
2a263e5e70
19
README.md
19
README.md
|
@ -252,8 +252,8 @@ SCGI applications must be started separately (i.e. Molly Brown expects
|
||||||
them to already be running and will not attempt to start them itself),
|
them to already be running and will not attempt to start them itself),
|
||||||
and as such they can run e.g. as their own user and/or chrooted into
|
and as such they can run e.g. as their own user and/or chrooted into
|
||||||
their own filesystem, meaning that they are less of a security threat
|
their own filesystem, meaning that they are less of a security threat
|
||||||
in addition to avoiding the overhead of process startup, database
|
than CGI applications (in addition to avoiding the overhead of process
|
||||||
connection etc. on each request.
|
startup, database connection etc. on each request).
|
||||||
|
|
||||||
* `CGIPaths`: A list of filesystem paths, within which
|
* `CGIPaths`: A list of filesystem paths, within which
|
||||||
world-executable files will be run as CGI processes. The paths act
|
world-executable files will be run as CGI processes. The paths act
|
||||||
|
@ -265,13 +265,14 @@ connection etc. on each request.
|
||||||
if wildcards are used, the path should *not* end in a trailing slash
|
if wildcards are used, the path should *not* end in a trailing slash
|
||||||
- this appears to be a peculiarity of the Go standard library's
|
- this appears to be a peculiarity of the Go standard library's
|
||||||
`filepath.Glob` function.
|
`filepath.Glob` function.
|
||||||
* `SCGIPaths`: In this section of the config file, keys are path
|
* `SCGIPaths`: In this section of the config file, keys are URL path
|
||||||
regexs and values are paths to unix domain sockets. Any request
|
prefixes and values are filesystem paths to unix domain sockets.
|
||||||
whose path matches one of the regexs will cause an SCGI request to
|
Any request for a URL whose path begins with one of the specified
|
||||||
be sent to the corresponding domain socket, and anything sent back
|
prefixes will cause an SCGI request to be sent to the corresponding
|
||||||
from a program listening on the other end of the socket will be send
|
domain socket. Anything sent back from a program listening on the
|
||||||
as the response to the client. SCGI applications are responsible
|
other end of the socket will be sent as the response to the client.
|
||||||
for generating their own response headers.
|
SCGI applications are responsible for generating their own response
|
||||||
|
headers.
|
||||||
|
|
||||||
### Certificate zones
|
### Certificate zones
|
||||||
|
|
||||||
|
|
11
dynamic.go
11
dynamic.go
|
@ -82,10 +82,10 @@ func handleCGI(config Config, path string, cgiPath string, URL *url.URL, log *Lo
|
||||||
conn.Write(response)
|
conn.Write(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSCGI(socket_path string, config Config, URL *url.URL, log *LogEntry, conn net.Conn) {
|
func handleSCGI(URL *url.URL, scgiPath string, scgiSocket string, config Config, log *LogEntry, conn net.Conn) {
|
||||||
|
|
||||||
// Connect to socket
|
// Connect to socket
|
||||||
socket, err := net.Dial("unix", socket_path)
|
socket, err := net.Dial("unix", scgiSocket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Write([]byte("42 Error connecting to SCGI service!\r\n"))
|
conn.Write([]byte("42 Error connecting to SCGI service!\r\n"))
|
||||||
log.Status = 42
|
log.Status = 42
|
||||||
|
@ -94,7 +94,7 @@ func handleSCGI(socket_path string, config Config, URL *url.URL, log *LogEntry,
|
||||||
defer socket.Close()
|
defer socket.Close()
|
||||||
|
|
||||||
// Send variables
|
// Send variables
|
||||||
vars := prepareSCGIVariables(config, URL, conn)
|
vars := prepareSCGIVariables(config, URL, scgiPath, conn)
|
||||||
length := 0
|
length := 0
|
||||||
for key, value := range vars {
|
for key, value := range vars {
|
||||||
length += len(key)
|
length += len(key)
|
||||||
|
@ -150,11 +150,12 @@ func prepareCGIVariables(config Config, URL *url.URL, conn net.Conn, script_path
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSCGIVariables(config Config, URL *url.URL, conn net.Conn) map[string]string {
|
func prepareSCGIVariables(config Config, URL *url.URL, scgiPath string, conn net.Conn) map[string]string {
|
||||||
vars := prepareGatewayVariables(config, URL, conn)
|
vars := prepareGatewayVariables(config, URL, conn)
|
||||||
vars["SCGI"] = "1"
|
vars["SCGI"] = "1"
|
||||||
vars["CONTENT_LENGTH"] = "0"
|
vars["CONTENT_LENGTH"] = "0"
|
||||||
vars["PATH_INFO"] = "/"
|
vars["SCRIPT_PATH"] = scgiPath
|
||||||
|
vars["PATH_INFO"] = URL.Path[len(scgiPath):]
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,9 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether this URL is mapped to an SCGI app
|
// Check whether this URL is mapped to an SCGI app
|
||||||
for scgi_url, scgi_socket := range config.SCGIPaths {
|
for scgiPath, scgiSocket := range config.SCGIPaths {
|
||||||
matched, err := regexp.Match(scgi_url, []byte(URL.Path))
|
if strings.HasPrefix(URL.Path, scgiPath) {
|
||||||
if matched && err == nil {
|
handleSCGI(URL, scgiPath, scgiSocket, config, &log, conn)
|
||||||
handleSCGI(scgi_socket, config, URL, &log, conn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue