Skip to content

Commit

Permalink
[API] add batch size limit for jsonrpc (#3805)
Browse files Browse the repository at this point in the history
* add batch size limit for jsonrpc
  • Loading branch information
millken authored and dustinxie committed Feb 21, 2023
1 parent 83008ed commit e3805a2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
25 changes: 20 additions & 5 deletions api/types/types.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package apitypes

import (
"encoding/json"
"errors"

"github.com/iotexproject/iotex-core/action"
"github.com/iotexproject/iotex-core/blockchain/block"
)

// MaxResponseSize is the max size of response
var MaxResponseSize = 1024 * 1024 * 100 // 100MB

type (
// Web3ResponseWriter is writer for web3 request
Web3ResponseWriter interface {
Expand Down Expand Up @@ -49,21 +55,30 @@ func (w *responseWriter) Write(in interface{}) error {

// BatchWriter for multiple web3 requests
type BatchWriter struct {
writer Web3ResponseWriter
buf []interface{}
totalSize int
writer Web3ResponseWriter
buf []json.RawMessage
}

// NewBatchWriter returns a new BatchWriter
func NewBatchWriter(singleWriter Web3ResponseWriter) *BatchWriter {
return &BatchWriter{
writer: singleWriter,
buf: make([]interface{}, 0),
writer: singleWriter,
buf: make([]json.RawMessage, 0),
}
}

// Write adds data into batch buffer
func (w *BatchWriter) Write(in interface{}) error {
w.buf = append(w.buf, in)
raw, err := json.Marshal(in)
if err != nil {
return err
}
w.totalSize += len(raw)
if w.totalSize > MaxResponseSize {
return errors.New("response size exceeds limit")
}
w.buf = append(w.buf, raw)
return nil
}

Expand Down
8 changes: 8 additions & 0 deletions api/web3server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"

apitypes "github.com/iotexproject/iotex-core/api/types"
"github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice"
)

Expand Down Expand Up @@ -105,6 +106,13 @@ func TestHandlePost(t *testing.T) {
require.True(gjson.Valid(string(bodyBytes5)))
require.Equal(2, len(gjson.Parse(string(bodyBytes5)).Array()))

// multiple web3 req with big batch
apitypes.MaxResponseSize = 1024 * 1024 // fake max response size
request8, _ := http.NewRequest(http.MethodPost, "http://url.com", strings.NewReader(`[`+strings.Repeat(`{"jsonrpc":"2.0","method":"eth_mining","params":[],"id":1},`, 100000)+`{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":2}]`))
response8 := getServerResp(svr, request8)
bodyBytes8, _ := io.ReadAll(response8.Body)
require.Equal(len(bodyBytes8), 0)

// multiple web3 req2
request6, _ := http.NewRequest(http.MethodPost, "http://url.com", strings.NewReader(`[{"jsonrpc":"2.0","method":"eth_mining","params":[],"id":1}]`))
response6 := getServerResp(svr, request6)
Expand Down

0 comments on commit e3805a2

Please sign in to comment.