Skip to content

Commit

Permalink
[plugin] Limits http body read length at correct place
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyanliu authored and Jack47 committed Dec 13, 2017
1 parent 25a998d commit 580d05a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 19 deletions.
22 changes: 22 additions & 0 deletions src/common/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,25 @@ func (tw *TimeWriter) Write(p []byte) (n int, err error) { // io.Write stub
defer tw.timeTrack(time.Now())
return tw.w.Write(p)
}

////

type readerWithCloser struct {
reader io.Reader
closer io.Closer
}

func IOReaderToReaderCloser(reader io.Reader, closer io.Closer) *readerWithCloser {
return &readerWithCloser{
reader: reader,
closer: closer,
}
}

func (rwc *readerWithCloser) Read(p []byte) (n int, err error) { // io.Reader stub
return rwc.reader.Read(p)
}

func (rwc *readerWithCloser) Close() error { // io.Closer stub
return rwc.closer.Close()
}
7 changes: 6 additions & 1 deletion src/plugins/http_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ func (h *httpInput) Prepare(ctx pipelines.PipelineContext) {
func (h *httpInput) handler(w http.ResponseWriter, req *http.Request, urlParams map[string]string,
routeDuration time.Duration) {

if req.ContentLength >= 0 { // content length is known
reader := io.LimitReader(req.Body, req.ContentLength)
req.Body = common.IOReaderToReaderCloser(reader, req.Body)
}

if h.conf.Unzip && strings.Contains(req.Header.Get("Content-Encoding"), "gzip") {
var err error
req.Body, err = gzip.NewReader(req.Body)
Expand Down Expand Up @@ -617,7 +622,7 @@ func logRequest(ht *httpTask, t task.Task, responseCodeKey, responseRemoteKey,
responseDurationKey string, readRespBodyElapse, writeClientBodyElapse, readClientBodyElapse time.Duration,
bodyBytesSent int64, routeDuration time.Duration) {

var responseRemote string = ""
var responseRemote = ""
value := t.Value(responseRemoteKey)
if value != nil {
rr, ok := value.(string)
Expand Down
20 changes: 2 additions & 18 deletions src/plugins/http_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"os"
"path"
"path/filepath"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -326,28 +325,13 @@ func (h *httpOutput) Run(ctx pipelines.PipelineContext, t task.Task) error {
var reader io.Reader
if len(h.conf.RequestBodyIOKey) != 0 {
inputValue := t.Value(h.conf.RequestBodyIOKey)
input, ok := inputValue.(io.Reader)
ok := false
reader, ok = inputValue.(io.Reader)
if !ok {
t.SetError(fmt.Errorf("input %s got wrong value: %#v", h.conf.RequestBodyIOKey, inputValue),
task.ResultMissingInput)
return nil
}

// optimization and defensive for http proxy case
lenValue := t.Value("HTTP_CONTENT_LENGTH")
clen, ok := lenValue.(string)
if ok {
var err error
length, err = strconv.ParseInt(clen, 10, 64)
if err == nil && length >= 0 {
reader = io.LimitReader(input, length)
} else {
reader = input
}
} else {
// Request.ContentLength of 0 means either actually 0 or unknown
reader = input
}
} else {
// skip error check safely due to we ensured it in Prepare()
body, _ := ReplaceTokensInPattern(t, h.conf.RequestBodyBufferPattern)
Expand Down

0 comments on commit 580d05a

Please sign in to comment.