Skip to content

Commit

Permalink
txn: don't try to decode request bodies > raft.SuggestedMaxDataSize (#…
Browse files Browse the repository at this point in the history
…6422)

txn: don't try to decode request bodies > raft.SuggestedMaxDataSize
  • Loading branch information
s-mang authored Aug 30, 2019
1 parent 20b9f0c commit 9f4b329
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
13 changes: 13 additions & 0 deletions agent/txn_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"fmt"
"net/http"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -98,6 +99,18 @@ func isWrite(op api.KVOp) bool {
// a boolean, that if false means an error response has been generated and
// processing should stop.
func (s *HTTPServer) convertOps(resp http.ResponseWriter, req *http.Request) (structs.TxnOps, int, bool) {

sizeStr := req.Header.Get("Content-Length")
if sizeStr != "" {
if size, err := strconv.Atoi(sizeStr); err != nil {
fmt.Fprintf(resp, "Failed to parse Content-Length: %v", err)
return nil, 0, false
} else if size > int(s.agent.config.KVMaxValueSize) {
fmt.Fprintf(resp, "Request body too large, max size: %v bytes", s.agent.config.KVMaxValueSize)
return nil, 0, false
}
}

// Note the body is in API format, and not the RPC format. If we can't
// decode it, we will return a 400 since we don't have enough context to
// associate the error with a given operation.
Expand Down
48 changes: 48 additions & 0 deletions agent/txn_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -602,3 +603,50 @@ func TestTxnEndpoint_UpdateCheck(t *testing.T) {
}
verify.Values(t, "", txnResp, expected)
}

func TestConvertOps_ContentLength(t *testing.T) {
a := NewTestAgent(t, t.Name(), "")
defer a.Shutdown()

jsonBody := `[
{
"KV": {
"Verb": "set",
"Key": "key1",
"Value": "aGVsbG8gd29ybGQ="
}
}
]`

tests := []struct {
contentLength string
ok bool
}{
{"", true},
{strconv.Itoa(len(jsonBody)), true},
{strconv.Itoa(raft.SuggestedMaxDataSize), true},
{strconv.Itoa(raft.SuggestedMaxDataSize + 100), false},
}

for _, tc := range tests {
t.Run("contentLength: "+tc.contentLength, func(t *testing.T) {
resp := httptest.NewRecorder()
var body bytes.Buffer

// Doesn't matter what the request body size actually is, as we only
// check 'Content-Length' header in this test anyway.
body.WriteString(jsonBody)

req := httptest.NewRequest("POST", "http://foo.com", &body)
req.Header.Add("Content-Length", tc.contentLength)

_, _, ok := a.srv.convertOps(resp, req)
if ok != tc.ok {
t.Fatal("ok != tc.ok")
}

})

}

}

0 comments on commit 9f4b329

Please sign in to comment.