Skip to content

Commit

Permalink
Merge branch 'feature/app-extends-params' into 'develop'
Browse files Browse the repository at this point in the history
应用支持额外参数

See merge request goku/apinto!115
  • Loading branch information
刘健 committed Sep 27, 2022
2 parents f6ba8b8 + f27180f commit 0c6770e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 89 deletions.
145 changes: 71 additions & 74 deletions drivers/app/extend-param.go
Original file line number Diff line number Diff line change
@@ -1,117 +1,87 @@
package app

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"mime"
"net/textproto"
"strings"

http_context "github.com/eolinker/apinto/node/http-context"
"github.com/ohler55/ojg/oj"

"github.com/eolinker/apinto/application"
"github.com/ohler55/ojg/jp"
"github.com/ohler55/ojg/oj"

http_service "github.com/eolinker/eosc/eocontext/http-context"
)
http_context "github.com/eolinker/apinto/node/http-context"

var (
FormParamType = "application/x-www-form-urlencoded"
JsonType = "application/json"
"github.com/eolinker/apinto/application"
http_service "github.com/eolinker/eosc/eocontext/http-context"
)

type additionalParam struct {
params []*Additional
needRawBody bool
params []*Additional
}

func newAdditionalParam(params []*Additional) *additionalParam {
needRawBody := false
for _, p := range params {
if p.Position == application.PositionBody {
needRawBody = true
break
}
}
return &additionalParam{params: params, needRawBody: needRawBody}
}

func (a *additionalParam) getBody(ctx http_service.IHttpContext) (string, bool) {
needBody := false
body := ""
if a.needRawBody {
method := ctx.Proxy().Method()
if method == http.MethodPost || method == http.MethodPut || method == http.MethodPatch {
b, _ := ctx.Proxy().Body().RawBody()

needBody = true
body = string(b)
}
}
return body, needBody
return &additionalParam{params: params}
}

func (a *additionalParam) Execute(ctx http_service.IHttpContext) error {
body, needBody := a.getBody(ctx)
contentType, _, _ := mime.ParseMediaType(ctx.Proxy().Body().ContentType())
bodyParams, formParams, err := parseBodyParams(ctx)
if err != nil {
return fmt.Errorf(`fail to parse body! [err]: %v`, err)
}
for _, p := range a.params {
conflict := p.Conflict
if conflict == "" {
conflict = "convert"
}
switch p.Position {
case application.PositionBody:
if !needBody {
continue
}
contentType := ctx.Proxy().Header().GetHeader("Content-Type")
if strings.Contains(contentType, http_context.FormData) || strings.Contains(contentType, http_context.MultipartForm) {
switch contentType {
case http_context.FormData, http_context.MultipartForm:
switch p.Conflict {
case conflictConvert:
ctx.Proxy().Body().SetToForm(p.Key, p.Value)
formParams[p.Key] = []string{p.Value}
case conflictOrigin, conflictError:
{
v := ctx.Proxy().Body().GetForm(p.Key)
if v == "" {
ctx.Proxy().Body().SetToForm(p.Key, p.Value)
} else {
if _, ok := formParams[p.Key]; ok {
if p.Conflict == conflictError {
return fmt.Errorf(errorExist, p.Position, p.Key)
}
}
formParams[p.Key] = []string{p.Value}
}
}
} else if strings.Contains(contentType, http_context.JSON) {
obj, err := oj.ParseString(body)
if err != nil {
return fmt.Errorf("parse body error: %v", err)
}
key := p.Key
if !strings.HasPrefix(p.Key, "$.") {
key = "$." + key
}
x, err := jp.ParseString(p.Key)
if err != nil {
return fmt.Errorf("parse key error: %v", err)
}
switch conflict {
case conflictConvert:
err = x.Set(obj, p.Value)
case http_context.JSON:
{
key := p.Key
if !strings.HasPrefix(p.Key, "$.") {
key = "$." + key
}
x, err := jp.ParseString(key)
if err != nil {
return fmt.Errorf("set additional json param error: %v", err)
return fmt.Errorf("parse key error: %v", err)
}
body = x.String()
case conflictOrigin, conflictError:
{
result := x.Get(p.Key)
if len(result) < 1 {
err = x.Set(obj, p.Value)
if err != nil {
return fmt.Errorf("set additional json param error: %v", err)
}
body = x.String()
switch conflict {
case conflictConvert:
err = x.Set(bodyParams, p.Value)
if err != nil {
return fmt.Errorf("set additional json param error: %v", err)
}
if conflict == conflictError {
return fmt.Errorf(errorExist, p.Position, p.Key)
case conflictOrigin, conflictError:
{
result := x.Get(bodyParams)
if len(result) < 1 {
err = x.Set(bodyParams, p.Value)
if err != nil {
return fmt.Errorf("set additional json param error: %v", err)
}
}
if conflict == conflictError {
return fmt.Errorf(errorExist, p.Position, p.Key)
}
}
}
}
Expand Down Expand Up @@ -148,5 +118,32 @@ func (a *additionalParam) Execute(ctx http_service.IHttpContext) error {
}
}
}

if strings.Contains(contentType, http_context.FormData) || strings.Contains(contentType, http_context.MultipartForm) {
ctx.Proxy().Body().SetForm(formParams)
} else if strings.Contains(contentType, http_context.JSON) {
b, _ := json.Marshal(bodyParams)
ctx.Proxy().Body().SetRaw(contentType, b)
}
return nil
}

func parseBodyParams(ctx http_service.IHttpContext) (interface{}, map[string][]string, error) {
contentType, _, _ := mime.ParseMediaType(ctx.Proxy().Body().ContentType())
switch contentType {
case http_context.FormData, http_context.MultipartForm:
formParams, err := ctx.Proxy().Body().BodyForm()
if err != nil {
return nil, nil, err
}
return nil, formParams, nil
case http_context.JSON:
body, err := ctx.Proxy().Body().RawBody()
if err != nil {
return nil, nil, err
}
bodyParams, err := oj.Parse(body)
return bodyParams, nil, err
}
return nil, nil, errors.New("unsupported content-type: " + contentType)
}
18 changes: 8 additions & 10 deletions drivers/plugins/extra-params/extra-params.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"encoding/json"
"errors"
"fmt"
"mime"
"strconv"
"strings"

http_context "github.com/eolinker/apinto/node/http-context"
"github.com/eolinker/eosc"
"github.com/eolinker/eosc/eocontext"
http_service "github.com/eolinker/eosc/eocontext/http-context"
"mime"
"strconv"
)

var _ http_service.HttpFilter = (*ExtraParams)(nil)
Expand Down Expand Up @@ -82,9 +84,7 @@ func (e *ExtraParams) access(ctx http_service.IHttpContext) (int, error) {
}
case "body":
{
switch contentType {
case http_context.FormData, http_context.MultipartForm:

if strings.Contains(contentType, http_context.FormData) || strings.Contains(contentType, http_context.MultipartForm) {
if _, has := formParams[param.Name]; has {
switch param.Conflict {
case paramConvert:
Expand All @@ -98,8 +98,7 @@ func (e *ExtraParams) access(ctx http_service.IHttpContext) (int, error) {
} else {
formParams[param.Name] = []string{paramValue.(string)}
}

case http_context.JSON:
} else if strings.Contains(contentType, http_context.JSON) {
if _, has := bodyParams[param.Name]; has {
switch param.Conflict {
case paramConvert:
Expand All @@ -118,10 +117,9 @@ func (e *ExtraParams) access(ctx http_service.IHttpContext) (int, error) {
}
}
}
switch contentType {
case http_context.FormData, http_context.MultipartForm:
if strings.Contains(contentType, http_context.FormData) || strings.Contains(contentType, http_context.MultipartForm) {
ctx.Proxy().Body().SetForm(formParams)
case http_context.JSON:
} else if strings.Contains(contentType, http_context.JSON) {
b, _ := json.Marshal(bodyParams)
ctx.Proxy().Body().SetRaw(contentType, b)
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/plugins/extra-params/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"encoding/json"
"errors"
"fmt"
http_context "github.com/eolinker/apinto/node/http-context"
http_service "github.com/eolinker/eosc/eocontext/http-context"
"mime"
"strings"

http_context "github.com/eolinker/apinto/node/http-context"
http_service "github.com/eolinker/eosc/eocontext/http-context"
)

const (
Expand Down Expand Up @@ -42,16 +43,15 @@ func encodeErr(ent string, origin string, statusCode int) error {
}

func parseBodyParams(ctx http_service.IHttpContext) (map[string]interface{}, map[string][]string, error) {
//formParams := make(map[string][]string)
//bodyParams := make(map[string]interface{})
contentType, _, _ := mime.ParseMediaType(ctx.Proxy().Body().ContentType())

switch contentType {
case http_context.FormData, http_context.MultipartForm:
formParams, err := ctx.Proxy().Body().BodyForm()
if err != nil {
return nil, formParams, err
return nil, nil, err
}
return nil, formParams, nil
case http_context.JSON:
body, err := ctx.Proxy().Body().RawBody()
if err != nil {
Expand Down

0 comments on commit 0c6770e

Please sign in to comment.