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 // ---------------------------------------------------