Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameters converter #3

Open
mdouchement opened this issue Mar 29, 2017 · 0 comments
Open

Parameters converter #3

mdouchement opened this issue Mar 29, 2017 · 0 comments

Comments

@mdouchement
Copy link
Owner

  • logger
...

params, err := json.Marshal(c.Get("echo_request_params"))
if err != nil {
	params = []byte("Ignored error during parameters parsing")
}
if len(params) == 0 {
	params = []byte{}
}

...
  • params_converter.go
package middlewares

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"strings"

	"github.com/labstack/echo"
)

// ParamsConverter instances a ParamsConverter middleware that will convert JSON body parameters into gin.Params
// Must be used after logger middleware:
//   engine.Use(middlewares.Logger())
//   engine.Use(middlewares.ParamsConverter())
func ParamsConverter() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) (err error) {
			// Handles URL queries
			params := make(map[string]interface{}, len(c.ParamNames()))
			for _, pname := range c.ParamNames() {
				params[pname] = c.Param(pname)
			}
			queries := c.QueryParams()
			for qname := range queries {
				params[qname] = queries.Get(qname)
			}

			// Pre-handles JSON body parameters
			body := &bytes.Buffer{}
			if strings.Contains(c.Request().Header.Get(echo.HeaderContentType), echo.MIMEApplicationJSON) && c.Request().Header.Get(echo.HeaderContentLength) != "" {
				c.Request().Body = newTeeReadCloser(c.Request().Body, body)
			}

			if err = next(c); err != nil {
				c.Error(err)
			}

			// Handles JSON body parameters
			if body.Len() > 0 {
				if err := json.Unmarshal(body.Bytes(), &params); err != nil {
					return fmt.Errorf("ParamsConverter: %s", err.Error())
				}
			}
			c.Set("echo_request_params", params)

			return
		}
	}
}

// http.Request.Body interceptor

type teeReadCloser struct {
	r io.Reader
	w io.Writer
	c io.Closer
}

func newTeeReadCloser(r io.ReadCloser, w io.Writer) io.ReadCloser {
	return &teeReadCloser{io.TeeReader(r, w), w, r}
}

// Read implements io.Reader
func (t *teeReadCloser) Read(b []byte) (int, error) {
	return t.r.Read(b)
}

// Close attempts to close the reader and write. It returns an error if both
// failed to Close.
func (t *teeReadCloser) Close() error {
	return t.c.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant