func (b *buffer) Put(buf []byte) {
	size := atomic.LoadUint64(b.size)
	bufLen := uint64(len(buf))
	bufCap := uint64(cap(buf))
	if bufLen >= size || bufCap >= size {
		size = max(bufLen, bufCap)  
		buf = make([]byte, 0, size)
		atomic.StoreUint64(b.size, size)
	}
	b.pool.Put(buf[:0])
}
Put adds the given slice back to internal pool, but resets its length to 0.
If the given slice have capacity > current new buffer size in the pool, all newly created byte slices from Get() will have capacity which equals to the given slice. Capacity of slices already in the pool will not be affected.
package infra
import (
	"net/http/httputil"
	"sync"
	"sync/atomic"
)
type buffer struct {
	pool sync.Pool
	size *uint64
}
func NewBuffer(size uint64) httputil.BufferPool {
	if size == 0 {
		return nil
	}
	return &buffer{
		pool: sync.Pool{
			New: func() interface{} {
				return make([]byte, 0, size)
			},
		},
		size: &size,
	}
}
func (b *buffer) Get() []byte {
	return b.pool.Get().([]byte)
}