diff --git a/api/agent/agent_test.go b/api/agent/agent_test.go index c6117eddb..d81e013ac 100644 --- a/api/agent/agent_test.go +++ b/api/agent/agent_test.go @@ -64,6 +64,7 @@ func TestCallConfigurationRequest(t *testing.T) { req.Header.Add("MYREALHEADER", "FOOLORD") req.Header.Add("MYREALHEADER", "FOOPEASANT") req.Header.Add("Content-Length", contentLength) + req.Header.Add("FN_ROUTE", "thewrongroute") // ensures that this doesn't leak out, should be overwritten call, err := a.GetCall( WithWriter(w), // XXX (reed): order matters [for now] diff --git a/api/agent/call.go b/api/agent/call.go index d864d12ae..1d4179b31 100644 --- a/api/agent/call.go +++ b/api/agent/call.go @@ -113,13 +113,19 @@ func FromRequest(appName, path string, req *http.Request) CallOpt { headerVars := make(map[string]string, len(req.Header)) for k, v := range req.Header { - headerVars[toEnvName("FN_HEADER", k)] = strings.Join(v, ", ") + if !noOverrideVars(k) { // NOTE if we don't do this, they'll leak in (don't want people relying on this behavior) + headerVars[toEnvName("FN_HEADER", k)] = strings.Join(v, ", ") + } } // add all the env vars we build to the request headers - // TODO should we save req.Headers and copy OVER app.Config / route.Config ? for k, v := range envVars { - req.Header.Add(k, v) + if noOverrideVars(k) { + // overwrite the passed in request headers explicitly with the generated ones + req.Header.Set(k, v) + } else { + req.Header.Add(k, v) + } } for k, v := range headerVars { @@ -171,6 +177,24 @@ func FromRequest(appName, path string, req *http.Request) CallOpt { } } +func noOverrideVars(key string) bool { + // descrepency in casing b/w req headers and env vars, force matches + return overrideVars[strings.ToUpper(key)] +} + +// overrideVars means that the app config, route config or header vars +// must not overwrite the generated values in call construction. +var overrideVars = map[string]bool{ + "FN_FORMAT": true, + "FN_APP_NAME": true, + "FN_ROUTE": true, + "FN_MEMORY": true, + "FN_TYPE": true, + "FN_CALL_ID": true, + "FN_METHOD": true, + "FN_REQUEST_URL": true, +} + // TODO this currently relies on FromRequest having happened before to create the model // here, to be a fully qualified model. We probably should double check but having a way // to bypass will likely be what's used anyway unless forced. diff --git a/api/agent/protocol/http.go b/api/agent/protocol/http.go index 03d62991c..a273c85c6 100644 --- a/api/agent/protocol/http.go +++ b/api/agent/protocol/http.go @@ -42,7 +42,7 @@ func (h *HTTPProtocol) Dispatch(w io.Writer, req *http.Request) error { } for k, v := range res.Header { - rw.Header()[k] = v + rw.Header().Add(k, v) // on top of any specified on the route } rw.WriteHeader(res.StatusCode) // TODO should we TCP_CORK ?