spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
920 stars 563 forks source link

self references generated incorrectly when id contains colons [DATAREST-1074] #1439

Closed spring-projects-issues closed 7 years ago

spring-projects-issues commented 7 years ago

Thomas Prebble opened DATAREST-1074 and commented

When the self ref is being generated for an entity with an id containing colons (e.g. SDN:P02::ASAM), the id is not appended to the entities base url

Example - option Entity containing ID SDN:P02::ASAM

Expected self ref http://\:\/option/SDN:P02::ASAM Actual self ref http://\:\/option

self ref for an id with no colons http://\:\/option/SDNP02ASAM

Initial Analysis

Caused by UriComponentsBuilder.fromUriString(path) in LinkBuilderSupport. When the RepositoryLinkBuilder delegates the slash method call to its parent, LinkBuilderSupport calls UriComponentsBuilder.fromUriString. the URI_PATTERN matches everything before the first colon to the scheme and the remaining section to ssp. The below test recreates the issue within the UriComponentsBuilder. Is there a reason the slash method calls fromUriString instead of fromPath?

import org.junit.Test;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import static org.junit.Assert.assertEquals;

public class UriComponentsBuilderTest {

    @Test
    public void fromUriStringWithColon() throws Exception {
        String pathWithColon = "SDN:P02::ASAM";
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(pathWithColon);
        UriComponents components = builder.build();
        assertEquals(pathWithColon, components.getPath());
    }

    @Test
    public void fromUriStringWithoutColon() throws Exception {
        String pathWithColon = "SDNP02ASAM";
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(pathWithColon);
        UriComponents components = builder.build();
        assertEquals(pathWithColon, components.getPath());
    }

    @Test
    public void fromPAthWithColon() throws Exception {
        String pathWithColon = "SDN:P02::ASAM";
        UriComponentsBuilder builder = UriComponentsBuilder.fromPath(pathWithColon);
        UriComponents components = builder.build();
        assertEquals(pathWithColon, components.getPath());
    }

}

No further details from DATAREST-1074

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

Yes, the reason is that slash(…) can also take segments that contain request parameters (e.g. foo?bar=foobar). It looks like there's no real alternative to using fromUriString(…) as there's no factory method that allows parsing request parameters except that one. Rossen Stoyanchev, can you advise?

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

It looks like the test passes if I prepend the input value with a /. That apparently triggers the regex to match in the expected way. I've [filed and fixed a ticket|{https://github.com/spring-projects/spring-hateoas/issues/582] in Spring HATEOAS to tweak LinkBuilderSupport accordingly.

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

Closing as invalid, as the root cause has been fixed in Spring HATEOAS