summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-09-05 13:36:42 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-09-05 13:36:42 -0600
commit80b54f3b9d5e207316fb9e8f83dd1e90659b25d7 (patch)
treecdbd23fbcb898970ed5ff20b004866db6ccd8cb1
parent0830fbad0347ead1dbea60e664556b263e44653f (diff)
Add original URI to request context; implement into fastcgi env
-rw-r--r--modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go77
-rw-r--r--modules/caddyhttp/server.go17
2 files changed, 46 insertions, 48 deletions
diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
index 35fef5f..090de25 100644
--- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
+++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
@@ -19,12 +19,14 @@ import (
"crypto/tls"
"fmt"
"net/http"
+ "net/url"
"path"
"path/filepath"
"strconv"
"strings"
"time"
+ "github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy"
"github.com/caddyserver/caddy/v2/modules/caddytls"
@@ -37,25 +39,11 @@ func init() {
// Transport facilitates FastCGI communication.
type Transport struct {
- //////////////////////////////
- // TODO: taken from v1 Handler type
-
- SoftwareName string
- SoftwareVersion string
- ServerName string
- ServerPort string
-
- //////////////////////////
- // TODO: taken from v1 Rule type
-
- // The base path to match. Required.
- // Path string
-
- // upstream load balancer
- // balancer
-
- // Always process files with this extension with fastcgi.
- // Ext string
+ // TODO: Populate these
+ softwareName string
+ softwareVersion string
+ serverName string
+ serverPort string
// Use this directory as the fastcgi root directory. Defaults to the root
// directory of the parent virtual host.
@@ -67,16 +55,9 @@ type Transport struct {
// PATH_INFO for the CGI script to use.
SplitPath string `json:"split_path,omitempty"`
- // If the URL ends with '/' (which indicates a directory), these index
- // files will be tried instead.
- // IndexFiles []string
-
// Environment Variables
EnvVars [][2]string `json:"env,omitempty"`
- // Ignored paths
- // IgnoredSubPaths []string
-
// The duration used to set a deadline when connecting to an upstream.
DialTimeout caddy.Duration `json:"dial_timeout,omitempty"`
@@ -170,7 +151,6 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
ip = strings.Replace(ip, "[", "", 1)
ip = strings.Replace(ip, "]", "", 1)
- // TODO: respect index files? or leave that to matcher/rewrite (I prefer that)?
fpath := r.URL.Path
// Split path in preparation for env variables.
@@ -194,16 +174,17 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
pathPrefix, _ := r.Context().Value(caddy.CtxKey("path_prefix")).(string)
scriptName = path.Join(pathPrefix, scriptName)
- // TODO: Disabled for now
- // // Get the request URI from context. The context stores the original URI in case
- // // it was changed by a middleware such as rewrite. By default, we pass the
- // // original URI in as the value of REQUEST_URI (the user can overwrite this
- // // if desired). Most PHP apps seem to want the original URI. Besides, this is
- // // how nginx defaults: http://stackoverflow.com/a/12485156/1048862
- // reqURL, _ := r.Context().Value(httpserver.OriginalURLCtxKey).(url.URL)
-
- // // Retrieve name of remote user that was set by some downstream middleware such as basicauth.
- // remoteUser, _ := r.Context().Value(httpserver.RemoteUserCtxKey).(string)
+ // Get the request URL from context. The context stores the original URL in case
+ // it was changed by a middleware such as rewrite. By default, we pass the
+ // original URI in as the value of REQUEST_URI (the user can overwrite this
+ // if desired). Most PHP apps seem to want the original URI. Besides, this is
+ // how nginx defaults: http://stackoverflow.com/a/12485156/1048862
+ reqURL, ok := r.Context().Value(caddyhttp.OriginalURLCtxKey).(url.URL)
+ if !ok {
+ // some requests, like active health checks, don't add this to
+ // the request context, so we can just use the current URL
+ reqURL = *r.URL
+ }
requestScheme := "http"
if r.TLS != nil {
@@ -224,19 +205,19 @@ func (t Transport) buildEnv(r *http.Request) (map[string]string, error) {
"REMOTE_HOST": ip, // For speed, remote host lookups disabled
"REMOTE_PORT": port,
"REMOTE_IDENT": "", // Not used
- // "REMOTE_USER": remoteUser, // TODO:
- "REQUEST_METHOD": r.Method,
- "REQUEST_SCHEME": requestScheme,
- "SERVER_NAME": t.ServerName,
- "SERVER_PORT": t.ServerPort,
- "SERVER_PROTOCOL": r.Proto,
- "SERVER_SOFTWARE": t.SoftwareName + "/" + t.SoftwareVersion,
+ "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_PROTOCOL": r.Proto,
+ "SERVER_SOFTWARE": t.SoftwareName + "/" + t.SoftwareVersion,
// Other variables
- // "DOCUMENT_ROOT": rule.Root,
- "DOCUMENT_URI": docURI,
- "HTTP_HOST": r.Host, // added here, since not always part of headers
- // "REQUEST_URI": reqURL.RequestURI(), // TODO:
+ "DOCUMENT_ROOT": t.Root,
+ "DOCUMENT_URI": docURI,
+ "HTTP_HOST": r.Host, // added here, since not always part of headers
+ "REQUEST_URI": reqURL.RequestURI(),
"SCRIPT_FILENAME": scriptFilename,
"SCRIPT_NAME": scriptName,
}
diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go
index 248e5f2..04935e6 100644
--- a/modules/caddyhttp/server.go
+++ b/modules/caddyhttp/server.go
@@ -20,6 +20,7 @@ import (
"log"
"net"
"net/http"
+ "net/url"
"strconv"
"strings"
@@ -58,6 +59,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), caddy.ReplacerCtxKey, repl)
ctx = context.WithValue(ctx, ServerCtxKey, s)
ctx = context.WithValue(ctx, VarCtxKey, make(map[string]interface{}))
+ ctx = context.WithValue(ctx, OriginalURLCtxKey, cloneURL(r.URL))
r = r.WithContext(ctx)
// once the pointer to the request won't change
@@ -228,6 +230,18 @@ type HTTPErrorConfig struct {
Routes RouteList `json:"routes,omitempty"`
}
+// cloneURL makes a copy of r.URL and returns a
+// new value that doesn't reference the original.
+func cloneURL(u *url.URL) url.URL {
+ urlCopy := *u
+ if u.User != nil {
+ userInfo := new(url.Userinfo)
+ *userInfo = *u.User
+ urlCopy.User = userInfo
+ }
+ return urlCopy
+}
+
// Context keys for HTTP request context values.
const (
// For referencing the server instance
@@ -235,4 +249,7 @@ const (
// For the request's variable table
VarCtxKey caddy.CtxKey = "vars"
+
+ // For the unmodified URL that originally came in with a request
+ OriginalURLCtxKey caddy.CtxKey = "original_url"
)