github.com/qiniu/x@v1.11.9/bytes/seekable/seekable.go (about)

     1  // This package provide a method to read and replace http.Request's body.
     2  package seekable
     3  
     4  import (
     5  	"errors"
     6  	"io"
     7  	"io/ioutil"
     8  	"net/http"
     9  
    10  	"github.com/qiniu/x/bytes"
    11  )
    12  
    13  // ---------------------------------------------------
    14  
    15  type Seekabler interface {
    16  	Bytes() []byte
    17  	Read(val []byte) (n int, err error)
    18  	SeekToBegin() error
    19  }
    20  
    21  type SeekableCloser interface {
    22  	Seekabler
    23  	io.Closer
    24  }
    25  
    26  // ---------------------------------------------------
    27  
    28  type readCloser struct {
    29  	Seekabler
    30  	io.Closer
    31  }
    32  
    33  var ErrNoBody = errors.New("no body")
    34  
    35  func New(req *http.Request) (r SeekableCloser, err error) {
    36  	if req.Body == nil {
    37  		return nil, ErrNoBody
    38  	}
    39  	var ok bool
    40  	if r, ok = req.Body.(SeekableCloser); ok {
    41  		return
    42  	}
    43  	b, err2 := ReadAll(req)
    44  	if err2 != nil {
    45  		return nil, err2
    46  	}
    47  	r = bytes.NewReader(b)
    48  	req.Body = readCloser{r, req.Body}
    49  	return
    50  }
    51  
    52  func ReadAll(req *http.Request) (b []byte, err error) {
    53  	if req.ContentLength > 0 {
    54  		b = make([]byte, int(req.ContentLength))
    55  		_, err = io.ReadFull(req.Body, b)
    56  		return
    57  	} else if req.ContentLength == 0 {
    58  		return nil, ErrNoBody
    59  	}
    60  	return ioutil.ReadAll(req.Body)
    61  }
    62  
    63  // ---------------------------------------------------