{"action":"created","issue":{"url":"https://api.github.com/repos/angular-ui/ui-router/issues/2598","repository_url":"https://api.github.com/repos/angular-ui/ui-router","labels_url":"https://api.github.com/repos/angular-ui/ui-router/issues/2598/labels{/name}","comments_url":"https://api.github.com/repos/angular-ui/ui-router/issues/2598/comments","events_url":"https://api.github.com/repos/angular-ui/ui-router/issues/2598/events","html_url":"https://github.com/angular-ui/ui-router/issues/2598","id":137757981,"number":2598,"title":"Impossible to encode slashes as path parameters using URI encoding","user":{"login":"christopherthielen","id":2053478,"avatar_url":"https://avatars.githubusercontent.com/u/2053478?v=3","gravatar_id":"","url":"https://api.github.com/users/christopherthielen","html_url":"https://github.com/christopherthielen","followers_url":"https://api.github.com/users/christopherthielen/followers","following_url":"https://api.github.com/users/christopherthielen/following{/other_user}","gists_url":"https://api.github.com/users/christopherthielen/gists{/gist_id}","starred_url":"https://api.github.com/users/christopherthielen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/christopherthielen/subscriptions","organizations_url":"https://api.github.com/users/christopherthielen/orgs","repos_url":"https://api.github.com/users/christopherthielen/repos","events_url":"https://api.github.com/users/christopherthielen/events{/privacy}","received_events_url":"https://api.github.com/users/christopherthielen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2016-03-02T03:08:41Z","updated_at":"2016-12-19T17:54:49Z","closed_at":null,"body":"UI-Router has had troubles encoding slashes in path parameters for quite a while now.  \n\nexample:\nGiven: a url with parameters: `/path/:param1/:param2`\nIf: `param1` is `foo/bar` and `param2` is `baz/qux`\nThe browser URL _should be_: `/path/foo%2Fbar/baz%2Fqux`\n\nWe've gone through a few iterations to encode those slashes, including attempting double encoding  (3045e41577a8b8b8afc6039f42adddf5f3c061ec) and eventually a custom encoding  (02e98660a80dfd1ca4b113dd24ee304af91e9f8c).\n\nI wanted to revert any special handling of slashes, and simply url-encode/decode.  I dug into this recently and I've come to the conclusion that it's actually impossible, using the $location service.\n\nFor posterity, I am leaving my notes here:\n\n---\n\nWe are currently calling `$location.url(url)` to apply a new URL.  The `$location.url` implementation [decodes the path portion](https://github.com/angular/angular.js/blob/v1.5.0/src/ng/location.js#L387-L390) of the `url` before applying it as the `$location.$$path`.  Naively passing a pre-encoded URL such as `/path/foo%2Fbar/baz%2Fqux` immediately get decoded to `/path/foo/bar/baz/qux`, the param separation are lost.  Internally `$$path` is set to `/path/foo/bar/baz/qux`\n\nSince `.url()` pre-decodes the incoming URL, we can't use it.  Calling `$location.path()` directly seemed like a possible alternative since [it applies the path without much processing](https://github.com/angular/angular.js/blob/v1.5.0/src/ng/location.js#L487-L490).  The `$$path` value is set the way we want with our parameters encoded: `/path/foo%2Fbar/baz%2Fqux`.  However, then the `$$url` is built from `$$compose()` by calling [`encodePath`](https://github.com/angular/angular.js/blob/v1.5.0/src/ng/location.js#L130) which [splits the path on the slashes, then encodes each segment](https://github.com/angular/angular.js/blob/v1.5.0/src/ng/location.js#L14-L23).  Because of this, `$location.url()` is double encoded as `/path/foo%252%bar/baz%252Fquz`.  \n\n<img width=\"1020\" alt=\"screen shot 2016-03-01 at 8 53 08 pm\" src=\"https://cloud.githubusercontent.com/assets/2053478/13449353/23375340-dff0-11e5-8ae3-b6b83833a436.png\">\n\nWe landed on purposefully double encoding the slashes, but this caused quite a few issues (most linked to this ticket #1645).\n\nAs of 0.2.16, we're custom encoding slashes as `~2F` (using the `string` typed parameter) so that the $location service doesn't try to handle them specially.\n\nThis is working fine for most of our users.  If a user requires a slug (non-encoded slashes) we can support that using a different parameter type that doesn't explicitly encode/decode.  \n\n---\n\nIn query parameters, however, we also currently default to the `string` parameter type, which is unnecessarily encoding slashes, such as `?queryParam=foo~2Fbar`.  _We should choose a different default parameter type for query parameters than for path parameters to avoid this._  I don't have a ticket for this yet.\n"},"comment":{"url":"https://api.github.com/repos/angular-ui/ui-router/issues/comments/268031618","html_url":"https://github.com/angular-ui/ui-router/issues/2598#issuecomment-268031618","issue_url":"https://api.github.com/repos/angular-ui/ui-router/issues/2598","id":268031618,"user":{"login":"christopherthielen","id":2053478,"avatar_url":"https://avatars.githubusercontent.com/u/2053478?v=3","gravatar_id":"","url":"https://api.github.com/users/christopherthielen","html_url":"https://github.com/christopherthielen","followers_url":"https://api.github.com/users/christopherthielen/followers","following_url":"https://api.github.com/users/christopherthielen/following{/other_user}","gists_url":"https://api.github.com/users/christopherthielen/gists{/gist_id}","starred_url":"https://api.github.com/users/christopherthielen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/christopherthielen/subscriptions","organizations_url":"https://api.github.com/users/christopherthielen/orgs","repos_url":"https://api.github.com/users/christopherthielen/repos","events_url":"https://api.github.com/users/christopherthielen/events{/privacy}","received_events_url":"https://api.github.com/users/christopherthielen/received_events","type":"User","site_admin":false},"created_at":"2016-12-19T17:54:49Z","updated_at":"2016-12-19T17:54:49Z","body":"It's basically a warning that using raw params is not guaranteed to work bi-directionally for arbitrary data.\r\n\r\nFor example, a url pattern like '/foo/:param1/:param2' with parameter values `{ param1: 'a/b', param2: 'c/d' }` serializes fine to `/foo/a/b/c/d` but there's no way to deserialize it and extract the original param values.\r\n\r\n---\r\n\r\nActually, I think the only guarantee we can make for `raw` is that **ui-router will not url-encode the parameter value**.  We're still at the mercy of the `$location` service (in ng1) for example.  Developers will be responsible to ensure their parameter values appear in the URL and are deserialized properly.\r\n\r\nHere's a plunk showing some edge cases that I don't think we can perform successfully in ng1 : http://plnkr.co/edit/bjDtVkdHaXUZe3p6NGJ7?p=preview\r\n"}}
{"actor":{"display_login":"christopherthielen"}}