From b86e60b9de1d3d04b7e9c126431c67dfdf64f010 Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Fri, 22 Jan 2016 10:52:20 -0800 Subject: [PATCH 1/3] Allow users to configure arbitrary headers in config --- command/agent/config.go | 4 ++++ command/agent/config_test.go | 6 ++++++ command/agent/http.go | 8 ++++++++ command/agent/http_test.go | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/command/agent/config.go b/command/agent/config.go index 1d567d653..7982dcbe5 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -101,6 +101,10 @@ type Config struct { // List of config files that have been loaded (in order) Files []string + + // HTTPAPIResponseHeaders allows users to configure the Nomad http agent to + // set arbritrary headers on API responses + HTTPAPIResponseHeaders map[string]string `hcl:"http_api_response_headers"` } // AtlasConfig is used to enable an parameterize the Atlas integration diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 160895afa..2662e1155 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -453,6 +453,9 @@ func TestConfig_LoadConfigString(t *testing.T) { Join: true, Endpoint: "127.0.0.1:1234", }, + HTTPAPIResponseHeaders: map[string]string{ + "Access-Control-Allow-Origin": "*", + }, } // Check parsing @@ -531,4 +534,7 @@ atlas { join = true endpoint = "127.0.0.1:1234" } +http_api_response_headers { + Access-Control-Allow-Origin = "*" +} ` diff --git a/command/agent/http.go b/command/agent/http.go index ca5b20104..6b36971fa 100644 --- a/command/agent/http.go +++ b/command/agent/http.go @@ -152,6 +152,7 @@ func (e *codedError) Code() int { // wrap is used to wrap functions to make them more convenient func (s *HTTPServer) wrap(handler func(resp http.ResponseWriter, req *http.Request) (interface{}, error)) func(resp http.ResponseWriter, req *http.Request) { f := func(resp http.ResponseWriter, req *http.Request) { + setHeaders(resp, s.agent.config.HTTPAPIResponseHeaders) // Invoke the handler reqURL := req.URL.String() start := time.Now() @@ -229,6 +230,13 @@ func setMeta(resp http.ResponseWriter, m *structs.QueryMeta) { setKnownLeader(resp, m.KnownLeader) } +// setHeaders is used to set canonical response header fields +func setHeaders(resp http.ResponseWriter, headers map[string]string) { + for field, value := range headers { + resp.Header().Set(http.CanonicalHeaderKey(field), value) + } +} + // parseWait is used to parse the ?wait and ?index query params // Returns true on error func parseWait(resp http.ResponseWriter, req *http.Request, b *structs.QueryOptions) bool { diff --git a/command/agent/http_test.go b/command/agent/http_test.go index b9da79820..8001d722e 100644 --- a/command/agent/http_test.go +++ b/command/agent/http_test.go @@ -104,6 +104,26 @@ func TestSetMeta(t *testing.T) { } } +func TestSetHeaders(t *testing.T) { + s := makeHTTPServer(t, nil) + s.Agent.config.HTTPAPIResponseHeaders = map[string]string{"foo": "bar"} + defer s.Cleanup() + + resp := httptest.NewRecorder() + handler := func(resp http.ResponseWriter, req *http.Request) (interface{}, error) { + return &structs.Job{Name: "foo"}, nil + } + + req, _ := http.NewRequest("GET", "/v1/kv/key", nil) + s.Server.wrap(handler)(resp, req) + header := resp.Header().Get("foo") + + if header != "bar" { + t.Fatalf("expected header: %v, actual: %v", "bar", header) + } + +} + func TestContentTypeIsJSON(t *testing.T) { s := makeHTTPServer(t, nil) defer s.Cleanup() From fc178b9319e496c90796ac98394bef8995333dc8 Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Fri, 22 Jan 2016 10:57:26 -0800 Subject: [PATCH 2/3] Added the docs --- CHANGELOG.md | 1 + website/source/docs/agent/config.html.md | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6791b8f16..62639539b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ IMPROVEMENTS: * drivers: Interpret Nomad variables in environment variables/args [GH-653] * core: Populate job status [GH-663] * core/cli: Print short identifiers and UX cleanup [GH-675, GH-693, GH-692] + * api: Allow users to set arbitrary headers via agent config [GH-699] BUG FIXES: * cli: Handle parsing of un-named ports [GH-604] diff --git a/website/source/docs/agent/config.html.md b/website/source/docs/agent/config.html.md index 3c76bcee3..431976219 100644 --- a/website/source/docs/agent/config.html.md +++ b/website/source/docs/agent/config.html.md @@ -190,6 +190,15 @@ nodes, unless otherwise specified: * `disable_anonymous_signature`: Disables providing an anonymous signature for de-duplication with the update check. See `disable_update_check`. +* `http_api_response_headers`: This object allows adding headers to the + HTTP API responses. For example, the following config can be used to enable + CORS on the HTTP API endpoints: + ``` + http_api_response_headers { + Access-Control-Allow-Origin = "*" + } + ``` + ## Server-specific Options The following options are applicable to server agents only and need not be From d7c04e26684dd772ca899a3782e87549eb52d58c Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Fri, 22 Jan 2016 14:52:34 -0800 Subject: [PATCH 3/3] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62639539b..ac7e93e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ IMPROVEMENTS: * drivers: Interpret Nomad variables in environment variables/args [GH-653] * core: Populate job status [GH-663] * core/cli: Print short identifiers and UX cleanup [GH-675, GH-693, GH-692] - * api: Allow users to set arbitrary headers via agent config [GH-699] + * core/api: Allow users to set arbitrary headers via agent config [GH-699] BUG FIXES: * cli: Handle parsing of un-named ports [GH-604]