Skip to content

Commit

Permalink
Merge pull request #29 from favclip/fix-consume-body
Browse files Browse the repository at this point in the history
fix(ucon): don't consume request body when Content-Type is not applic…
  • Loading branch information
vvakame authored Apr 13, 2019
2 parents ec80ec1 + 75e790b commit 9bfb742
Show file tree
Hide file tree
Showing 6 changed files with 454 additions and 86 deletions.
22 changes: 11 additions & 11 deletions middleware_builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,23 +165,23 @@ func RequestObjectMapper() MiddlewareFunc {
}
}

var body []byte
var err error
if b.R.Body != nil {
// this case occured in unit test
defer b.R.Body.Close()
body, err = ioutil.ReadAll(b.R.Body)
}
if err != nil {
return err
}

// request body as JSON
{
// where is the spec???
ct := strings.Split(b.R.Header.Get("Content-Type"), ";")
// TODO check charset
if ct[0] == "application/json" {
var body []byte
var err error
if b.R.Body != nil {
// this case occured in unit test
defer b.R.Body.Close()
body, err = ioutil.ReadAll(b.R.Body)
}
if err != nil {
return err
}

if len(body) == 2 {
// dirty hack. {} map to []interface or [] map to normal struct.
} else if len(body) != 0 {
Expand Down
135 changes: 115 additions & 20 deletions sample/appengine/model_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,43 @@ type TodoPropertyDecoder func(src *TodoJSON, dest *Todo) error

// TodoPropertyInfo stores property information.
type TodoPropertyInfo struct {
name string
Encoder TodoPropertyEncoder
Decoder TodoPropertyDecoder
fieldName string
jsonName string
Encoder TodoPropertyEncoder
Decoder TodoPropertyDecoder
}

// FieldName returns struct field name of property.
func (info *TodoPropertyInfo) FieldName() string {
return info.fieldName
}

// JSONName returns json field name of property.
func (info *TodoPropertyInfo) JSONName() string {
return info.jsonName
}

// TodoJSONBuilder convert between Todo to TodoJSON mutually.
type TodoJSONBuilder struct {
_properties map[string]*TodoPropertyInfo
ID *TodoPropertyInfo
Text *TodoPropertyInfo
Done *TodoPropertyInfo
UpdatedAt *TodoPropertyInfo
CreatedAt *TodoPropertyInfo
_properties map[string]*TodoPropertyInfo
_jsonPropertyMap map[string]*TodoPropertyInfo
_structPropertyMap map[string]*TodoPropertyInfo
ID *TodoPropertyInfo
Text *TodoPropertyInfo
Done *TodoPropertyInfo
UpdatedAt *TodoPropertyInfo
CreatedAt *TodoPropertyInfo
}

// NewTodoJSONBuilder make new TodoJSONBuilder.
func NewTodoJSONBuilder() *TodoJSONBuilder {
return &TodoJSONBuilder{
_properties: map[string]*TodoPropertyInfo{},
jb := &TodoJSONBuilder{
_properties: map[string]*TodoPropertyInfo{},
_jsonPropertyMap: map[string]*TodoPropertyInfo{},
_structPropertyMap: map[string]*TodoPropertyInfo{},
ID: &TodoPropertyInfo{
name: "ID",
fieldName: "ID",
jsonName: "id",
Encoder: func(src *Todo, dest *TodoJSON) error {
if src == nil {
return nil
Expand All @@ -64,7 +80,8 @@ func NewTodoJSONBuilder() *TodoJSONBuilder {
},
},
Text: &TodoPropertyInfo{
name: "Text",
fieldName: "Text",
jsonName: "text",
Encoder: func(src *Todo, dest *TodoJSON) error {
if src == nil {
return nil
Expand All @@ -81,7 +98,8 @@ func NewTodoJSONBuilder() *TodoJSONBuilder {
},
},
Done: &TodoPropertyInfo{
name: "Done",
fieldName: "Done",
jsonName: "done",
Encoder: func(src *Todo, dest *TodoJSON) error {
if src == nil {
return nil
Expand All @@ -98,7 +116,8 @@ func NewTodoJSONBuilder() *TodoJSONBuilder {
},
},
UpdatedAt: &TodoPropertyInfo{
name: "UpdatedAt",
fieldName: "UpdatedAt",
jsonName: "updatedAt",
Encoder: func(src *Todo, dest *TodoJSON) error {
if src == nil {
return nil
Expand All @@ -115,7 +134,8 @@ func NewTodoJSONBuilder() *TodoJSONBuilder {
},
},
CreatedAt: &TodoPropertyInfo{
name: "CreatedAt",
fieldName: "CreatedAt",
jsonName: "createdAt",
Encoder: func(src *Todo, dest *TodoJSON) error {
if src == nil {
return nil
Expand All @@ -132,6 +152,28 @@ func NewTodoJSONBuilder() *TodoJSONBuilder {
},
},
}
jb._structPropertyMap["ID"] = jb.ID
jb._jsonPropertyMap["id"] = jb.ID
jb._structPropertyMap["Text"] = jb.Text
jb._jsonPropertyMap["text"] = jb.Text
jb._structPropertyMap["Done"] = jb.Done
jb._jsonPropertyMap["done"] = jb.Done
jb._structPropertyMap["UpdatedAt"] = jb.UpdatedAt
jb._jsonPropertyMap["updatedAt"] = jb.UpdatedAt
jb._structPropertyMap["CreatedAt"] = jb.CreatedAt
jb._jsonPropertyMap["createdAt"] = jb.CreatedAt
return jb
}

// Properties returns all properties on TodoJSONBuilder.
func (b *TodoJSONBuilder) Properties() []*TodoPropertyInfo {
return []*TodoPropertyInfo{
b.ID,
b.Text,
b.Done,
b.UpdatedAt,
b.CreatedAt,
}
}

// AddAll adds all property to TodoJSONBuilder.
Expand All @@ -145,14 +187,67 @@ func (b *TodoJSONBuilder) AddAll() *TodoJSONBuilder {
}

// Add specified property to TodoJSONBuilder.
func (b *TodoJSONBuilder) Add(info *TodoPropertyInfo) *TodoJSONBuilder {
b._properties[info.name] = info
func (b *TodoJSONBuilder) Add(infos ...*TodoPropertyInfo) *TodoJSONBuilder {
for _, info := range infos {
b._properties[info.fieldName] = info
}
return b
}

// AddByJSONNames add properties to TodoJSONBuilder by JSON property name. if name is not in the builder, it will ignore.
func (b *TodoJSONBuilder) AddByJSONNames(names ...string) *TodoJSONBuilder {
for _, name := range names {
info := b._jsonPropertyMap[name]
if info == nil {
continue
}
b._properties[info.fieldName] = info
}
return b
}

// AddByNames add properties to TodoJSONBuilder by struct property name. if name is not in the builder, it will ignore.
func (b *TodoJSONBuilder) AddByNames(names ...string) *TodoJSONBuilder {
for _, name := range names {
info := b._structPropertyMap[name]
if info == nil {
continue
}
b._properties[info.fieldName] = info
}
return b
}

// Remove specified property to TodoJSONBuilder.
func (b *TodoJSONBuilder) Remove(info *TodoPropertyInfo) *TodoJSONBuilder {
delete(b._properties, info.name)
func (b *TodoJSONBuilder) Remove(infos ...*TodoPropertyInfo) *TodoJSONBuilder {
for _, info := range infos {
delete(b._properties, info.fieldName)
}
return b
}

// RemoveByJSONNames remove properties to TodoJSONBuilder by JSON property name. if name is not in the builder, it will ignore.
func (b *TodoJSONBuilder) RemoveByJSONNames(names ...string) *TodoJSONBuilder {

for _, name := range names {
info := b._jsonPropertyMap[name]
if info == nil {
continue
}
delete(b._properties, info.fieldName)
}
return b
}

// RemoveByNames remove properties to TodoJSONBuilder by struct property name. if name is not in the builder, it will ignore.
func (b *TodoJSONBuilder) RemoveByNames(names ...string) *TodoJSONBuilder {
for _, name := range names {
info := b._structPropertyMap[name]
if info == nil {
continue
}
delete(b._properties, info.fieldName)
}
return b
}

Expand Down
Loading

0 comments on commit 9bfb742

Please sign in to comment.