Closed
Description
When testing the UriTemplate
, we ran into several issues with encoding. The URI template, when given a path like /foo%20bar
will return /foo%252520bar
on a call to expand
. It looks like both the hateoas UriTemplate and the spring UriTemplate are not handling ecoded URLs. Also if you provide a URL with a character needing encoding, you get the %
sign escaped only once.
Here is a spock test to shows the errors. The last three tests will fail due to the issues.
@Unroll("template expand with params '#params' and uri '#uri' results in '#expectedUri ")
def "template expands with parameter map"() {
when:
UriTemplate template = new UriTemplate(uri)
String expandedUri = template.expand(params)
then:
expandedUri == expectedUri
where:
uri | params | expectedUri
'/foo/bar{?x}' | ['x': 1] | '/foo/bar?x=1'
'/foo/bar{?x,y}' | ['x': 1, 'y': "2"] | '/foo/bar?x=1&y=2'
'/foo/bar{?x}{&y}' | ['x': 1, 'y': "2"] | '/foo/bar?x=1&y=2'
'/foo/bar?x=1{&y}' | ['y': 2] | '/foo/bar?x=1&y=2'
'/foo/bar?x=1{&y,z}' | ['y': 2, 'z': 3L] | '/foo/bar?x=1&y=2&z=3'
'/foo{/x}' | ['x': 1] | '/foo/1'
'/foo{/x,y}' | ['x': 1, 'y': "2"] | '/foo/1/2'
'/foo{/x}{/y}' | ['x': 1, 'y': "2"] | '/foo/1/2'
'/foo{/x}{/y}{?z}' | ['x': 1, 'y': "2", 'z': 3L] | '/foo/1/2?z=3'
'/foo/{x}' | ['x': 1] | '/foo/1'
'/foo/{x}/bar' | ['x': 1] | '/foo/1/bar'
'/services/foo/{x}/bar/{y}/gaz' | ['x': 1, 'y': "2"] | '/services/foo/1/bar/2/gaz'
'/foo/{x}/bar/{y}/bar{?z}' | ['x': 1, 'y': "2", 'z': 3L] | '/foo/1/bar/2/bar?z=3'
'/foo/{x}/bar/{y}/bar{?z}' | ['x': 1, 'y': "2"] | '/foo/1/bar/2/bar'
'/foo/bar{?x,y,z}' | ['x': 1] | '/foo/bar?x=1'
'/foo/bar{?x,y,z}' | ['x': 1, 'y': "2"] | '/foo/bar?x=1&y=2'
'/foo/bar{?x,y,z}' | ['x': 1, 'z': 3L] | '/foo/bar?x=1&z=3'
'/foo/{x}/bar{/y}{?z}' | ['x': 1, 'y': "2", 'z': 3L] | '/foo/1/bar/2?z=3'
'/foo/{x}/bar{/y}{?z}' | ['x': 1, 'z': 3L] | '/foo/1/bar?z=3'
'/foo/{x}/bar{?y}{#z}' | ['x': 1, 'y': "2"] | '/foo/1/bar?y=2'
'/foo/{x}/bar{?y}{#z}' | ['x': 1, 'y': "2", 'z': 3L] | '/foo/1/bar?y=2#3'
'/foo/{x}/bar{?y}{#z}' | ['x': 1, 'z': 3L] | '/foo/1/bar#3'
'/foo/b%20ar{?x}' | ['x': 1] | '/foo/b%20ar?x=1'
'/foo/b"ar{?x}' | ['x': 1] | '/foo/b%22ar?x=1'
'/foo/b%22ar{?x}' | ['x': 1] | '/foo/b%22ar?x=1'
}