logical/request: store the entire http.Request object instead (#7412)

This allows logical operations (along with a non-nil response writer) to
process http handler funcs within the operation function while keeping
auth and audit checks that the logical request flow provides.
This commit is contained in:
Calvin Leung Huang 2019-09-06 12:40:15 -07:00 committed by GitHub
parent c2905773e4
commit ec64b7c672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 11 deletions

View File

@ -27,7 +27,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 passHTTPReq bool
var responseWriter http.ResponseWriter
// Determine the operation
@ -68,10 +68,10 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques
// Parse the request if we can
if op == logical.UpdateOperation {
// If we are uploading a snapshot we don't want to parse it. Instead
// we will simply add the request body to the logical request object
// we will simply add the HTTP request to the logical request object
// for later consumption.
if path == "sys/storage/raft/snapshot" || path == "sys/storage/raft/snapshot-force" {
requestReader = r.Body
passHTTPReq = true
origBody = r.Body
} else {
origBody, err = parseRequest(core, r, w, &data)
@ -131,8 +131,8 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques
return nil, nil, http.StatusBadRequest, errwrap.Wrapf(fmt.Sprintf(`failed to parse %s header: {{err}}`, PolicyOverrideHeaderName), err)
}
if requestReader != nil {
req.RequestReader = requestReader
if passHTTPReq {
req.HTTPRequest = r
}
if responseWriter != nil {
req.ResponseWriter = logical.NewHTTPResponseWriter(responseWriter)

View File

@ -2,7 +2,7 @@ package logical
import (
"fmt"
"io"
"net/http"
"strings"
"time"
)
@ -173,9 +173,9 @@ type Request struct {
// we can delete it before sending off to plugins
ClientTokenSource ClientTokenSource
// RequestReader if set can be used to read the full request body from the
// http request that generated this logical.Request object.
RequestReader io.ReadCloser `json:"-" sentinel:""`
// HTTPRequest, if set, can be used to access fields from the HTTP request
// that generated this logical.Request object, such as the request body.
HTTPRequest *http.Request `json:"-" sentinel:""`
// ResponseWriter if set can be used to stream a response value to the http
// request that generated this logical.Request object.

View File

@ -307,7 +307,7 @@ func (b *SystemBackend) handleStorageRaftSnapshotWrite(force bool) framework.Ope
if !ok {
return logical.ErrorResponse("raft storage is not in use"), logical.ErrInvalidRequest
}
if req.RequestReader == nil {
if req.HTTPRequest == nil || req.HTTPRequest.Body == nil {
return nil, errors.New("no reader for request")
}
@ -320,7 +320,7 @@ func (b *SystemBackend) handleStorageRaftSnapshotWrite(force bool) framework.Ope
// don't have to hold the full snapshot in memory. We also want to do
// the restore in two parts so we can restore the snapshot while the
// stateLock is write locked.
snapFile, cleanup, metadata, err := raftStorage.WriteSnapshotToTemp(req.RequestReader, access)
snapFile, cleanup, metadata, err := raftStorage.WriteSnapshotToTemp(req.HTTPRequest.Body, access)
switch {
case err == nil:
case strings.Contains(err.Error(), "failed to open the sealed hashes"):