Browse Source

fastcgi: Set default root path; add interface guards

master
Matthew Holt 5 years ago
parent
commit
d2e46c2be0
No known key found for this signature in database GPG Key ID: 2A349DD577D586A5
  1. 30
      modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
  2. 6
      modules/caddyhttp/reverseproxy/httptransport.go

30
modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go

@ -76,6 +76,14 @@ func (Transport) CaddyModule() caddy.ModuleInfo {
}
}
// Provision sets up t.
func (t *Transport) Provision(_ caddy.Context) error {
if t.Root == "" {
t.Root = "{http.var.root}"
}
return nil
}
// RoundTrip implements http.RoundTripper.
func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) {
env, err := t.buildEnv(r)
@ -136,6 +144,8 @@ func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) {
// buildEnv returns a set of CGI environment variables for the request.
func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
var env map[string]string
// Separate remote IP and port; more lenient than net.SplitHostPort
@ -151,6 +161,7 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
ip = strings.Replace(ip, "[", "", 1)
ip = strings.Replace(ip, "]", "", 1)
root := repl.ReplaceAll(t.Root, ".")
fpath := r.URL.Path
// Split path in preparation for env variables.
@ -167,7 +178,7 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
scriptName = strings.TrimSuffix(scriptName, pathInfo)
// SCRIPT_FILENAME is the absolute path of SCRIPT_NAME
scriptFilename := filepath.Join(t.Root, scriptName)
scriptFilename := filepath.Join(root, scriptName)
// Add vhost path prefix to scriptName. Otherwise, some PHP software will
// have difficulty discovering its URL.
@ -208,13 +219,13 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
"REMOTE_USER": "", // TODO: once there are authentication handlers, populate this
"REQUEST_METHOD": r.Method,
"REQUEST_SCHEME": requestScheme,
"SERVER_NAME": t.ServerName,
"SERVER_PORT": t.ServerPort,
"SERVER_NAME": t.serverName,
"SERVER_PORT": t.serverPort,
"SERVER_PROTOCOL": r.Proto,
"SERVER_SOFTWARE": t.SoftwareName + "/" + t.SoftwareVersion,
"SERVER_SOFTWARE": t.softwareName + "/" + t.softwareVersion,
// Other variables
"DOCUMENT_ROOT": t.Root,
"DOCUMENT_ROOT": root,
"DOCUMENT_URI": docURI,
"HTTP_HOST": r.Host, // added here, since not always part of headers
"REQUEST_URI": reqURL.RequestURI(),
@ -226,7 +237,7 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
// PATH_TRANSLATED should only exist if PATH_INFO is defined.
// Info: https://www.ietf.org/rfc/rfc3875 Page 14
if env["PATH_INFO"] != "" {
env["PATH_TRANSLATED"] = filepath.Join(t.Root, pathInfo) // Info: http://www.oreilly.com/openbook/cgi/ch02_04.html
env["PATH_TRANSLATED"] = filepath.Join(root, pathInfo) // Info: http://www.oreilly.com/openbook/cgi/ch02_04.html
}
// Some web apps rely on knowing HTTPS or not
@ -248,7 +259,6 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
}
// Add env variables from config (with support for placeholders in values)
repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
for _, envVar := range t.EnvVars {
env[envVar[0]] = repl.ReplaceAll(envVar[1], "")
}
@ -283,3 +293,9 @@ var tlsProtocolStrings = map[uint16]string{
}
var headerNameReplacer = strings.NewReplacer(" ", "_", "-", "_")
// Interface guards
var (
_ caddy.Provisioner = (*Transport)(nil)
_ http.RoundTripper = (*Transport)(nil)
)

6
modules/caddyhttp/reverseproxy/httptransport.go

@ -200,3 +200,9 @@ type KeepAlive struct {
MaxIdleConnsPerHost int `json:"max_idle_conns_per_host,omitempty"`
IdleConnTimeout caddy.Duration `json:"idle_timeout,omitempty"` // how long should connections be kept alive when idle
}
// Interface guards
var (
_ caddy.Provisioner = (*HTTPTransport)(nil)
_ http.RoundTripper = (*HTTPTransport)(nil)
)

Loading…
Cancel
Save