Skip to content

Commit

Permalink
Fix request.body rego builtin sporadic unexpected EOF
Browse files Browse the repository at this point in the history
  • Loading branch information
cclerget committed Jan 15, 2024
1 parent 6aec20b commit cea17b6
Showing 1 changed file with 19 additions and 43 deletions.
62 changes: 19 additions & 43 deletions internal/pkg/router/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"io"
"net/http"
"strings"
"sync"

"github.com/distribution/distribution/v3"
"github.com/distribution/reference"
Expand Down Expand Up @@ -129,22 +128,6 @@ var ociBlobDigestBuiltin = rego.Function3(
},
)

type bodyCloser struct {
io.Reader
closeFn func() error
}

func (bc bodyCloser) Close() error {
return bc.closeFn()
}

var bufferPool = sync.Pool{
New: func() interface{} {
buffer := make([]byte, 8192)
return &buffer
},
}

var requestBodyBuiltin = rego.FunctionDyn(
&rego.Function{
Name: "request.body",
Expand All @@ -165,38 +148,31 @@ var requestBodyBuiltin = rego.FunctionDyn(
}
}()

if funcContext.req.Body != nil && funcContext.req.Body != http.NoBody {
buf := bufferPool.Get().(*[]byte)

n, err := io.ReadAtLeast(funcContext.req.Body, *buf, 1)
if err != nil {
return nil, fmt.Errorf("empty body request")
}

bodyReader := bytes.NewReader((*buf)[:n])

v, err := ast.ValueFromReader(bodyReader)
if err != nil {
return nil, err
}
if funcContext.req.Body == nil || funcContext.req.Body == http.NoBody {
v, err := ast.InterfaceToValue(nil)
return ast.NewTerm(v), err
}

_, _ = bodyReader.Seek(0, io.SeekStart)
buf := new(bytes.Buffer)

originalBody := funcContext.req.Body
_, err := buf.ReadFrom(io.LimitReader(funcContext.req.Body, 8192))
if err != nil {
return nil, err
} else if err := funcContext.req.Body.Close(); err != nil {
return nil, err
}

funcContext.req.Body = &bodyCloser{
Reader: bodyReader,
closeFn: func() error {
defer bufferPool.Put(buf)
return originalBody.Close()
},
}
bodyReader := bytes.NewReader(buf.Bytes())

return ast.NewTerm(v), nil
v, err := ast.ValueFromReader(bodyReader)
if err != nil {
return nil, err
} else if _, err = bodyReader.Seek(0, io.SeekStart); err != nil {
return nil, err
}

v, err := ast.InterfaceToValue(nil)
funcContext.req.Body = io.NopCloser(bodyReader)

return ast.NewTerm(v), err
return ast.NewTerm(v), nil
},
)

0 comments on commit cea17b6

Please sign in to comment.