Skip to content
This repository has been archived by the owner on Apr 11, 2020. It is now read-only.

Commit

Permalink
refactor: udpate module
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Aug 15, 2019
1 parent 818dbf6 commit 6fb2075
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 80 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# cod-body-parser
# elton-body-parser

[![Build Status](https://img.shields.io/travis/vicanso/cod-body-parser.svg?label=linux+build)](https://travis-ci.org/vicanso/cod-body-parser)
[![Build Status](https://img.shields.io/travis/vicanso/elton-body-parser.svg?label=linux+build)](https://travis-ci.org/vicanso/elton-body-parser)

Body parser for cod. It support `application/json` and `application/x-www-form-urlencoded` type, but `NewDefault` just support `application/json`.
Body parser for elton. It support `application/json` and `application/x-www-form-urleneltoned` type, but `NewDefault` just support `application/json`.

```go
package main

import (
"bytes"

"github.com/vicanso/cod"
bodyparser "github.com/vicanso/cod-body-parser"
"github.com/vicanso/elton"
bodyparser "github.com/vicanso/elton-body-parser"
)

func main() {
d := cod.New()
d := elton.New()

d.Use(bodyparser.NewDefault())

d.POST("/user/login", func(c *cod.Context) (err error) {
d.POST("/user/login", func(c *elton.Context) (err error) {
c.BodyBuffer = bytes.NewBuffer(c.RequestBody)
return
})
Expand Down
68 changes: 34 additions & 34 deletions body_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,33 @@ import (
"net/url"
"strings"

"github.com/vicanso/cod"
"github.com/vicanso/elton"
"github.com/vicanso/hes"
)

const (
// ErrCategory body parser error category
ErrCategory = "cod-body-parser"
ErrCategory = "elton-body-parser"
// 默认为50kb
defaultRequestBodyLimit = 50 * 1024
jsonContentType = "application/json"
formURLEncodedContentType = "application/x-www-form-urlencoded"
defaultRequestBodyLimit = 50 * 1024
jsonContentType = "application/json"
formURLEneltonedContentType = "application/x-www-form-urleneltoned"
)

type (
// Decode body decode function
Decode func(c *cod.Context, originalData []byte) (data []byte, err error)
// Deeltone body deeltone function
Deeltone func(c *elton.Context, originalData []byte) (data []byte, err error)
// Config json parser config
Config struct {
// Limit the limit size of body
Limit int
// IgnoreJSON ignore json type
IgnoreJSON bool
// IgnoreFormURLEncoded ignore form url encoded type
IgnoreFormURLEncoded bool
// Decode decode function
Decode Decode
Skipper cod.Skipper
// IgnoreFormURLEneltoned ignore form url eneltoned type
IgnoreFormURLEneltoned bool
// Deeltone deeltone function
Deeltone Deeltone
Skipper elton.Skipper
}
)

Expand All @@ -61,21 +61,21 @@ var (
}
)

// DefaultDecode default decode
func DefaultDecode(c *cod.Context, data []byte) ([]byte, error) {
encoding := c.GetRequestHeader(cod.HeaderContentEncoding)
if encoding == cod.Gzip {
c.SetRequestHeader(cod.HeaderContentEncoding, "")
// DefaultDeeltone default deeltone
func DefaultDeeltone(c *elton.Context, data []byte) ([]byte, error) {
eneltoning := c.GetRequestHeader(elton.HeaderContentEncoding)
if eneltoning == elton.Gzip {
c.SetRequestHeader(elton.HeaderContentEncoding, "")
return doGunzip(data)
}
return data, nil
}

// NewDefault create a default body parser, default limit and only json parser
func NewDefault() cod.Handler {
func NewDefault() elton.Handler {
return New(Config{
IgnoreFormURLEncoded: true,
Decode: DefaultDecode,
IgnoreFormURLEneltoned: true,
Deeltone: DefaultDeeltone,
})
}

Expand All @@ -90,16 +90,16 @@ func doGunzip(buf []byte) ([]byte, error) {
}

// New create a body parser
func New(config Config) cod.Handler {
func New(config Config) elton.Handler {
limit := defaultRequestBodyLimit
if config.Limit != 0 {
limit = config.Limit
}
skipper := config.Skipper
if skipper == nil {
skipper = cod.DefaultSkipper
skipper = elton.DefaultSkipper
}
return func(c *cod.Context) (err error) {
return func(c *elton.Context) (err error) {
if skipper(c) || c.RequestBody != nil {
return c.Next()
}
Expand All @@ -116,23 +116,23 @@ func New(config Config) cod.Handler {
if !valid {
return c.Next()
}
ct := c.GetRequestHeader(cod.HeaderContentType)
ct := c.GetRequestHeader(elton.HeaderContentType)
ctFields := strings.Split(ct, ";")
// 非json则跳过
isJSON := ctFields[0] == jsonContentType
isFormURLEncoded := ctFields[0] == formURLEncodedContentType
isFormURLEneltoned := ctFields[0] == formURLEneltonedContentType

// 如果不是 json 也不是 form url encoded,则跳过
if !isJSON && !isFormURLEncoded {
// 如果不是 json 也不是 form url eneltoned,则跳过
if !isJSON && !isFormURLEneltoned {
return c.Next()
}
// 如果数据类型json,而且中间件不处理,则跳过
if isJSON && config.IgnoreJSON {
return c.Next()
}

// 如果数据类型form url encoded,而且中间件不处理,则跳过
if isFormURLEncoded && config.IgnoreFormURLEncoded {
// 如果数据类型form url eneltoned,而且中间件不处理,则跳过
if isFormURLEneltoned && config.IgnoreFormURLEneltoned {
return c.Next()
}

Expand All @@ -157,15 +157,15 @@ func New(config Config) cod.Handler {
}
return
}
if config.Decode != nil {
// 对提交数据做decode处理(如编码转换等)
body, err = config.Decode(c, body)
if config.Deeltone != nil {
// 对提交数据做deeltone处理(如编码转换等)
body, err = config.Deeltone(c, body)
if err != nil {
return
}
}
// 将form url encoded 数据转化为json
if isFormURLEncoded {
// 将form url eneltoned 数据转化为json
if isFormURLEneltoned {
data, err := url.ParseQuery(string(body))
if err != nil {
he := hes.Wrap(err)
Expand Down
70 changes: 35 additions & 35 deletions body_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/vicanso/cod"
"github.com/vicanso/elton"
"github.com/vicanso/hes"
)

Expand Down Expand Up @@ -40,7 +40,7 @@ func NewErrorReadCloser(err error) io.ReadCloser {
return r
}

func TestDefaultDecode(t *testing.T) {
func TestDefaultDeeltone(t *testing.T) {
assert := assert.New(t)
originalBuf := []byte("abcdabcdabcd")
var b bytes.Buffer
Expand All @@ -49,14 +49,14 @@ func TestDefaultDecode(t *testing.T) {
assert.Nil(err)
w.Close()

c := cod.NewContext(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
c := elton.NewContext(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))

buf, err := DefaultDecode(c, b.Bytes())
buf, err := DefaultDeeltone(c, b.Bytes())
assert.Nil(err)
assert.Equal(b.Bytes(), buf)

c.SetRequestHeader(cod.HeaderContentEncoding, cod.Gzip)
buf, err = DefaultDecode(c, b.Bytes())
c.SetRequestHeader(elton.HeaderContentEncoding, elton.Gzip)
buf, err = DefaultDeeltone(c, b.Bytes())
assert.Nil(err)
assert.Equal(originalBuf, buf)
}
Expand All @@ -65,15 +65,15 @@ func TestBodyParser(t *testing.T) {
t.Run("skip", func(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{
Skipper: func(c *cod.Context) bool {
Skipper: func(c *elton.Context) bool {
return true
},
})

body := `{"name": "tree.xie"}`
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(body))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -91,8 +91,8 @@ func TestBodyParser(t *testing.T) {

body := `{"name": "tree.xie"}`
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(body))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -110,7 +110,7 @@ func TestBodyParser(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{})
req := httptest.NewRequest("GET", "https://aslant.site/", nil)
c := cod.NewContext(nil, req)
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -125,7 +125,7 @@ func TestBodyParser(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{})
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader("abc"))
c := cod.NewContext(nil, req)
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -140,11 +140,11 @@ func TestBodyParser(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{})
req := httptest.NewRequest("POST", "https://aslant.site/", NewErrorReadCloser(hes.New("abc")))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
err := bodyParser(c)
assert.NotNil(err)
assert.Equal(err.Error(), "category=cod-body-parser, message=message=abc")
assert.Equal(err.Error(), "category=elton-body-parser, message=message=abc")
})

t.Run("body over limit size", func(t *testing.T) {
Expand All @@ -153,11 +153,11 @@ func TestBodyParser(t *testing.T) {
Limit: 1,
})
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader("abc"))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
err := bodyParser(c)
assert.NotNil(err)
assert.Equal(err.Error(), "category=cod-body-parser, message=request body is 3 bytes, it should be <= 1")
assert.Equal(err.Error(), "category=elton-body-parser, message=request body is 3 bytes, it should be <= 1")
})

t.Run("ignore json and content type is json", func(t *testing.T) {
Expand All @@ -166,8 +166,8 @@ func TestBodyParser(t *testing.T) {
IgnoreJSON: true,
})
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader("abc"))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -179,15 +179,15 @@ func TestBodyParser(t *testing.T) {
assert.Equal(len(c.RequestBody), 0)
})

t.Run("ignore form url encoded and content type is form url encoded", func(t *testing.T) {
t.Run("ignore form url eneltoned and content type is form url eneltoned", func(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{
IgnoreFormURLEncoded: true,
IgnoreFormURLEneltoned: true,
})
body := `name=tree.xie&type=1`
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(body))
req.Header.Set(cod.HeaderContentType, "application/x-www-form-urlencoded")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/x-www-form-urleneltoned")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -204,8 +204,8 @@ func TestBodyParser(t *testing.T) {
bodyParser := New(Config{})
body := `{"name": "tree.xie"}`
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(body))
req.Header.Set(cod.HeaderContentType, "application/json")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -219,11 +219,11 @@ func TestBodyParser(t *testing.T) {
assert.True(done)
})

t.Run("decode data success", func(t *testing.T) {
t.Run("deeltone data success", func(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{
Decode: func(c *cod.Context, data []byte) ([]byte, error) {
if strings.HasSuffix(c.GetRequestHeader(cod.HeaderContentType), "charset=base64") {
Deeltone: func(c *elton.Context, data []byte) ([]byte, error) {
if strings.HasSuffix(c.GetRequestHeader(elton.HeaderContentType), "charset=base64") {
return base64.RawStdEncoding.DecodeString(string(data))
}
return data, nil
Expand All @@ -232,8 +232,8 @@ func TestBodyParser(t *testing.T) {
body := `{"name": "tree.xie"}`
b64 := base64.RawStdEncoding.EncodeToString([]byte(body))
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(b64))
req.Header.Set(cod.HeaderContentType, "application/json;charset=base64")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/json;charset=base64")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand All @@ -247,13 +247,13 @@ func TestBodyParser(t *testing.T) {
assert.True(done)
})

t.Run("parse form url encoded success", func(t *testing.T) {
t.Run("parse form url eneltoned success", func(t *testing.T) {
assert := assert.New(t)
bodyParser := New(Config{})
body := `name=tree.xie&type=1&type=2`
req := httptest.NewRequest("POST", "https://aslant.site/", strings.NewReader(body))
req.Header.Set(cod.HeaderContentType, "application/x-www-form-urlencoded")
c := cod.NewContext(nil, req)
req.Header.Set(elton.HeaderContentType, "application/x-www-form-urleneltoned")
c := elton.NewContext(nil, req)
done := false
c.Next = func() error {
done = true
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ go 1.12

require (
github.com/stretchr/testify v1.3.0
github.com/vicanso/cod v0.1.1
github.com/vicanso/hes v0.1.4
github.com/vicanso/elton v0.2.0
github.com/vicanso/hes v0.2.1
)
Loading

0 comments on commit 6fb2075

Please sign in to comment.