diff --git a/go.mod b/go.mod index 60068be466..f10a14f5f3 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf github.com/hashicorp/raft v1.1.1 - github.com/hashicorp/raft-snapshot v1.0.1 + github.com/hashicorp/raft-snapshot v1.0.2-0.20190827162939-8117efcc5aab github.com/hashicorp/vault-plugin-auth-alicloud v0.5.2-0.20190814210027-93970f08f2ec github.com/hashicorp/vault-plugin-auth-azure v0.5.2-0.20190814210035-08e00d801115 github.com/hashicorp/vault-plugin-auth-centrify v0.5.2-0.20190814210042-090ec2ed93ce diff --git a/go.sum b/go.sum index 916f9b5163..dd1be4f43c 100644 --- a/go.sum +++ b/go.sum @@ -329,6 +329,8 @@ github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7 github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/raft-snapshot v1.0.1 h1:cx002JsTEAfAP0pIuANlDtTXg/pi2Db6YbRRmLQTQKw= github.com/hashicorp/raft-snapshot v1.0.1/go.mod h1:5sL9eUn72lH5DzsFIJ9jaysITbHksSSszImWSOTC8Ic= +github.com/hashicorp/raft-snapshot v1.0.2-0.20190827162939-8117efcc5aab h1:WzGMwlO1DvaC93SvVOBOKtn+nXGEDXapyJuaRV3/VaY= +github.com/hashicorp/raft-snapshot v1.0.2-0.20190827162939-8117efcc5aab/go.mod h1:5sL9eUn72lH5DzsFIJ9jaysITbHksSSszImWSOTC8Ic= github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/vault-plugin-auth-alicloud v0.5.2-0.20190814210027-93970f08f2ec h1:HXVE8h6RXFsPJgwWpE+5CscsgekqtX4nhDlZGV9jEe4= diff --git a/http/logical.go b/http/logical.go index 4147693ea8..10f909f170 100644 --- a/http/logical.go +++ b/http/logical.go @@ -28,7 +28,7 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques var data map[string]interface{} var origBody io.ReadCloser var requestReader io.ReadCloser - var responseWriter io.Writer + var responseWriter http.ResponseWriter // Determine the operation var op logical.Operation diff --git a/physical/raft/raft.go b/physical/raft/raft.go index 13cd0e6348..329d61e0e5 100644 --- a/physical/raft/raft.go +++ b/physical/raft/raft.go @@ -21,6 +21,7 @@ import ( snapshot "github.com/hashicorp/raft-snapshot" raftboltdb "github.com/hashicorp/vault/physical/raft/logstore" "github.com/hashicorp/vault/sdk/helper/consts" + "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault/cluster" "github.com/hashicorp/vault/vault/seal" @@ -606,7 +607,7 @@ func (b *RaftBackend) Peers(ctx context.Context) ([]Peer, error) { // Snapshot takes a raft snapshot, packages it into a archive file and writes it // to the provided writer. Seal access is used to encrypt the SHASUM file so we // can validate the snapshot was taken using the same master keys or not. -func (b *RaftBackend) Snapshot(out io.Writer, access seal.Access) error { +func (b *RaftBackend) Snapshot(out *logical.HTTPResponseWriter, access seal.Access) error { b.l.RLock() defer b.l.RUnlock() @@ -628,6 +629,14 @@ func (b *RaftBackend) Snapshot(out io.Writer, access seal.Access) error { } defer snap.Close() + size, err := snap.Size() + if err != nil { + return err + } + + out.Header().Add("Content-Disposition", "attachment") + out.Header().Add("Content-Length", fmt.Sprintf("%d", size)) + out.Header().Add("Content-Type", "application/gzip") _, err = io.Copy(out, snap) if err != nil { return err diff --git a/sdk/logical/response.go b/sdk/logical/response.go index ecc208f96e..fb799ba4b8 100644 --- a/sdk/logical/response.go +++ b/sdk/logical/response.go @@ -4,7 +4,7 @@ import ( "encoding/json" "errors" "fmt" - "io" + "net/http" "sync/atomic" "github.com/hashicorp/vault/sdk/helper/wrapping" @@ -187,16 +187,16 @@ func RespondWithStatusCode(resp *Response, req *Request, code int) (*Response, e // HTTPResponseWriter is optionally added to a request object and can be used to // write directly to the HTTP response writter. type HTTPResponseWriter struct { - writer io.Writer + http.ResponseWriter written *uint32 } // NewHTTPResponseWriter creates a new HTTPRepoinseWriter object that wraps the // provided io.Writer. -func NewHTTPResponseWriter(w io.Writer) *HTTPResponseWriter { +func NewHTTPResponseWriter(w http.ResponseWriter) *HTTPResponseWriter { return &HTTPResponseWriter{ - writer: w, - written: new(uint32), + ResponseWriter: w, + written: new(uint32), } } @@ -204,7 +204,7 @@ func NewHTTPResponseWriter(w io.Writer) *HTTPResponseWriter { func (rw *HTTPResponseWriter) Write(bytes []byte) (int, error) { atomic.StoreUint32(rw.written, 1) - return rw.writer.Write(bytes) + return rw.ResponseWriter.Write(bytes) } // Written tells us if the writer has been written to yet.