Echo: How to prevent uri decoding in routing

Created on 11 Jun 2016  路  6Comments  路  Source: labstack/echo

Please consider the following example:

e.GET("/search/:term/:page", func (c echo.Context) error {
    return c.String(http.StatusOK, c.Param("term"))
})

The routing is not working when the term contains %2F, because the term is decoded and %2F is converted to /, e.g., http://localhost:5050/search/a%2Fb/1 returns Not Found exception.

Most helpful comment

FYI: our approach to working around this was middleware which called url.QueryUnescape() on the params. This method is flawed unfortunately. Query escaped strings may replace spaces with '+', as golang's url.QueryEscape() function does. So url.QueryUnescape() replaces '+' with spaces.

But URI path segments are allowed to have literal '+' characters in them, so "unescaping" them back into spaces is inappropriate. golang's url package does have the code to correctly unescape path segments, but the only way to invoke it is:

u, _ := url.Parse(param)
param = u.Path

All 6 comments

After upgrading my issue is the opposite; has decoding been disabled? Possibly related to https://github.com/labstack/echo/issues/587.

As a workaround I have done the following:

url.QueryUnescape(c.Param("..."))

No biggie, just verifying that this is intended?

@Puffton Yes, it seems they have changed the code to escape the parameters.
Please check commit: c00d017 (@vishr committed 11days ago)
This change makes sense because prevents unintended consequences.

Seems like path params with escapes were only messing up the router. But after routing and parsing out the path params, isn't it desirable to unescape the params before invoking the handlers?

This broke a lot of our tests, because our routes use path params with encoded spaces in them pretty often. I'm tempted to put in a root middleware like:

c.SetParamValues(unescapeThemAll(c.ParamValues))

@ansel1 I second your opinion. Params should be unescaped before the handler is invoked.

We have ended up inserting another middleware in our chain which unescapes them all right after routing.

FYI: our approach to working around this was middleware which called url.QueryUnescape() on the params. This method is flawed unfortunately. Query escaped strings may replace spaces with '+', as golang's url.QueryEscape() function does. So url.QueryUnescape() replaces '+' with spaces.

But URI path segments are allowed to have literal '+' characters in them, so "unescaping" them back into spaces is inappropriate. golang's url package does have the code to correctly unescape path segments, but the only way to invoke it is:

u, _ := url.Parse(param)
param = u.Path
Was this page helpful?
0 / 5 - 0 ratings

Related issues

spielstein picture spielstein  路  3Comments

mmindenhall picture mmindenhall  路  4Comments

vishr picture vishr  路  3Comments

danieldaeschle picture danieldaeschle  路  3Comments

ellisonleao picture ellisonleao  路  3Comments