Add 'no-store' response header from all the API outlets (#2183)

This commit is contained in:
Vishal Nayak
2016-12-15 17:53:07 -05:00
committed by Jeff Mitchell
parent cb594ae9a1
commit 8f30b4751e
5 changed files with 60 additions and 3 deletions

View File

@@ -61,9 +61,26 @@ func Handler(core *vault.Core) http.Handler {
mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core, false, nil))) mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core, false, nil)))
// Wrap the handler in another handler to trigger all help paths. // Wrap the handler in another handler to trigger all help paths.
handler := handleHelpHandler(mux, core) helpWrappedHandler := wrapHelpHandler(mux, core)
return handler // Wrap the help wrapped handler with another layer with a generic
// handler
genericWrappedHandler := wrapGenericHandler(helpWrappedHandler)
return genericWrappedHandler
}
// wrapGenericHandler wraps the handler with an extra layer of handler where
// tasks that should be commonly handled for all the requests and/or responses
// are performed.
func wrapGenericHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Set the Cache-Control header for all the responses returned
// by Vault
w.Header().Set("Cache-Control", "no-store")
h.ServeHTTP(w, r)
return
})
} }
// A lookup on a token that is about to expire returns nil, which means by the // A lookup on a token that is about to expire returns nil, which means by the

View File

@@ -13,6 +13,39 @@ import (
"github.com/hashicorp/vault/vault" "github.com/hashicorp/vault/vault"
) )
func TestHandler_CacheControlNoStore(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
req, err := http.NewRequest("GET", addr+"/v1/sys/mounts", nil)
if err != nil {
t.Fatalf("err: %s", err)
}
req.Header.Set(AuthHeaderName, token)
req.Header.Set(WrapTTLHeaderName, "60s")
client := cleanhttp.DefaultClient()
resp, err := client.Do(req)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp == nil {
t.Fatalf("nil response")
}
actual := resp.Header.Get("Cache-Control")
if actual == "" {
t.Fatalf("missing 'Cache-Control' header entry in response writer")
}
if actual != "no-store" {
t.Fatalf("bad: Cache-Control. Expected: 'no-store', Actual: %q", actual)
}
}
// We use this test to verify header auth // We use this test to verify header auth
func TestSysMounts_headerAuth(t *testing.T) { func TestSysMounts_headerAuth(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t) core, _, token := vault.TestCoreUnsealed(t)

View File

@@ -7,7 +7,7 @@ import (
"github.com/hashicorp/vault/vault" "github.com/hashicorp/vault/vault"
) )
func handleHelpHandler(h http.Handler, core *vault.Core) http.Handler { func wrapHelpHandler(h http.Handler, core *vault.Core) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// If the help parameter is not blank, then show the help // If the help parameter is not blank, then show the help
if v := req.URL.Query().Get("help"); v != "" || req.Method == "HELP" { if v := req.URL.Query().Get("help"); v != "" || req.Method == "HELP" {

View File

@@ -260,6 +260,7 @@ func respondRaw(w http.ResponseWriter, r *http.Request, resp *logical.Response)
if contentType != "" { if contentType != "" {
w.Header().Set("Content-Type", contentType) w.Header().Set("Content-Type", contentType)
} }
w.WriteHeader(status) w.WriteHeader(status)
w.Write(body) w.Write(body)
} }

View File

@@ -398,6 +398,12 @@ func WrapHandlerForClustering(handler http.Handler, logger log.Logger) func() (h
} }
w.Header().Add("Content-Type", "application/json") w.Header().Add("Content-Type", "application/json")
// The response writer here is different from
// the one set in Vault's HTTP handler.
// Hence, set the Cache-Control explicitly.
w.Header().Set("Cache-Control", "no-store")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
type errorResponse struct { type errorResponse struct {