api/handler: use http.MaxBytesReader and buffer pool (#1415)

* api/handler: use http.MaxBytesReader

protect api handlers from OOM cases

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
2020-03-26 14:29:28 +03:00
committed by GitHub
parent 776a7d6cd6
commit 02839cfba5
9 changed files with 146 additions and 51 deletions

View File

@@ -3,7 +3,6 @@ package broker
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"strings"
@@ -15,6 +14,11 @@ import (
"github.com/micro/go-micro/v2/api/handler"
"github.com/micro/go-micro/v2/broker"
"github.com/micro/go-micro/v2/logger"
"github.com/oxtoacart/bpool"
)
var (
bufferPool = bpool.NewSizedBufferPool(1024, 8)
)
const (
@@ -155,6 +159,13 @@ func (c *conn) writeLoop() {
}
func (b *brokerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
bsize := handler.DefaultMaxRecvSize
if b.opts.MaxRecvSize > 0 {
bsize = b.opts.MaxRecvSize
}
r.Body = http.MaxBytesReader(w, r.Body, bsize)
br := b.opts.Service.Client().Options().Broker
// Setup the broker
@@ -191,14 +202,15 @@ func (b *brokerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
// Read body
b, err := ioutil.ReadAll(r.Body)
if err != nil {
buf := bufferPool.Get()
defer bufferPool.Put(buf)
if _, err := buf.ReadFrom(r.Body); err != nil {
http.Error(w, err.Error(), 500)
return
}
// Set body
msg.Body = b
msg.Body = buf.Bytes()
// Set body
// Publish
br.Publish(topic, msg)