#1685 ✓resolved
Neeme Praks

Play is unable to generate a URL with path variables if variable value contains forward-slash

Reported by Neeme Praks | July 26th, 2013 @ 03:52 PM | in 1.3 (closed)

Play! 1.2.5, all platforms

In "routes" I have:
GET /apps/{appId}/{verId} Resources.index

I generate a link to this page from a template, like this:
@{Resources.index(app.id, ver.versionId)}

This works fine, as long as app.id or ver.versionId does not contain forward-slash ("/").

If any of these contain forward-slash, Play fails to find the correct route. If I put this URL together by hand (properly escaping the slash), it is handled correctly by Play (correct route is found, parameter is decoded, template is rendered).

As expected, the problem lies in play.mvc.Router class. There are several issues:

On line 749, it uses "[^/]+" as default regexp pattern for argument "constraint". As you can see, this regexp pattern assumes that the parameter value does not contain forward-slash.

I tried to work around this limitation by supplying my own custom "constraint" for the parameter in question. If use ".+", the reverse route lookup works ok (with forward-slash), generating the correct link. However, now the request parsing does not work anymore - parameter parsing is too greedy and the whole latter part of the URL is assigned to "app.id" parameter, instead of splitting it between app.id and ver.versionId.

After a bit of more investigation, I figured out that this "constraint" feature is severly broken - the same regexp pattern is used to match non-URL-encoded values (on reverse lookup) and URL-encoded values (on regular lookup).

One way to fix this would be to URL-decode the path variables (on regular lookup) before applying the regexp -- however, this means that there needs to be some other logic or regexp pattern that would split the incoming URL into individual variables. Otherwise, if you decode "/apps/myapp/origin%2Fmaster%201" into "/apps/myapp/origin/master 1" it will be impossible to separate the path slashes from slashes contained inside parameter values.

Another way would be to use separate regexp patterns for regular lookup and reverse lookup but trying to match URL-encoded values with regexp seems rather hackish.

For now, I've added an option to disable the whole "constraint" matching when doing reverse lookups - we are not using that feature anyway and supporting forward-slashes inside parameter names is more important for us.

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2>Play framework</h2>

Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>

<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>

<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>

<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>

<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>

Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>

Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.