Skip to content

Golang io.Reader and io.Writer but with limits

License

Notifications You must be signed in to change notification settings

nanmu42/limitio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LimitIO

GoDoc Build status codecov Go Report Card

io.Reader and io.Writer with limit.

go get github.com/nanmu42/limitio

Rationale and Usage

There are times when a limited reader or writer comes in handy.

  1. wrap upstream so that reading is metered and limited:
// request is an incoming http.Request
request.Body = limitio.NewReadCloser(c.Request.Body, maxRequestBodySize, false)

// deal with the body now with easy mind. It's maximum size is assured.

Yes, io.LimitReader works the same way, but throws EOF on exceeding limit, which is confusing.

LimitIO provides error that can be identified.

decoder := json.NewDecoder(request.Body)
err := decoder.Decode(&myStruct)
if err != nil {
    if errors.Is(err, limitio.ErrThresholdExceeded) {
        // oops, we reached the limit
    }

    err = fmt.Errorf("other error happened: %w", err)
    return
}
  1. wrap downstream so that writing is metered and limited(or instead, just pretending writing):
// request is an incoming http.Request.
// Say, we want to record its body somewhere in the middleware,
// but feeling uneasy since its body might be HUGE, which may
// result in OOM and a successful DDOS...

var reqBuf bytes.buffer

// a limited writer comes to rescue!
// `true` means after reaching `RequestBodyMaxLength`,
// `limitedReqBuf` will start pretending writing so that
// io.TeeReader continues working while reqBuf stays unmodified.
limitedReqBuf := limitio.NewWriter(&reqBuf, RequestBodyMaxLength, true)

request.Body = &readCloser{
    Reader: io.TeeReader(request.Body, limitedReqBuf), 
    Closer: c.Request.Body,
}

LimitIO provides Reader, Writer and their Closer versions, for details, see docs.

Status: Stable

LimitIO is well battle tested under production environment.

APIs are subjected to change in backward compatible way during 1.x releases.

License

MIT License

Copyright (c) 2021 LI Zhennan