silkapp / rest

Packages for defining APIs, running them, generating client code and documentation.
http://silkapp.github.io/rest
390 stars 52 forks source link

Need for double encoding when using String with slashes in part of url #127

Closed ryskajakub closed 9 years ago

ryskajakub commented 9 years ago

I have a resource under this url:

/my-resource/%string-id%

When the string-id contains slashes, those slashed are url-decoded before the string gets into the unnamedSingle or similar. Since the the url looks like /my-resource/some/thing, the router doesn't route it to the handler and the rest reports unsupportedRoute.

I have solved it by double-encoding the url on the client, so one encoding happens in the rest and the other one in the handler, but it is kind of hacky.

ryskajakub commented 9 years ago

It happens at least on the rest-wai, I'm not sure if the encoding is done by the rest-core or the drivers.

bergmark commented 9 years ago

Your original url is encoded as some%2Fthing, correct? Definitely sounds like a bug.

ryskajakub commented 9 years ago

Yes, my original url, that I'd like to use is something like some%2Fthing and what I actually use is something like some%252Fthing.

hesselink commented 9 years ago

Do you by any chance have apache in front of your API? We've had issues like this with Apache several times.

ryskajakub commented 9 years ago

I have nginx there, I'll try to bypass it and see if that changes anything.

ryskajakub commented 9 years ago

Ok, so it was indeed caused by the nginx at the front, thanks @hesselink !

just for future reference:

I the api under the api path in the nginx, I want to remove the /api prefix, before it gets to the rest.

location /api {
  rewrite ^/api(.*)$ $1 break;
  proxy_pass http://localhost:8000;
}

When I start doing anything with the path inside the location, the nginx will decode the url. So I had to drop the rewrite line and pass everything to the rest.

location /api {
  proxy_pass http://localhost:8000;
}

And then remove the prefix after the request is processed by the driver but before it gets into rest-core. In my case, using the rest-wai, I did this:

removeApiPrefix = lmap $ \r -> r { pathInfo = tail . pathInfo $ r }