add multiple methods support for united routes registering (#2664)

This commit is contained in:
John Guo 2023-05-25 10:58:06 +08:00 committed by GitHub
parent 368312c816
commit 2329622564
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 26 deletions

View File

@ -8,9 +8,6 @@ package utils
import (
"io"
"io/ioutil"
"github.com/gogf/gf/v2/errors/gerror"
)
// ReadCloser implements the io.ReadCloser interface
@ -20,7 +17,7 @@ import (
type ReadCloser struct {
index int // Current read position.
content []byte // Content.
repeatable bool
repeatable bool // Mark the content can be repeatable read.
}
// NewReadCloser creates and returns a RepeatReadCloser object.
@ -31,30 +28,15 @@ func NewReadCloser(content []byte, repeatable bool) io.ReadCloser {
}
}
// NewReadCloserWithReadCloser creates and returns a RepeatReadCloser object
// with given io.ReadCloser.
func NewReadCloserWithReadCloser(r io.ReadCloser, repeatable bool) (io.ReadCloser, error) {
content, err := ioutil.ReadAll(r)
if err != nil {
err = gerror.Wrapf(err, `ioutil.ReadAll failed`)
return nil, err
}
defer r.Close()
return &ReadCloser{
content: content,
repeatable: repeatable,
}, nil
}
// Read implements the io.ReadCloser interface.
func (b *ReadCloser) Read(p []byte) (n int, err error) {
// Make it repeatable reading.
if b.index >= len(b.content) && b.repeatable {
b.index = 0
}
n = copy(p, b.content[b.index:])
b.index += n
if b.index >= len(b.content) {
// Make it repeatable reading.
if b.repeatable {
b.index = 0
}
return n, io.EOF
}
return n, nil

View File

@ -153,6 +153,13 @@ func (r *Request) Get(key string, def ...interface{}) *gvar.Var {
// GetBody retrieves and returns request body content as bytes.
// It can be called multiple times retrieving the same body content.
func (r *Request) GetBody() []byte {
if r.bodyContent == nil {
r.bodyContent = r.makeBodyRepeatableRead(true)
}
return r.bodyContent
}
func (r *Request) makeBodyRepeatableRead(repeatableRead bool) []byte {
if r.bodyContent == nil {
var err error
if r.bodyContent, err = ioutil.ReadAll(r.Body); err != nil {
@ -162,8 +169,8 @@ func (r *Request) GetBody() []byte {
}
panic(gerror.WrapCode(gcode.CodeInternalError, err, errMsg))
}
r.Body = utils.NewReadCloser(r.bodyContent, true)
}
r.Body = utils.NewReadCloser(r.bodyContent, repeatableRead)
return r.bodyContent
}
@ -261,6 +268,8 @@ func (r *Request) parseForm() {
return
}
if contentType := r.Header.Get("Content-Type"); contentType != "" {
// Mark the request body content can be read just once next time.
r.makeBodyRepeatableRead(false)
var err error
if gstr.Contains(contentType, "multipart/") {
// multipart/form-data, multipart/mixed
@ -274,7 +283,7 @@ func (r *Request) parseForm() {
}
}
if len(r.PostForm) > 0 {
// Re-parse the form data using united parsing way.
// Parse the form data using united parsing way.
params := ""
for name, values := range r.PostForm {
// Invalid parameter name.

View File

@ -155,7 +155,7 @@ func Test_ClientMaxBodySize_File(t *testing.T) {
defer gfile.Remove(path)
t.Assert(
gstr.Trim(c.PostContent(ctx, "/", "name=john&file=@file:"+path)),
"r.ParseMultipartForm failed: http: request body too large",
"Read from request Body failed: http: request body too large",
)
})
}