damnhandy / Handy-URI-Templates

A Java URI Template processor implementing RFC6570
https://damnhandy.github.io/Handy-URI-Templates/
Other
202 stars 37 forks source link

Commas get HTTP escaped in expanded Request-URI query parameter values #60

Closed Jitsusama closed 6 years ago

Jitsusama commented 6 years ago

I'm running into an issue where when a URI template is expanded, in the circumstance that a query parameter is templated and set with a value containing commas (,), that the expanded String escapes the commas with %2C. This is not necessary as per this StackOverflow question response: https://stackoverflow.com/a/2375597/3827514.

Having the request URI escaped in such a manner is making it hard for me to write tests, as my web application includes escaped values when it auto-generates links to REST resources.

Here's an example bit of code showing how to easily reproduce the issue:

package tests;

import com.damnhandy.uri.template.UriTemplate;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class TemplateTests {
    @Test public void
    simpleTest() {
        String actual = UriTemplate
                .fromTemplate("http://localhost/thing{?things}")
                .set("things", "1,2,3")
                .expand();

        assertThat(actual, equalTo("http://localhost/thing?things=1,2,3"));
    }
}

Is there a way to prevent the HTTP URI escaping from occurring? I haven't found such an option in the library. Otherwise, would you be willing to change this behaviour, as it is not needed and is counter-intuitive (at least to me)?

damnhandy commented 6 years ago

Sorry it's take so long to follow up on this. This seems like a bug, but It also seems like a use case that isn't covered in the core URI template test. I'm going to put in a fix for this shortly as it seems legit.

damnhandy commented 6 years ago

And upon re-reading RFC6570 section 1.5 Notational Conventions, the comma will always be escaped with %2C. You could get the results you were looking for by altering it so that your comma-delimited value is an array or List type. Something like this will works:


package tests;

import com.damnhandy.uri.template.UriTemplate;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class TemplateTests {
    @Test public void
    simpleTest() {
        String actual = UriTemplate
                .fromTemplate("http://localhost/thing{?things}")
                .set("things", "1,2,3".split(","))
                .expand();

        assertThat(actual, equalTo("http://localhost/thing?things=1,2,3"));
    }
}